树莓派通过UDP实现从OpenCV向EmguCV传输摄像头图像帧的技术咨询
我来帮你完善这个基于UDP协议,从树莓派OpenCV向EmguCV传输摄像头图像帧的代码实现,下面是整理好的完整方案:
树莓派端OpenCV UDP发送图像帧代码
这个方案利用树莓派的picamera模块采集图像,转成OpenCV可处理的格式,压缩为JPEG后通过UDP发送——UDP的低延迟特性非常适合实时图像传输场景,虽然存在少量丢包风险,但对实时性要求高的场景很友好。
from picamera.array import PiRGBArray from picamera import PiCamera import time import cv2 import socket import numpy as np import sys class Cam(): def __init__(self, ip, port): # 初始化UDP套接字 self._s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self._address = (ip, port) # JPEG压缩参数:质量80,平衡清晰度和传输大小 self._quality = [int(cv2.IMWRITE_JPEG_QUALITY), 80] def run(self): # 初始化树莓派摄像头 self._cam = PiCamera() # 可根据需求调整分辨率和帧率 self._cam.resolution = (640, 480) self._cam.framerate = 30 rawCapture = PiRGBArray(self._cam, size=(640, 480)) # 给摄像头预热时间 time.sleep(0.1) try: # 循环采集图像帧 for frame in self._cam.capture_continuous(rawCapture, format="bgr", use_video_port=True): # 获取当前帧的numpy数组 image = frame.array # 这里可以添加你的图像处理代码(你提到已删除,保留位置方便后续扩展) # 压缩图像为JPEG格式,减少传输数据量 _, img_encoded = cv2.imencode('.jpg', image, self._quality) # 转成字节流发送 self._s.sendto(img_encoded.tobytes(), self._address) # 清空缓存,准备下一帧 rawCapture.truncate(0) except KeyboardInterrupt: # 捕获Ctrl+C,优雅退出 print("传输终止") self._cam.close() self._s.close() sys.exit() # 替换为你的EmguCV接收端的IP和端口 if __name__ == "__main__": sender = Cam("192.168.1.100", 5000) sender.run()
关键细节说明
- JPEG压缩:默认设置的质量80,你可以根据实际需求调整——数值越高清晰度越好,但传输数据量越大,容易导致UDP包过大丢包。
- 摄像头参数:
resolution和framerate可以根据网络带宽和需求调整,比如降低分辨率来提升传输流畅度。 - UDP特性:UDP不需要建立连接,所以接收端必须提前监听指定端口,否则发送的数据包会丢失。
EmguCV端UDP接收图像帧思路
在EmguCV(C#)这边,你需要监听对应UDP端口,接收字节流后转成Mat对象:
- 初始化UDP客户端,绑定指定端口
- 循环接收字节数据
- 将字节数据转成
MemoryStream,再通过CvInvoke.Imdecode解析为Mat - 显示或处理图像帧
内容的提问来源于stack exchange,提问作者Oscar Martinez
相关产品推荐
相关产品推荐

