SOT · 2022年10月18日 · 陕西

基于opencv与flask实现实时传输摄像头图像

硬件:eaidk610(fedaro28)、普通带usb接口摄像头
软件环境: python3.9、opencv4.6、Flask2.2

主要实现了从板子的连接的摄像头收集图像并在网页中展示,板子上没有安装任何编辑器,所以主要代码都是在win11下使用pycharm编写,下面是文件目录。
 title=

数据传输

因为传输图像是实时的并且随着时间拉长数据量会很大,所以必须把应答的数据以一种类似分块的形式发送,算是一种流媒体技术。
关于数据更新问题,有两种方式(客户端拉拽和服务器推送),具体内容如果感兴趣可以去网上深入了解,由于篇幅这里不过多解释。本次为简单起见,选用服务器推送的方式,使用如下报文格式
mimetype='multipart/x-mixed-replace; boundary=frame'
multipart/mixed可以使得多个数据块共用一个报文头
replace可以使得新的数据块覆盖旧的数据块,凭借这个来实现网页画面更新
boundary是两个数据块的边界标志

数据格式定义好了之后使用yield生成器函数来获取每个数据块(也就是每个图像数据)

将数据块封装好之后通过flask库中的Response返回给客户端

数据收集

使用opencv中的VideoCapture()来使用摄像头文件,括号里可以写摄像头的编号或者文件(基本都是0 1 或者/dev/video0 | video1)
检测摄像头正常开启后,读取图像,因为opencv读到的图像是格式为(w,h,3)的像素矩阵,所以要通过下列语句将其转换为字节流
np.array(cv2.imencode('.jpg', img)[1]).tobytes()
在使用摄像头的时间犯了小错误,将开启摄像头的语句放在了类型定义的外面
video = cv.VideoCapture(0)
class Camera(object):
····def __init__(self):
········pass

在执行文件的时候一直发现开启不了摄像头,然后去查看文件占用进程
fuser -uv "/dev/video1"
dir USER PID ACCESS COMMAND
/dev/video1: root 32372 F...m (root)python3
发现确实被程序占用着,突然想起来python在导入文件的时候会先执行一遍,定义所有变量和函数,应该是这时候把摄像头占用了,于是把开启语句放在类中之后就没有错误了
class Camera(object):
····def __init__(self):
········self.video = cv.VideoCapture(1)

实现结果

设置host为当前设备的ip地址以允许局域网内其他设备访问
A}F@P[C3U(_G59~49Q85~Z4.pngND6_T4VM9T}RDT5{DSB](_D.png

项目存放在https://github.com/Onenormler...下的NetCamera目录

推荐阅读
关注数
1
文章数
2
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息