yolov7 javascript 调用测试

 学了一段时间的神经网络,尝试了几个版本的yolo模型和其他类型神经网络模型。
前两天看到了js onnx运行时,就测试了下。
先试了试刚在测试的对抗网络,生成人脸……经过了几次尝试修改调用成功了,看上去效果还不错,于是就再试试yolov7了。
yolov7调用是比较顺利的,只是还需后续处理才能得到最后的结果。这个处理代码网上没找到现成的js代码,自己写写算了。
参考C++的代码写了下

function yolov7(data, score_threshold, nms_threshold) {
            let netAnchors = [[10, 13, 16, 30, 33, 23], [30, 61, 62, 45, 59, 119], [116, 90, 156, 198, 373, 326]];
            let netStride = [8, 16, 32, 64]

            let confThreshold = score_threshold;

            let datas = [];
            for (let t in data) {
                datas.push(data[t]);
            }
            datas.sort(function (a, b) { return b.dims[2] - a.dims[2]; });

            let res = [];
            for (let i = 0; i < datas.length; i++) {
                res = res.concat(get(datas[i], netAnchors[i], netStride[i]));
            }

            res = nms(res, score_threshold, nms_threshold);

            return res;

            function sigmoid(v) {
                return 1.0 / (1 + Math.exp(-v));
            }
            function getMaxIndex(data, start, len) {
                let i = 0;
                let v = data[start];
                for (let j = 1; j < len; j++) {
                    if (data[start + j] > v) {
                        v = data[start + j];
                        i = j;
                    }
                }
                return { index: i, score: v };
            }
            function get(data, anchors, stride) {
                let gh = data.dims[2];
                let gw = data.dims[3];
                let c = data.dims[4];
                let classCount = c - 5;
                let res = [];
                let p = 0;
                for (let i = 0; i < data.dims[1]; i++) {
                    let aw = anchors[i * 2];
                    let ah = anchors[i * 2 + 1];

                    for (let gy = 0; gy < gh; gy++) {
                        for (let gx = 0; gx < gw; gx++) {
                            let boxScore = sigmoid(data.data[p + 4]);
                            if (boxScore >= confThreshold) {
                                let indexScore = getMaxIndex(data.data, p + 5, classCount);
                                indexScore.score = sigmoid(indexScore.score);
                                if (indexScore.score >= confThreshold) {
                                    let x = (sigmoid(data.data[p]) * 2 - 0.5 + gx) * stride;
                                    let y = (sigmoid(data.data[p + 1]) * 2 - 0.5 + gy) * stride;
                                    let w = Math.pow(sigmoid(data.data[p + 2]) * 2, 2) * aw;
                                    let h = Math.pow(sigmoid(data.data[p + 3]) * 2, 2) * ah;
                                    res.push({
                                        x: (x - 0.5 * w),
                                        y: (y - 0.5 * h),
                                        w: w,
                                        h: h,
                                        index: indexScore.index,
                                        score: indexScore.score
                                    });
                                }

                            }
                            p += c;
                        }
                    }
                }
                return res;
            }
            function iou(a, b) {
                var aa = a.w * a.h;
                var ba = b.w * b.h;
                var x = Math.max(a.x, b.x);
                var y = Math.max(a.y, b.y);
                var xx = Math.min(a.x + a.w, b.x + b.w);
                var yy = Math.min(a.y + a.h, b.y + b.h);
                var w = xx - x;
                var h = yy - y;
                if (w <= 0 || h <= 0) return 0;
                var area = w * h;

                return area / (aa + ba - area);

            }
            function nms(boxs, score_threshold, nms_threshold) {
                let score_indexs = [];
                for (var i = 0; i < boxs.length; i++) {
                    if (boxs[i].score > score_threshold)
                        score_indexs.push({ second: i, first: boxs[i].score });
                }
                score_indexs.sort(function (a, b) { return b.first - a.first });
                let res = [];
                let adaptive_threshold = nms_threshold;

                for (let i = 0; i < score_indexs.length; i++) {
                    let idx = score_indexs[i].second;
                    let keep = true;
                    for (let k = 0; k < res.length && keep; k++) {
                        let k_idx = res[k];
                        let v = iou(boxs[idx], boxs[k_idx]);
                        keep = v <= adaptive_threshold;
                    }
                    if (keep) {
                        res.push(idx);
                    }
                }
                for (let i = 0; i < res.length; i++) {
                    res[i] = boxs[res[i]];
                }
                return res;
            }
        }

调用

    <!--运行时的js -->
    <script src="https://cdn.jsdelivr.net/npm/onnxruntime-web/dist/ort.min.js"></script>
    <canvas width="800" height="800" id="can"></canvas>

    <script>
        let can = document.getElementById("can");
        let ctx = can.getContext("2d");

        function getData() {
            let w = can.width;
            let h = can.height;
            let wh = w * h;
            let img = ctx.getImageData(0, 0, w, h).data;
            let datas = new Array(3 * wh);
            let j = 0;
            for (let i = 0; i < img.length; i += 4) {
                datas[j] = img[i] / 255.0;
                datas[wh + j] = img[i + 1] / 255.0;
                datas[wh * 2 + j] = img[i + 2] / 255.0;
                j++;
            }
            return datas;
        }

        function drawBoxs(boxs, labs) {
            ctx.strokeStyle = "#ff0000";
            ctx.strokeWidth = 1;
            ctx.font = '18px Arial';
            ctx.beginPath();

            for (let i = 0; i < boxs.length; i++) {
                ctx.rect(boxs[i].x, boxs[i].y, boxs[i].w, boxs[i].h);
                ctx.strokeText(labs[boxs[i].index], boxs[i].x, boxs[i].y);
            }
            ctx.stroke();
        }

        async function mainYoloV7(imageData, width, height) {
            try {
                const session = await ort.InferenceSession.create('./best.onnx');
                const dataA = Float32Array.from(imageData);
                const tensorA = new ort.Tensor('float32', dataA, [1, 3, height, width]);

                const feeds = { images: tensorA };
                let results = await session.run(feeds);

                let boxs = yolov7(results, 0.26, 0.4);

                drawBoxs(boxs, "0,1,2,3,4,5,6,7,8,9,-".split(','));

            } catch (e) {
                document.write(`failed to inference ONNX model: ${e}.`);
                console.log(e);
            }
        }
        let image = document.createElement("img");

        image.onload = function () {
            can.width = parseInt(image.width / 32) * 32;
            can.height = parseInt(image.height / 32) * 32;
            ctx.drawImage(image, 0, 0);
            mainYoloV7(getData(), can.width, can.height);
        }
        image.src = "2.png";

    </script>

以上调用是在 yolov7 tiny 的模型测试的,导出 onnx 时 --grid 参数=False

简单测试结果

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值