用 javascript 标记像素的连通分量?
Connected components labeling pixels with javascript?
我有一组像素。从一开始我就需要从 PNG 中删除黑色背景,然后以某种方式将剩余的白色像素分组到数组中。每个子数组都对应于像素(形状)斑点坐标。问题是如何在 javascript 中进行连接组件标记?也许有一个图书馆可以做到这一点?
[[10,34,34,10],[72, 300, 72, 30]]
这是我去除黑色像素的方法:
const black2transparent = (img: HTMLImageElement) => {
const c = document.createElement("canvas");
const w = img.width;
const h = img.height;
c.width = w;
c.height = h;
const ctx = c.getContext("2d");
if (!ctx) {
return "";
}
ctx.drawImage(img, 0, 0, w, h);
const imageData = ctx.getImageData(0, 0, w, h);
const pixel = imageData.data;
const r = 0;
const g = 1;
const b = 2;
const a = 3;
for (let p = 0; p < pixel.length; p += 4) {
if (pixel[p + r] === 0 && pixel[p + g] === 0 && pixel[p + b] === 0) {
pixel[p + a] = 0;
}
}
ctx.putImageData(imageData, 0, 0);
return c.toDataURL("image/png");
};
const black2transparent = (img: HTMLImageElement) => {
const c = document.createElement("canvas");
const w = img.width;
const h = img.height;
c.width = w;
c.height = h;
const ctx = c.getContext("2d");
if (!ctx) {
return "";
}
ctx.drawImage(img, 0, 0, w, h);
const imageData = ctx.getImageData(0, 0, w, h);
const pixel = imageData.data;
const r = 0;
const g = 1;
const b = 2;
const a = 3;
let x = 1;
let y = 0;
const whiteLines = [];
let lastWhitePixelStart = null;
for (let p = 0; p < pixel.length; p += 4) {
if (p > 0 && p % (w * 4) === 0) {
x = 1;
lastWhitePixelStart = null;
y += 1;
} else {
x += 1;
}
if (pixel[p + r] === 0 && pixel[p + g] === 0 && pixel[p + b] === 0) {
pixel[p + a] = 0;
if (lastWhitePixelStart !== null) {
whiteLines.push([lastWhitePixelStart, { x, y }]);
lastWhitePixelStart = null;
}
} else {
if (lastWhitePixelStart === null) {
lastWhitePixelStart = { x, y };
}
}
}
const blobs: MaskDataType[] = [];
while (whiteLines.length) {
let line = whiteLines.shift();
if (!line) break;
let categorized = false;
for (let i = 0; i < blobs.length; i += 1) {
let blob = blobs[i];
if (blob.maxY + 2 < line[0].y) continue;
if (blob.minX > line[1].x || blob.maxX < line[0].x) {
continue;
}
blob.maxY = line[0].y;
blob.minX = Math.min(blob.minX, line[0].x);
blob.maxX = Math.min(blob.maxX, line[1].x);
blob.lines.push(line);
categorized = true;
}
if (!categorized) {
blobs.push({
minY: line[0].y,
maxY: line[0].y,
minX: line[0].x,
maxX: line[1].x,
lines: [line],
});
}
}
// blob contains array of white pixels coordinates
setMaskData(blobs);
ctx.putImageData(imageData, 0, 0);
return c.toDataURL("image/png");
};
像素数组在 blob 中
我有一组像素。从一开始我就需要从 PNG 中删除黑色背景,然后以某种方式将剩余的白色像素分组到数组中。每个子数组都对应于像素(形状)斑点坐标。问题是如何在 javascript 中进行连接组件标记?也许有一个图书馆可以做到这一点?
[[10,34,34,10],[72, 300, 72, 30]]
这是我去除黑色像素的方法:
const black2transparent = (img: HTMLImageElement) => {
const c = document.createElement("canvas");
const w = img.width;
const h = img.height;
c.width = w;
c.height = h;
const ctx = c.getContext("2d");
if (!ctx) {
return "";
}
ctx.drawImage(img, 0, 0, w, h);
const imageData = ctx.getImageData(0, 0, w, h);
const pixel = imageData.data;
const r = 0;
const g = 1;
const b = 2;
const a = 3;
for (let p = 0; p < pixel.length; p += 4) {
if (pixel[p + r] === 0 && pixel[p + g] === 0 && pixel[p + b] === 0) {
pixel[p + a] = 0;
}
}
ctx.putImageData(imageData, 0, 0);
return c.toDataURL("image/png");
};
const black2transparent = (img: HTMLImageElement) => {
const c = document.createElement("canvas");
const w = img.width;
const h = img.height;
c.width = w;
c.height = h;
const ctx = c.getContext("2d");
if (!ctx) {
return "";
}
ctx.drawImage(img, 0, 0, w, h);
const imageData = ctx.getImageData(0, 0, w, h);
const pixel = imageData.data;
const r = 0;
const g = 1;
const b = 2;
const a = 3;
let x = 1;
let y = 0;
const whiteLines = [];
let lastWhitePixelStart = null;
for (let p = 0; p < pixel.length; p += 4) {
if (p > 0 && p % (w * 4) === 0) {
x = 1;
lastWhitePixelStart = null;
y += 1;
} else {
x += 1;
}
if (pixel[p + r] === 0 && pixel[p + g] === 0 && pixel[p + b] === 0) {
pixel[p + a] = 0;
if (lastWhitePixelStart !== null) {
whiteLines.push([lastWhitePixelStart, { x, y }]);
lastWhitePixelStart = null;
}
} else {
if (lastWhitePixelStart === null) {
lastWhitePixelStart = { x, y };
}
}
}
const blobs: MaskDataType[] = [];
while (whiteLines.length) {
let line = whiteLines.shift();
if (!line) break;
let categorized = false;
for (let i = 0; i < blobs.length; i += 1) {
let blob = blobs[i];
if (blob.maxY + 2 < line[0].y) continue;
if (blob.minX > line[1].x || blob.maxX < line[0].x) {
continue;
}
blob.maxY = line[0].y;
blob.minX = Math.min(blob.minX, line[0].x);
blob.maxX = Math.min(blob.maxX, line[1].x);
blob.lines.push(line);
categorized = true;
}
if (!categorized) {
blobs.push({
minY: line[0].y,
maxY: line[0].y,
minX: line[0].x,
maxX: line[1].x,
lines: [line],
});
}
}
// blob contains array of white pixels coordinates
setMaskData(blobs);
ctx.putImageData(imageData, 0, 0);
return c.toDataURL("image/png");
};
像素数组在 blob 中