Anonymous
Маска сегментации пост-обработки из модели ONNX в Интернете (Onnx Runtime JS)
Сообщение
Anonymous » 30 апр 2025, 10:00
В настоящее время я работаю над тем, чтобы запустить свою пользовательскую модель сегментации ONNX непосредственно в браузере, используя время выполнения ONNX для Web с HTML и JavaScript. Модель успешно загружает и выполняет вывод. Тем не менее, я застрял на логике постобработки, в частности, когда речь идет о фильтрации и визуализации маски сегментации.
Я был бы признателен любые рекомендации или примеры реализаций для:
/> Правильно фильтрация /порога маски сегментации в JavaScript < /p>
Мой случай использования аналогичен тому, как Yolov8-SEG выводит маски, но адаптирован для веб-сайта выполнения ONNX. Если у кого-то есть опыт работы с выходами сегментации пост-обработки в браузере с использованием моделей ONNX, ваш ввод был бы очень полезным.
Выходная сегменция:
Ввод изображение здесь
фактическая бит:
. /> html -код: < /strong> < /p>
Код: Выделить всё
YOLOv8 Segmentation Viewer
canvas {
border: 1px solid black;
display: block;
margin-top: 10px;
}
YOLOv8 Segmentation Mask Demo
const inputSize = 640;
document.getElementById("upload").addEventListener("change", async (e) => {
const file = e.target.files[0];
const img = new Image();
img.src = URL.createObjectURL(file);
img.onload = async () => {
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0);
const offscreen = new OffscreenCanvas(inputSize, inputSize);
const offCtx = offscreen.getContext("2d");
offCtx.drawImage(img, 0, 0, inputSize, inputSize);
const imageData = offCtx.getImageData(0, 0, inputSize, inputSize);
const inputTensor = preprocess(imageData);
const session = await ort.InferenceSession.create("best_on.onnx");
const feeds = { images: inputTensor };
const results = await session.run(feeds);
const output0 = results[Object.keys(results)[0]].data;
const output1 = results[Object.keys(results)[1]].data;
const [numProposals, numChannels] = [8400, 37];
const prototypeH = 160;
const prototypeW = 160;
for (let i = 0; i < numProposals; i++) {
const conf = output0[i * numChannels + 4];
if (conf < 0.5) continue;
const maskCoeffs = output0.slice(
i * numChannels + 5,
i * numChannels + 5 + 32
);
const mask = new Float32Array(prototypeH * prototypeW).fill(0);
for (let m = 0; m < 32; m++) {
for (let j = 0; j < prototypeH * prototypeW; j++) {
mask[j] += maskCoeffs[m] * output1[m * prototypeH * prototypeW + j];
}
}
for (let j = 0; j < mask.length; j++) {
mask[j] = 1 / (1 + Math.exp(-mask[j]));
}
drawMaskOnCanvas(
mask,
prototypeH,
prototypeW,
canvas,
ctx,
img.width,
img.height
);
break;
}
};
});
function preprocess(imageData) {
const [r, g, b] = [[], [], []];
for (let i = 0; i < imageData.data.length; i += 4) {
r.push(imageData.data[i] / 255);
g.push(imageData.data[i + 1] / 255);
b.push(imageData.data[i + 2] / 255);
}
return new ort.Tensor(
"float32",
new Float32Array([...r, ...g, ...b]),
[1, 3, 640, 640]
);
}
function drawMaskOnCanvas(mask, maskH, maskW, canvas, ctx, imgW, imgH) {
const imageData = ctx.getImageData(0, 0, imgW, imgH);
const maskResized = resizeMask(mask, maskW, maskH, imgW, imgH);
for (let y = 0; y < imgH; y++) {
for (let x = 0; x < imgW; x++) {
const m = maskResized[y * imgW + x];
if (m > 1) {
const idx = (y * imgW + x) * 4;
imageData.data[idx] = 255;
imageData.data[idx + 1] = 0;
imageData.data[idx + 2] = 0;
imageData.data[idx + 3] = 100;
}
}
}
ctx.putImageData(imageData, 0, 0);
}
function resizeMask(src, srcW, srcH, dstW, dstH) {
const dst = new Float32Array(dstW * dstH);
for (let y = 0; y < dstH; y++) {
const sy = ((y + 0.5) * srcH) / dstH - 0.5;
const y0 = Math.max(Math.floor(sy), 0);
const y1 = Math.min(y0 + 1, srcH - 1);
const yLerp = sy - y0;
for (let x = 0; x < dstW; x++) {
const sx = ((x + 0.5) * srcW) / dstW - 0.5;
const x0 = Math.max(Math.floor(sx), 0);
const x1 = Math.min(x0 + 1, srcW - 1);
const xLerp = sx - x0;
const top =
(1 - xLerp) * src[y0 * srcW + x0] + xLerp * src[y0 * srcW + x1];
const bottom =
(1 - xLerp) * src[y1 * srcW + x0] + xLerp * src[y1 * srcW + x1];
dst[y * dstW + x] = (1 - yLerp) * top + yLerp * bottom;
}
}
return dst;
}
Кто -нибудь из них предлагает мне, что я делаю неправильно, где -нибудь?>
Подробнее здесь:
https://stackoverflow.com/questions/795 ... runtime-js
1745996422
Anonymous
В настоящее время я работаю над тем, чтобы запустить свою пользовательскую модель сегментации ONNX непосредственно в браузере, используя время выполнения ONNX для Web с HTML и JavaScript. Модель успешно загружает и выполняет вывод. Тем не менее, я застрял на логике постобработки, в частности, когда речь идет о фильтрации и визуализации маски сегментации. Я был бы признателен любые рекомендации или примеры реализаций для: /> Правильно фильтрация /порога маски сегментации в JavaScript < /p> Мой случай использования аналогичен тому, как Yolov8-SEG выводит маски, но адаптирован для веб-сайта выполнения ONNX. Если у кого-то есть опыт работы с выходами сегментации пост-обработки в браузере с использованием моделей ONNX, ваш ввод был бы очень полезным. [b] Выходная сегменция: [/b] Ввод изображение здесь фактическая бит: . /> html -код: < /strong> < /p> [code] YOLOv8 Segmentation Viewer canvas { border: 1px solid black; display: block; margin-top: 10px; } YOLOv8 Segmentation Mask Demo const inputSize = 640; document.getElementById("upload").addEventListener("change", async (e) => { const file = e.target.files[0]; const img = new Image(); img.src = URL.createObjectURL(file); img.onload = async () => { const canvas = document.getElementById("canvas"); const ctx = canvas.getContext("2d"); canvas.width = img.width; canvas.height = img.height; ctx.drawImage(img, 0, 0); const offscreen = new OffscreenCanvas(inputSize, inputSize); const offCtx = offscreen.getContext("2d"); offCtx.drawImage(img, 0, 0, inputSize, inputSize); const imageData = offCtx.getImageData(0, 0, inputSize, inputSize); const inputTensor = preprocess(imageData); const session = await ort.InferenceSession.create("best_on.onnx"); const feeds = { images: inputTensor }; const results = await session.run(feeds); const output0 = results[Object.keys(results)[0]].data; const output1 = results[Object.keys(results)[1]].data; const [numProposals, numChannels] = [8400, 37]; const prototypeH = 160; const prototypeW = 160; for (let i = 0; i < numProposals; i++) { const conf = output0[i * numChannels + 4]; if (conf < 0.5) continue; const maskCoeffs = output0.slice( i * numChannels + 5, i * numChannels + 5 + 32 ); const mask = new Float32Array(prototypeH * prototypeW).fill(0); for (let m = 0; m < 32; m++) { for (let j = 0; j < prototypeH * prototypeW; j++) { mask[j] += maskCoeffs[m] * output1[m * prototypeH * prototypeW + j]; } } for (let j = 0; j < mask.length; j++) { mask[j] = 1 / (1 + Math.exp(-mask[j])); } drawMaskOnCanvas( mask, prototypeH, prototypeW, canvas, ctx, img.width, img.height ); break; } }; }); function preprocess(imageData) { const [r, g, b] = [[], [], []]; for (let i = 0; i < imageData.data.length; i += 4) { r.push(imageData.data[i] / 255); g.push(imageData.data[i + 1] / 255); b.push(imageData.data[i + 2] / 255); } return new ort.Tensor( "float32", new Float32Array([...r, ...g, ...b]), [1, 3, 640, 640] ); } function drawMaskOnCanvas(mask, maskH, maskW, canvas, ctx, imgW, imgH) { const imageData = ctx.getImageData(0, 0, imgW, imgH); const maskResized = resizeMask(mask, maskW, maskH, imgW, imgH); for (let y = 0; y < imgH; y++) { for (let x = 0; x < imgW; x++) { const m = maskResized[y * imgW + x]; if (m > 1) { const idx = (y * imgW + x) * 4; imageData.data[idx] = 255; imageData.data[idx + 1] = 0; imageData.data[idx + 2] = 0; imageData.data[idx + 3] = 100; } } } ctx.putImageData(imageData, 0, 0); } function resizeMask(src, srcW, srcH, dstW, dstH) { const dst = new Float32Array(dstW * dstH); for (let y = 0; y < dstH; y++) { const sy = ((y + 0.5) * srcH) / dstH - 0.5; const y0 = Math.max(Math.floor(sy), 0); const y1 = Math.min(y0 + 1, srcH - 1); const yLerp = sy - y0; for (let x = 0; x < dstW; x++) { const sx = ((x + 0.5) * srcW) / dstW - 0.5; const x0 = Math.max(Math.floor(sx), 0); const x1 = Math.min(x0 + 1, srcW - 1); const xLerp = sx - x0; const top = (1 - xLerp) * src[y0 * srcW + x0] + xLerp * src[y0 * srcW + x1]; const bottom = (1 - xLerp) * src[y1 * srcW + x0] + xLerp * src[y1 * srcW + x1]; dst[y * dstW + x] = (1 - yLerp) * top + yLerp * bottom; } } return dst; } [/code] Кто -нибудь из них предлагает мне, что я делаю неправильно, где -нибудь?> Подробнее здесь: [url]https://stackoverflow.com/questions/79599708/post-processing-segmentation-mask-from-onnx-model-in-web-onnx-runtime-js[/url]