简单使用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,不过有时会卡住)

运行效果

截图:

简单使用TensorFlow.js在浏览器进行视频实时目标识别(基于YOLO V3)

GIF:

简单使用TensorFlow.js在浏览器进行视频实时目标识别(基于YOLO V3)

运行方式

推荐放到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 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="http://www.likecs.com/tfjs-m.min.js"></script> <script src="http://www.likecs.com/config.js"></script> <script src="http://www.likecs.com/yolo-tfjs-m.js"></script> <div>等待模型载入...</div> <br> <div> <video muted="true" autoplay src="http://www.likecs.com/demo01.mp4" controls="" playsinline="" webkit-playsinline=""> </video> <!-- 用于展示识别框 --> <div> </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

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwzxjp.html