Маска сегментации пост-обработки из модели ONNX в Интернете (Onnx Runtime JS)Javascript

Форум по Javascript
Ответить
Anonymous
 Маска сегментации пост-обработки из модели ONNX в Интернете (Onnx Runtime JS)

Сообщение Anonymous »

В настоящее время я работаю над тем, чтобы запустить свою пользовательскую модель сегментации 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
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Javascript»