Skip to content

Commit 4aaf391

Browse files
authored
Move InferenceImage to smart-tools (#528)
1 parent 131ec63 commit 4aaf391

File tree

5 files changed

+73
-71
lines changed

5 files changed

+73
-71
lines changed

web_ui/packages/smart-tools/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,6 @@ export { default as OpenCVLoader } from './src/utils/opencv-loader';
66
export { Watershed } from './src/watershed/watershed';
77
export { type WatershedInstance, type WatershedPolygon } from './src/watershed/interfaces';
88

9+
export { InferenceImage } from './src/inference-image/inference-image';
10+
911
export { formatContourToPoints, approximateShape } from './src/utils/utils';
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright (C) 2022-2025 Intel Corporation
2+
// LIMITED EDGE SOFTWARE DISTRIBUTION LICENSE
3+
4+
import type OpenCVTypes from 'OpenCVTypes';
5+
6+
import { formatImageData } from '../utils/utils';
7+
8+
export class InferenceImage {
9+
constructor(private CV: OpenCVTypes.cv) {}
10+
11+
resize(imageData: ImageData, width: number, height: number): ImageData {
12+
const img = this.getImage(imageData);
13+
14+
const size = new this.CV.Size(width, height);
15+
const dst: OpenCVTypes.Mat = new this.CV.Mat();
16+
const colorMap: OpenCVTypes.Mat = new this.CV.Mat();
17+
18+
this.CV.resize(img, dst, size, 0, 0, this.CV.INTER_CUBIC);
19+
this.CV.applyColorMap(dst, colorMap, this.CV.COLORMAP_JET);
20+
this.CV.cvtColor(colorMap, colorMap, this.CV.COLOR_BGR2RGB);
21+
22+
const finalImageData = formatImageData(this.CV, colorMap);
23+
24+
img.delete();
25+
dst.delete();
26+
colorMap.delete();
27+
28+
return finalImageData;
29+
}
30+
31+
getImage(imageData: ImageData): OpenCVTypes.Mat {
32+
const data = this.CV.matFromImageData(imageData);
33+
34+
this.CV.cvtColor(data, data, this.CV.COLOR_RGBA2RGB, 0);
35+
36+
return data;
37+
}
38+
}

web_ui/packages/smart-tools/src/utils/utils.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,27 @@ export const approximateShape = (CV: OpenCVTypes.cv, contour: OpenCVTypes.Mat, i
3636

3737
return newContour;
3838
};
39+
40+
export const formatImageData = (CV: OpenCVTypes.cv, mat: OpenCVTypes.Mat): ImageData => {
41+
const img = new CV.Mat();
42+
const depth = mat.type() % 8;
43+
const scale = depth <= CV.CV_8S ? 1 : depth <= CV.CV_32S ? 1 / 256 : 255;
44+
const shift = depth === CV.CV_8S || depth === CV.CV_16S ? 128 : 0;
45+
46+
mat.convertTo(img, CV.CV_8U, scale, shift);
47+
48+
switch (img.type()) {
49+
case CV.CV_8UC1:
50+
CV.cvtColor(img, img, CV.COLOR_GRAY2RGBA);
51+
break;
52+
case CV.CV_8UC3:
53+
CV.cvtColor(img, img, CV.COLOR_RGB2RGBA);
54+
break;
55+
case CV.CV_8UC4:
56+
break;
57+
default:
58+
throw new Error('Bad number of channels (Source image must have 1, 3 or 4 channels)');
59+
}
60+
61+
return new ImageData(new Uint8ClampedArray(img.data), img.cols, img.rows);
62+
};
Lines changed: 9 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,26 @@
11
// Copyright (C) 2022-2025 Intel Corporation
22
// LIMITED EDGE SOFTWARE DISTRIBUTION LICENSE
33

4-
// Dependencies get bundled into the worker
5-
6-
import { OpenCVLoader } from '@geti/smart-tools';
4+
import { InferenceImage, OpenCVLoader } from '@geti/smart-tools';
75
import { expose } from 'comlink';
86
import type OpenCVTypes from 'OpenCVTypes';
97

10-
import { formatImageData } from './utils';
11-
128
declare const self: DedicatedWorkerGlobalScope;
139

14-
let CV: OpenCVTypes.cv | null = null;
15-
16-
const terminate = (): void => {
17-
self.close();
18-
};
19-
20-
class InferenceImage {
21-
resize(imageData: ImageData, width: number, height: number): ImageData {
22-
const img = this.getImage(imageData);
23-
24-
const size = new CV.Size(width, height);
25-
const dst: OpenCVTypes.Mat = new CV.Mat();
26-
const colorMap: OpenCVTypes.Mat = new CV.Mat();
27-
28-
CV.resize(img, dst, size, 0, 0, CV.INTER_CUBIC);
29-
CV.applyColorMap(dst, colorMap, CV.COLORMAP_JET);
30-
CV.cvtColor(colorMap, colorMap, CV.COLOR_BGR2RGB);
10+
let opencv: OpenCVTypes;
3111

32-
const finalImageData = formatImageData(CV, colorMap);
12+
const waitForOpenCV = async () => {
13+
if (opencv) return true;
3314

34-
img.delete();
35-
dst.delete();
36-
colorMap.delete();
15+
opencv = await OpenCVLoader();
3716

38-
return finalImageData;
17+
if ('ready' in opencv) {
18+
await opencv.ready;
3919
}
4020

41-
getImage(imageData: ImageData): OpenCVTypes.Mat {
42-
const data = CV.matFromImageData(imageData);
43-
44-
CV.cvtColor(data, data, CV.COLOR_RGBA2RGB, 0);
45-
46-
return data;
47-
}
48-
}
49-
50-
const waitForOpenCV = async (): Promise<boolean> => {
51-
if (CV) {
52-
return true;
53-
} else {
54-
return OpenCVLoader().then((cvInstance: OpenCVTypes.cv) => {
55-
CV = cvInstance;
56-
57-
return true;
58-
});
59-
}
21+
return false;
6022
};
6123

62-
const WorkerApi = { InferenceImage, waitForOpenCV, terminate };
24+
const WorkerApi = { InferenceImage, waitForOpenCV, terminate: self.close };
6325

6426
expose(WorkerApi);

web_ui/src/webworkers/utils.ts

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -44,30 +44,6 @@ export const getPointsFromMat = (mat: OpenCVTypes.Mat, offset = { x: 0, y: 0 }):
4444
return points;
4545
};
4646

47-
export const formatImageData = (CV: OpenCVTypes.cv, mat: OpenCVTypes.Mat): ImageData => {
48-
const img = new CV.Mat();
49-
const depth = mat.type() % 8;
50-
const scale = depth <= CV.CV_8S ? 1 : depth <= CV.CV_32S ? 1 / 256 : 255;
51-
const shift = depth === CV.CV_8S || depth === CV.CV_16S ? 128 : 0;
52-
53-
mat.convertTo(img, CV.CV_8U, scale, shift);
54-
55-
switch (img.type()) {
56-
case CV.CV_8UC1:
57-
CV.cvtColor(img, img, CV.COLOR_GRAY2RGBA);
58-
break;
59-
case CV.CV_8UC3:
60-
CV.cvtColor(img, img, CV.COLOR_RGB2RGBA);
61-
break;
62-
case CV.CV_8UC4:
63-
break;
64-
default:
65-
throw new Error('Bad number of channels (Source image must have 1, 3 or 4 channels)');
66-
}
67-
68-
return new ImageData(new Uint8ClampedArray(img.data), img.cols, img.rows);
69-
};
70-
7147
// For debugging purposes, not being used atm
7248
// eslint-disable-next-line @typescript-eslint/no-unused-vars
7349
const logMat = (mat: OpenCVTypes.Mat, name: string): void => {

0 commit comments

Comments
 (0)