zoukankan      html  css  js  c++  java
  • 简单使用TensorFlow.js在浏览器进行视频实时目标识别(基于YOLO V3)

    !!! 完全忘记当时是怎么写了,我不会了 !!!

    背景

    在GitHub查看 TensorFlow.js 的项目时,...
    继上次的官方实例之后,又在GitHub发现了新的实现方式.

    GitHub地址: https://github.com/zqingr/tfjs-yolov3

    运行原理

    使用 TensorFlow.js 导入转换后的 YOLO-V3 模型,
    对视频或者图片进行检测,拿到对应的坐标之后显示.
    在这里我是使用div绝对定位显示对于的框框.

    (有一个巨大的BUG,一段时间后会占满GPU,然后黑屏)

    大概流程:

    • 使用video标签载入MP4文件
    • 使用TensorFlow.js 载入 YOLO-V3 模型
    • 调用模型检测方法,获取坐标并显示到页面
    • 使用setTimeout进行延迟后进行下一次检测
    • (也可以requestAnimationFrame,不过有时会卡住)

    运行效果

    截图:

    GIF:

    运行方式

    推荐放到web软件容器当中
    例如: Nginx
    我自己是使用 http-server 启动的web服务
    然后访问相对应的地址就好了.

    关于http-server

    http-server需要先安装 Node.js 和 npm
    然后运行npm安装命令:

    npm install http-server -g
    

    安装完之后,去指定文件夹运行命令,就可以启动一个静态文件服务器
    例如

    http-server . -p 2333
    

    其中的 . 代表当前目录
    -p 指定端口,后面的 2333 表示使用 2333 端口

    代码

    相关文件我放到网盘和QQ群
    群号: 492781269
    城通网盘: https://306t.com/file/29360148-466426046
    下面直接公示代码.

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>TensorFlow.js Demo</title>
        <style>
            #big-box {
                position: relative;
            }
    
            #img-box {
                position: absolute;
                top: 0px;
                left: 0px;
            }
    
            #img-box .rect {
                position: absolute;
                border: 2px solid #f00;
                pointer-events: none;
            }
    
            #img-box .rect .className {
                position: absolute;
                top: 0;
                /* background: #f00; */
                color: #fff;
            }
    
            #myPlayer {
                max- 600px;
                 100%;
            }
        </style>
    </head>
    
    <body>
    
        <script src="tfjs-m.min.js"></script>
        <script src="config.js"></script>
        <script src="yolo-tfjs-m.js"></script>
    
        <div id="showBox">等待模型载入...</div>
        <br>
    
        <div id="big-box">
            <video id="myPlayer" muted="true" autoplay src="demo01.mp4" controls="" playsinline="" webkit-playsinline="">
            </video>
            <!-- 用于展示识别框 -->
            <div id="img-box">
    
            </div>
        </div>
    
    
        <script>
    
            var myModel = null;
            var V = null;
    
            var requestAnimationFrameIndex = null;
            var myPlayer = document.getElementById("myPlayer");
    
            var videoHeight = 0;
            var videoWidth = 0;
            var clientHeight = 0;
            var clientWidth = 0;
    
            var modelLoad = false;
            var videoLoad = false;
    
            var anchors = ANCHORS_TINY;
            var modelUrl = 'yolov3-tiny/model.json';
            var modelPromise = tf.loadLayersModel(modelUrl);
    
            window.onload = function () {
    
                // 当视频准备好了就准备开始识别吧
                myPlayer.addEventListener("canplay", function () {
                    videoHeight = myPlayer.videoHeight;
                    videoWidth = myPlayer.videoWidth;
                    clientHeight = myPlayer.clientHeight;
                    clientWidth = myPlayer.clientWidth;
                    V = this;
                    videoLoad = true;
                })
    
                loadModel();
            }
    
            // 载入模型文件
            function loadModel() {
                if (modelLoad) {
                    return;
                }
    
                // Load the model.
                modelPromise.then(model => {
                    var showBox = document.getElementById("showBox");
                    showBox.innerHTML = "载入成功";
                    myModel = model;
                    detectImage();
                    modelLoad = true;
                });
    
            }
    
            // 识别图片,并在页面展示
            function detectImage() {
    
                var showBox = document.getElementById("showBox");
                showBox.innerHTML = "识别中...";
    
                if (videoLoad) {
    
                    // 准备用于识别的样本
                    var sample = tf.stack([
                        tf.div(tf.cast(tf.browser.fromPixels(V), 'float32'), 255)
                    ])
    
                    // 获取到识别的结果
                    let output = (myModel.predict(sample));
    
                    // 
                    output = output.map(feats =>
                        feats.reshape(feats.shape.slice(1))
                    )
    
                    var boxes = yoloEval(
                        output,
                        tf.tensor1d(anchors).reshape([-1, 2]),
                        COCO_CLASSESS.length,
                        [videoHeight, videoWidth]
                    )
    
                    boxes.then(myBoxes => {
    
                        showBox.innerHTML = "识别完毕";
                        var $imgbox = document.getElementById('img-box');
                        $imgbox.innerHTML = "";
    
                        myBoxes.forEach(box => {
    
                            var $div = document.createElement('div');
                            $div.className = 'rect';
    
                            var heightScale = (clientHeight / videoHeight);
                            var widthScale = (clientWidth / videoWidth);
                            var transformTop = box.top * heightScale;
                            var transformLeft = box.left * widthScale;
                            var transformWidth = box.width * widthScale;
                            var transformHeight = box.height * heightScale;
    
                            $div.style.top = transformTop + 'px';
                            $div.style.left = transformLeft + 'px';
                            $div.style.width = transformWidth + 'px';
                            $div.style.height = transformHeight + 'px';
                            $div.innerHTML = `<span class='className'>${box.classes} ${box.scores}</span>`;
    
                            $imgbox.appendChild($div);
                        })
    
                        setTimeout(function () {
                            detectImage();
                        }, 10);
    
                    })
    
                }
    
            }
    
        </script>
    </body>
    
    </html>
    

    PS:
    如有错误,还请多多指出来~

    – Nick
    – 2020/10/12

  • 相关阅读:
    《张艺谋这个人》较真
    《智能》是真智能
    《解密小米之互联网下的商业奇迹》
    《三毛。。。。》烂漫
    《盛典―― 诺奖之行》
    常用iOS、Mac框架和库及常用中文开发博客
    《人脸识别与人体动作识别技术及应用》
    《程序员第二步从程序员到项目经理》
    《信息安全导论》
    [leetCode]141.环形链表
  • 原文地址:https://www.cnblogs.com/inick/p/13804411.html
Copyright © 2011-2022 走看看