Skip to content

Commit cf810d7

Browse files
committed
feat: replicate annotation data between overlapping images
1 parent 1f031eb commit cf810d7

File tree

3 files changed

+50
-6
lines changed

3 files changed

+50
-6
lines changed

backend/api/services/images.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,10 @@ def compute_overlap(
6060
) -> tuple[list[list[float]], float]:
6161
if image1_path < image2_path:
6262
homography_matrix, overlap_ratio = _compute_overlap(image1_path, image2_path)
63-
return homography_matrix.tolist(), overlap_ratio
63+
return np.linalg.inv(homography_matrix).tolist(), overlap_ratio
6464
else:
6565
homography_matrix, overlap_ratio = _compute_overlap(image2_path, image1_path)
66-
return np.linalg.inv(homography_matrix).tolist(), overlap_ratio
66+
return homography_matrix.tolist(), overlap_ratio
6767

6868

6969
@cache

frontend/src/models.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ export interface AnnotationData {
5858
}
5959

6060
export interface Overlap {
61-
imageUrl: string;
62-
homographyMatrix: number[][];
63-
overlapRatio: number;
61+
image_path: string;
62+
homography_matrix: number[][];
63+
overlap_ratio: number;
6464
}

frontend/src/stores/annotation-data.ts

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { defineStore, acceptHMRUpdate } from 'pinia';
2-
import type { AnnotationData, Annotation, Overlap } from '../models';
2+
import { baseUrl } from 'boot/api';
3+
import type { AnnotationData, Annotation, Overlap, Point } from '../models';
34
import { exportFile } from 'quasar';
45

56
export const DAMAGE_LEVELS = 4;
@@ -12,6 +13,8 @@ export const DAMAGE_COLORS = [
1213
'#ee6677',
1314
];
1415

16+
const OVERLAP_RATIO_THRESHOLD = 0.3;
17+
1518
export const useAnnotationDataStore = defineStore('annotationData', {
1619
state: (): AnnotationData & { selectedImageUrl: string | null; overlapLoading: boolean } => ({
1720
userInfo: {
@@ -71,6 +74,47 @@ export const useAnnotationDataStore = defineStore('annotationData', {
7174

7275
addAnnotationsFromOverlap(imageUrl: string, overlap: Overlap | null) {
7376
if (!overlap) return;
77+
console.log(
78+
`Detected overlap between ${imageUrl} and ${overlap.image_path} with ratio ${overlap.overlap_ratio}`,
79+
);
80+
if (overlap.overlap_ratio < OVERLAP_RATIO_THRESHOLD) return;
81+
82+
const sourceAnnotations = this.getAnnotationsForImage(
83+
`${baseUrl}/files/get/${overlap.image_path}`,
84+
);
85+
if (sourceAnnotations.length === 0) return;
86+
87+
const H = overlap.homography_matrix;
88+
89+
for (const sourceAnnotation of sourceAnnotations) {
90+
const transformedPoints = sourceAnnotation.target.selector.geometry.points.map(
91+
(point: Point): Point => {
92+
const [x, y] = point;
93+
const x1 = H[0]![0]! * x + H[0]![1]! * y + H[0]![2]!;
94+
const y1 = H[1]![0]! * x + H[1]![1]! * y + H[1]![2]!;
95+
const w = H[2]![0]! * x + H[2]![1]! * y + H[2]![2]!;
96+
97+
return [x1 / w, y1 / w];
98+
},
99+
);
100+
101+
const newAnnotation: Annotation = {
102+
id: sourceAnnotation.id,
103+
bodies: sourceAnnotation.bodies,
104+
target: {
105+
...sourceAnnotation.target,
106+
selector: {
107+
...sourceAnnotation.target.selector,
108+
geometry: {
109+
...sourceAnnotation.target.selector.geometry,
110+
points: transformedPoints,
111+
},
112+
},
113+
},
114+
};
115+
116+
this.addAnnotation(imageUrl, newAnnotation);
117+
}
74118
},
75119

76120
selectPrevious(): void {

0 commit comments

Comments
 (0)