硬件:eaidk610(fedaro28)、普通带usb接口摄像头
软件环境: python3.9、opencv4.6、Flask2.2
主要实现了从板子的连接的摄像头收集图像并在网页中展示,板子上没有安装任何编辑器,所以主要代码都是在win11下使用pycharm编写,下面是文件目录。
数据传输
因为传输图像是实时的并且随着时间拉长数据量会很大,所以必须把应答的数据以一种类似分块的形式发送,算是一种流媒体技术。
关于数据更新问题,有两种方式(客户端拉拽和服务器推送),具体内容如果感兴趣可以去网上深入了解,由于篇幅这里不过多解释。本次为简单起见,选用服务器推送的方式,使用如下报文格式 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地址以允许局域网内其他设备访问
项目存放在https://github.com/Onenormler...下的NetCamera目录