react-native-mask-segment-canvas 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +904 -0
- package/dist/components/MaskSegmentCanvas.d.ts +6 -0
- package/dist/components/MaskSegmentCanvas.d.ts.map +1 -0
- package/dist/components/MaskSegmentCanvas.js +2012 -0
- package/dist/components/MaskSegmentCanvas.js.map +1 -0
- package/dist/components/MaskSegmentCanvas.types.d.ts +189 -0
- package/dist/components/MaskSegmentCanvas.types.d.ts.map +1 -0
- package/dist/components/MaskSegmentCanvas.types.js +2 -0
- package/dist/components/MaskSegmentCanvas.types.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/shaders/regionPaint.sksl.d.ts +3 -0
- package/dist/shaders/regionPaint.sksl.d.ts.map +1 -0
- package/dist/shaders/regionPaint.sksl.js +72 -0
- package/dist/shaders/regionPaint.sksl.js.map +1 -0
- package/dist/utils/compositePaintedImage.d.ts +44 -0
- package/dist/utils/compositePaintedImage.d.ts.map +1 -0
- package/dist/utils/compositePaintedImage.js +146 -0
- package/dist/utils/compositePaintedImage.js.map +1 -0
- package/dist/utils/exportUtils.d.ts +20 -0
- package/dist/utils/exportUtils.d.ts.map +1 -0
- package/dist/utils/exportUtils.js +32 -0
- package/dist/utils/exportUtils.js.map +1 -0
- package/dist/utils/freqLayerPrep.d.ts +23 -0
- package/dist/utils/freqLayerPrep.d.ts.map +1 -0
- package/dist/utils/freqLayerPrep.js +168 -0
- package/dist/utils/freqLayerPrep.js.map +1 -0
- package/dist/utils/maskSegmentRuntime.d.ts +43 -0
- package/dist/utils/maskSegmentRuntime.d.ts.map +1 -0
- package/dist/utils/maskSegmentRuntime.js +181 -0
- package/dist/utils/maskSegmentRuntime.js.map +1 -0
- package/dist/utils/maskSegmentation.d.ts +133 -0
- package/dist/utils/maskSegmentation.d.ts.map +1 -0
- package/dist/utils/maskSegmentation.js +1600 -0
- package/dist/utils/maskSegmentation.js.map +1 -0
- package/dist/utils/maskSemanticPalette.d.ts +31 -0
- package/dist/utils/maskSemanticPalette.d.ts.map +1 -0
- package/dist/utils/maskSemanticPalette.js +125 -0
- package/dist/utils/maskSemanticPalette.js.map +1 -0
- package/dist/utils/opencvAdapter.d.ts +116 -0
- package/dist/utils/opencvAdapter.d.ts.map +1 -0
- package/dist/utils/opencvAdapter.js +353 -0
- package/dist/utils/opencvAdapter.js.map +1 -0
- package/dist/utils/paintColorMapTexture.d.ts +5 -0
- package/dist/utils/paintColorMapTexture.d.ts.map +1 -0
- package/dist/utils/paintColorMapTexture.js +203 -0
- package/dist/utils/paintColorMapTexture.js.map +1 -0
- package/dist/utils/paintShaderRuntime.d.ts +40 -0
- package/dist/utils/paintShaderRuntime.d.ts.map +1 -0
- package/dist/utils/paintShaderRuntime.js +76 -0
- package/dist/utils/paintShaderRuntime.js.map +1 -0
- package/dist/utils/pickMapTexture.d.ts +4 -0
- package/dist/utils/pickMapTexture.d.ts.map +1 -0
- package/dist/utils/pickMapTexture.js +24 -0
- package/dist/utils/pickMapTexture.js.map +1 -0
- package/dist/utils/pngImage.d.ts +49 -0
- package/dist/utils/pngImage.d.ts.map +1 -0
- package/dist/utils/pngImage.js +438 -0
- package/dist/utils/pngImage.js.map +1 -0
- package/dist/utils/resolveAssetPath.d.ts +3 -0
- package/dist/utils/resolveAssetPath.d.ts.map +1 -0
- package/dist/utils/resolveAssetPath.js +56 -0
- package/dist/utils/resolveAssetPath.js.map +1 -0
- package/dist/utils/resolveImageUrl.d.ts +3 -0
- package/dist/utils/resolveImageUrl.d.ts.map +1 -0
- package/dist/utils/resolveImageUrl.js +51 -0
- package/dist/utils/resolveImageUrl.js.map +1 -0
- package/dist/utils/skiaImage.d.ts +4 -0
- package/dist/utils/skiaImage.d.ts.map +1 -0
- package/dist/utils/skiaImage.js +12 -0
- package/dist/utils/skiaImage.js.map +1 -0
- package/package.json +100 -0
- package/patches/react-native-fast-opencv+0.4.8.patch +122 -0
- package/src/components/MaskSegmentCanvas.tsx +2832 -0
- package/src/components/MaskSegmentCanvas.types.ts +216 -0
- package/src/globals.d.ts +19 -0
- package/src/index.ts +45 -0
- package/src/shaders/regionPaint.sksl.ts +71 -0
- package/src/upng-js.d.ts +33 -0
- package/src/utils/compositePaintedImage.ts +201 -0
- package/src/utils/exportUtils.ts +40 -0
- package/src/utils/freqLayerPrep.ts +267 -0
- package/src/utils/maskSegmentRuntime.ts +257 -0
- package/src/utils/maskSegmentation.ts +2294 -0
- package/src/utils/maskSemanticPalette.ts +187 -0
- package/src/utils/opencvAdapter.ts +539 -0
- package/src/utils/paintColorMapTexture.ts +239 -0
- package/src/utils/paintShaderRuntime.tsx +150 -0
- package/src/utils/pickMapTexture.ts +37 -0
- package/src/utils/pngImage.ts +591 -0
- package/src/utils/resolveAssetPath.ts +64 -0
- package/src/utils/resolveImageUrl.ts +63 -0
- package/src/utils/skiaImage.ts +25 -0
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getMaskRuntimeRevision,
|
|
3
|
+
getMaskSegmentRuntimeConfig,
|
|
4
|
+
} from './maskSegmentRuntime';
|
|
5
|
+
|
|
6
|
+
export type MaskSemanticColor = {
|
|
7
|
+
name: string;
|
|
8
|
+
hex: string;
|
|
9
|
+
/** 参考色(BGR,与掩码 buffer 通道一致) */
|
|
10
|
+
bgr: { b: number; g: number; r: number };
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
/** 掩码语义色表(与后端分区颜色参考一致) */
|
|
14
|
+
export const MASK_SEMANTIC_COLORS: MaskSemanticColor[] = [
|
|
15
|
+
{ name: 'door', hex: '#E6194B', bgr: { b: 75, g: 25, r: 230 } },
|
|
16
|
+
{ name: 'ceiling', hex: '#3CB44B', bgr: { b: 75, g: 180, r: 60 } },
|
|
17
|
+
{ name: 'cabinet', hex: '#FFE119', bgr: { b: 25, g: 225, r: 255 } },
|
|
18
|
+
{ name: 'wall', hex: '#4363D8', bgr: { b: 216, g: 99, r: 67 } },
|
|
19
|
+
{ name: 'baseboard', hex: '#F58231', bgr: { b: 49, g: 130, r: 245 } },
|
|
20
|
+
{ name: 'windowFrame', hex: '#911EB4', bgr: { b: 180, g: 30, r: 145 } },
|
|
21
|
+
{ name: 'garageDoor', hex: '#46F0F0', bgr: { b: 240, g: 240, r: 70 } },
|
|
22
|
+
{ name: 'roof', hex: '#F032E6', bgr: { b: 230, g: 50, r: 240 } },
|
|
23
|
+
{ name: 'eave', hex: '#BCF60C', bgr: { b: 12, g: 246, r: 188 } },
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
export const BASEBOARD_SEMANTIC_NAME = 'baseboard';
|
|
27
|
+
|
|
28
|
+
type SemanticRgbEntry = {
|
|
29
|
+
name: string;
|
|
30
|
+
rgb: { r: number; g: number; b: number };
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
type SemanticContext = {
|
|
34
|
+
baseboardMaxColorDistSq: number;
|
|
35
|
+
semanticRgb: SemanticRgbEntry[];
|
|
36
|
+
baseboardRgb: SemanticRgbEntry;
|
|
37
|
+
cabinetRgb: SemanticRgbEntry;
|
|
38
|
+
wallRgb: SemanticRgbEntry;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
let contextRevision = -1;
|
|
42
|
+
let cachedContext: SemanticContext | null = null;
|
|
43
|
+
|
|
44
|
+
function buildSemanticRgb(colors: MaskSemanticColor[]): SemanticRgbEntry[] {
|
|
45
|
+
return colors.map(entry => ({
|
|
46
|
+
name: entry.name,
|
|
47
|
+
rgb: {
|
|
48
|
+
r: entry.bgr.r,
|
|
49
|
+
g: entry.bgr.g,
|
|
50
|
+
b: entry.bgr.b,
|
|
51
|
+
},
|
|
52
|
+
}));
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function getSemanticContext(): SemanticContext {
|
|
56
|
+
const revision = getMaskRuntimeRevision();
|
|
57
|
+
if (contextRevision === revision && cachedContext) {
|
|
58
|
+
return cachedContext;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const mask = getMaskSegmentRuntimeConfig().mask;
|
|
62
|
+
const semanticRgb = buildSemanticRgb(mask.semanticColors);
|
|
63
|
+
const baseboardRgb = semanticRgb.find(
|
|
64
|
+
entry => entry.name === BASEBOARD_SEMANTIC_NAME,
|
|
65
|
+
)!;
|
|
66
|
+
const cabinetRgb = semanticRgb.find(entry => entry.name === 'cabinet')!;
|
|
67
|
+
const wallRgb = semanticRgb.find(entry => entry.name === 'wall')!;
|
|
68
|
+
const maxDist = mask.baseboardMaxColorDist;
|
|
69
|
+
|
|
70
|
+
cachedContext = {
|
|
71
|
+
baseboardMaxColorDistSq: maxDist * maxDist,
|
|
72
|
+
semanticRgb,
|
|
73
|
+
baseboardRgb,
|
|
74
|
+
cabinetRgb,
|
|
75
|
+
wallRgb,
|
|
76
|
+
};
|
|
77
|
+
contextRevision = revision;
|
|
78
|
+
return cachedContext;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function colorDistanceSq(
|
|
82
|
+
a: { r: number; g: number; b: number },
|
|
83
|
+
b: { r: number; g: number; b: number },
|
|
84
|
+
): number {
|
|
85
|
+
const dr = a.r - b.r;
|
|
86
|
+
const dg = a.g - b.g;
|
|
87
|
+
const db = a.b - b.b;
|
|
88
|
+
return dr * dr + dg * dg + db * db;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/** 将掩码像素归类到最近的语义色(baseboard 仅严格橙色命中) */
|
|
92
|
+
export function classifyBgrPixelToSemantic(
|
|
93
|
+
b: number,
|
|
94
|
+
g: number,
|
|
95
|
+
r: number,
|
|
96
|
+
): string {
|
|
97
|
+
const ctx = getSemanticContext();
|
|
98
|
+
const pixel = { r, g, b };
|
|
99
|
+
const distToBaseboard = colorDistanceSq(pixel, ctx.baseboardRgb.rgb);
|
|
100
|
+
const distToCabinet = colorDistanceSq(pixel, ctx.cabinetRgb.rgb);
|
|
101
|
+
const distToWall = colorDistanceSq(pixel, ctx.wallRgb.rgb);
|
|
102
|
+
|
|
103
|
+
if (
|
|
104
|
+
distToBaseboard <= ctx.baseboardMaxColorDistSq &&
|
|
105
|
+
distToBaseboard < distToCabinet &&
|
|
106
|
+
distToBaseboard < distToWall
|
|
107
|
+
) {
|
|
108
|
+
return BASEBOARD_SEMANTIC_NAME;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
let best = ctx.semanticRgb[0];
|
|
112
|
+
let bestDist = Number.POSITIVE_INFINITY;
|
|
113
|
+
|
|
114
|
+
for (const entry of ctx.semanticRgb) {
|
|
115
|
+
if (entry.name === BASEBOARD_SEMANTIC_NAME) {
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
const dist = colorDistanceSq(pixel, entry.rgb);
|
|
119
|
+
if (dist < bestDist) {
|
|
120
|
+
bestDist = dist;
|
|
121
|
+
best = entry;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return best.name;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export function getSemanticColorByName(name: string): MaskSemanticColor | undefined {
|
|
129
|
+
const colors = getMaskSegmentRuntimeConfig().mask.semanticColors;
|
|
130
|
+
return colors.find(entry => entry.name === name);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* 踢脚线须更接近 #F58231 且明显优于黄柜 / 蓝墙,避免整块黄区被误判。
|
|
135
|
+
*/
|
|
136
|
+
export function isStrictBaseboardPixel(
|
|
137
|
+
b: number,
|
|
138
|
+
g: number,
|
|
139
|
+
r: number,
|
|
140
|
+
): boolean {
|
|
141
|
+
const ctx = getSemanticContext();
|
|
142
|
+
const pixel = { r, g, b };
|
|
143
|
+
const distToBaseboard = colorDistanceSq(pixel, ctx.baseboardRgb.rgb);
|
|
144
|
+
const distToCabinet = colorDistanceSq(pixel, ctx.cabinetRgb.rgb);
|
|
145
|
+
const distToWall = colorDistanceSq(pixel, ctx.wallRgb.rgb);
|
|
146
|
+
|
|
147
|
+
return (
|
|
148
|
+
distToBaseboard <= ctx.baseboardMaxColorDistSq &&
|
|
149
|
+
distToBaseboard < distToCabinet &&
|
|
150
|
+
distToBaseboard < distToWall
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export function isBaseboardPixel(b: number, g: number, r: number): boolean {
|
|
155
|
+
return isStrictBaseboardPixel(b, g, r);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/** 掩码上墙/柜交界细条的量化色 */
|
|
159
|
+
export const BASEBOARD_STRIP_QUANT_KEYS = new Set(['0,255,255', '64,255,255']);
|
|
160
|
+
|
|
161
|
+
/** 掩码上墙面量化色 */
|
|
162
|
+
export const WALL_QUANT_KEYS = new Set([
|
|
163
|
+
'192,128,64',
|
|
164
|
+
'192,64,64',
|
|
165
|
+
'128,64,64',
|
|
166
|
+
'192,192,128',
|
|
167
|
+
'128,128,64',
|
|
168
|
+
]);
|
|
169
|
+
|
|
170
|
+
/** 掩码上柜/地面量化色 */
|
|
171
|
+
export const CABINET_QUANT_KEYS = new Set([
|
|
172
|
+
'0,192,255',
|
|
173
|
+
'64,192,255',
|
|
174
|
+
'128,192,255',
|
|
175
|
+
]);
|
|
176
|
+
|
|
177
|
+
export function getBaseboardStripQuantKeys(): Set<string> {
|
|
178
|
+
return getMaskSegmentRuntimeConfig().mask.baseboardStripQuantKeys;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export function getWallQuantKeys(): Set<string> {
|
|
182
|
+
return getMaskSegmentRuntimeConfig().mask.wallQuantKeys;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
export function getCabinetQuantKeys(): Set<string> {
|
|
186
|
+
return getMaskSegmentRuntimeConfig().mask.cabinetQuantKeys;
|
|
187
|
+
}
|