簡單使用TensorFlow.js在瀏覽器進行視頻實時目標識別(基於COCO-SSD)


!!! 完全忘記當時是怎么寫了,我不會了 !!!

背景

在GitHub查看 TensorFlow.js 的項目時,
發現的一個模型,覺得還不錯,就試着運行了一下

GitHub地址: https://github.com/tensorflow/tfjs-models/tree/master/coco-ssd

運行原理

使用 TensorFlow.js 導入訓練好的 COCO-SSD 模型,
對視頻或者圖片進行檢測,拿到對應的坐標之后顯示.
在這里我是使用div絕對定位顯示對於的框框.

大概流程:

  • 使用video標簽載入MP4文件
  • 使用TensorFlow.js 載入 COCO-SSD 模型
  • 調用模型檢測方法,獲取坐標並顯示到頁面
  • 使用setTimeout進行延遲后進行下一次檢測
  • (也可以requestAnimationFrame,不過有時會卡住)

運行效果

截圖:

gif:

代碼

相關文件我放到網盤和QQ群
群號: 492781269
城通網盤: https://306t.com/file/29360148-460317614
下面直接公示代碼.

<!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-width: 600px;
            width: 100%;
        }
    </style>
</head>

<body>

    <script src="tfjs.min.js"></script>
    <script src="coco-ssd-m.min.js"></script>

    <div id="showBox">等待模型載入...</div>
    <br>

    <div id="big-box">
        <video id="myPlayer" muted="true" autoplay src="demo.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;

        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.
            cocoSsd.load().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) {
                myModel.detect(V).then(predictions => {

                    showBox.innerHTML = "識別完畢";

                    const $imgbox = document.getElementById('img-box');

                    $imgbox.innerHTML = ""

                    predictions.forEach(box => {

                        const $div = document.createElement('div')
                        $div.className = 'rect';
                        var heightScale = (clientHeight / videoHeight);
                        var widthScale = (clientWidth / videoWidth)
                        var transformTop = box.bbox[1] * heightScale;
                        var transformLeft = box.bbox[0] * widthScale;
                        var transformWidth = box.bbox[2] * widthScale;
                        var transformHeight = box.bbox[3] * 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.class} ${box.score}</span>`

                        $imgbox.appendChild($div)


                    })
                    // detectImage();
                    setTimeout(function () {
                        detectImage();
                    }, 10);

                });

            }


        }


    </script>
</body>

</html>

運行方式

推薦放到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 端口

PS:
如有錯誤,還請多多指出來~

– Nick
– 2020/09/05


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM