images/blog-posts

影像处理・网络摄像头

返回教程主页

上篇 影像处理・调用摄像头

了解到如何使用OpenCV调用摄像头并显示视频内容后,我们可以尝试实现支持远程客户端的网络摄像头。我们将使用到OpenCV以及WebSockets。

WebSockets的安装方法记载如下:

pip install websockets

服务器程序

我们在服务器上打开摄像头,然后分享给“遥远”的客户端:

import asyncio

import websockets
import cv2 as cv


async def capture(websocket, path):
    while video.isOpened():
        ret, frame = video.read()
        if not ret: continue
        _, buf = cv.imencode('.jpeg', frame)
        await websocket.send(buf.tobytes())
        await asyncio.sleep(0.05)

async def main():
    async with websockets.serve(capture, "0.0.0.0", 5678):
        await asyncio.Future()

video = cv.VideoCapture(0)
try:
    asyncio.run(main())
except KeyboardInterrupt:
    if video.isOpened():
        video.release()

有几个地方需要说明:

  • import asyncio 我们需要引入这个异步模块来帮助处理异步问题
  • import websockets 需要的WebSocket模块
  • def capture 定义用于处理视频发送的函数,当有客户端连接时会触发「需要使用async做异步声明」
  • cv.imencode 将numpy数组转换成字节数据,便于被浏览器使用
  • websocket.send 发送视频数据,需要使用await做等待声明
  • asyncio.sleep 控制摄像头读取频率
  • websockets.serve 启动一个服务,传入参数capture,主机地址,端口号
  • asyncio.run 运行主程序

有关WebSockets的更多内容可以去往项目文档网站进行了解: https://websockets.readthedocs.io/en/stable/index.html

客户端HTML

可以创建一个名为index.html的文本文件「注意.html是扩展名」,复制粘贴以下代码并保存:

<!DOCTYPE html>
<html>
    <head>
        <title>OpenCV&WebSocket</title>
    </head>
    <body>
        <img id="img"/>
    </body>
</html>
<script>
var ws = new WebSocket(`ws://${location.hostname}:5678/`);
var image = document.querySelector('#img');
ws.onmessage = function (event) {
    image.src = URL.createObjectURL(event.data);
};
</script>

运行测试

首先,我们运行服务端程序,这与之前的代码的运行没有不同,因此不做具体说明。

然后,我们在HTML文件所在的目录下开启一个静态文件服务器,例如:

python3 -m http.server

这时用浏览器访问http://<你的局域网IP地址>:8000,如果不出意外,你将看到浏览器中正在显示你电脑摄像头所拍摄的影像。如果你的手机与你的电脑在同一个局域网下「例如都连接家里的路由器」,那么你可以尝试用手机浏览器进行访问。

下篇 影像处理・目标检测

SUBSCRIBE


🔒 No spam. Unsubscribe any time.

About kk

kk

Vincenzo Antedoro is an engineer who helps those who want to invest in renewables. For the rest he enjoys teaching with the method of learning by doing..

» More about kk