将PyuEye/PyPyuEye接入OpenCV图像跟踪脚本的实现方案
PyuEye视频流接入运动跟踪代码解决方案
核心说明
你无法用单条代码直接替换cv2.VideoCapture(0),PyuEye的设备初始化、帧读取是拆分的多步操作,我们可以直接复用官方示例的相机连接逻辑,替换原有代码的视频输入部分即可。
完整整合代码
from pyueye import ueye import numpy as np import cv2 # ---------------------- PyuEye初始化部分(替换原cv2.VideoCapture逻辑) ---------------------- hCam = ueye.HIDS(0) # 0代表取第一个可用相机,1-254对应指定ID的相机 sInfo = ueye.SENSORINFO() cInfo = ueye.CAMINFO() pcImageMemory = ueye.c_mem_p() MemID = ueye.int() rectAOI = ueye.IS_RECT() pitch = ueye.INT() nBitsPerPixel = ueye.INT(24) # 彩色模式24位,黑白模式改为8 m_nColorMode = ueye.INT() bytes_per_pixel = int(nBitsPerPixel / 8) # 初始化相机连接 nRet = ueye.is_InitCamera(hCam, None) if nRet != ueye.IS_SUCCESS: print("相机初始化失败") exit() # 获取相机和传感器参数 ueye.is_GetCameraInfo(hCam, cInfo) ueye.is_GetSensorInfo(hCam, sInfo) ueye.is_ResetToDefault(hCam) ueye.is_SetDisplayMode(hCam, ueye.IS_SET_DM_DIB) # 自动匹配相机颜色模式 if int.from_bytes(sInfo.nColorMode.value, byteorder='big') == ueye.IS_COLORMODE_BAYER: ueye.is_GetColorDepth(hCam, nBitsPerPixel, m_nColorMode) bytes_per_pixel = int(nBitsPerPixel / 8) elif int.from_bytes(sInfo.nColorMode.value, byteorder='big') == ueye.IS_COLORMODE_CBYCRY: m_nColorMode = ueye.IS_CM_BGRA8_PACKED nBitsPerPixel = ueye.INT(32) bytes_per_pixel = int(nBitsPerPixel / 8) elif int.from_bytes(sInfo.nColorMode.value, byteorder='big') == ueye.IS_COLORMODE_MONOCHROME: m_nColorMode = ueye.IS_CM_MONO8 nBitsPerPixel = ueye.INT(8) bytes_per_pixel = int(nBitsPerPixel / 8) else: m_nColorMode = ueye.IS_CM_MONO8 nBitsPerPixel = ueye.INT(8) bytes_per_pixel = int(nBitsPerPixel / 8) # 获取相机有效画面尺寸 ueye.is_AOI(hCam, ueye.IS_AOI_IMAGE_GET_AOI, rectAOI, ueye.sizeof(rectAOI)) width = rectAOI.s32Width height = rectAOI.s32Height # 分配图像内存并启动视频流 nRet = ueye.is_AllocImageMem(hCam, width, height, nBitsPerPixel, pcImageMemory, MemID) if nRet != ueye.IS_SUCCESS: print("内存分配失败") ueye.is_ExitCamera(hCam) exit() ueye.is_SetImageMem(hCam, pcImageMemory, MemID) ueye.is_SetColorMode(hCam, m_nColorMode) nRet = ueye.is_CaptureVideo(hCam, ueye.IS_DONT_WAIT) if nRet != ueye.IS_SUCCESS: print("视频流启动失败") ueye.is_FreeImageMem(hCam, pcImageMemory, MemID) ueye.is_ExitCamera(hCam) exit() ueye.is_InquireImageMem(hCam, pcImageMemory, MemID, width, height, nBitsPerPixel, pitch) # 封装帧读取函数(替代原cap.read()) def get_frame(): array = ueye.get_data(pcImageMemory, width, height, nBitsPerPixel, pitch, copy=False) frame = np.reshape(array, (height.value, width.value, bytes_per_pixel)) # 如果是4通道BGRA格式,转为OpenCV兼容的BGR格式 if bytes_per_pixel ==4: frame = cv2.cvtColor(frame, cv2.COLOR_BGRA2BGR) # 可根据需要调整缩放比例,不需要缩放可以注释掉下一行 frame = cv2.resize(frame, (0,0), fx=0.5, fy=0.5) return True, frame # ---------------------- 原有跟踪逻辑(仅替换视频输入部分) ---------------------- # 高帧率低精度用MOSSE,低帧率高精度用CSRT,修正原代码的CSST拼写错误 tracker = cv2.TrackerMOSSE_create() # tracker = cv2.TrackerCSRT_create() success, img = get_frame() bbox = cv2.selectROI("Tracking", img, False) tracker.init(img, bbox) def drawBox(img, bbox): x,y,w,h = int(bbox[0]),int(bbox[1]),int(bbox[2]),int(bbox[3]) cv2.rectangle(img,(x,y),((x+w),(y+h)),(255,0,255),3,1) cv2.putText(img, "Tracking", (75, 75), cv2.FONT_HERSHEY_COMPLEX, 0.7, (0, 255, 255), 2) while True: timer = cv2.getTickCount() success, img = get_frame() success, bbox = tracker.update(img) if success: drawBox(img, bbox) else: cv2.putText(img, "Lost", (75, 75), cv2.FONT_HERSHEY_COMPLEX, 0.7, (0, 0, 255), 2) fps = cv2.getTickFrequency()/(cv2.getTickCount()-timer) cv2.putText(img, str(int(fps)), (75,50), cv2.FONT_HERSHEY_COMPLEX, 0.7,(0,0,255),2) cv2.imshow("Tracking",img) if cv2.waitKey(1) & 0xff == ord('q'): break # ---------------------- 资源释放 ---------------------- ueye.is_FreeImageMem(hCam, pcImageMemory, MemID) ueye.is_ExitCamera(hCam) cv2.destroyAllWindows()
关键调整点
- 用PyuEye的官方初始化逻辑完全替代
cv2.VideoCapture(0)的设备连接功能 - 封装
get_frame()函数替代原cap.read(),实现从PyuEye共享内存中读取帧并转换为OpenCV可用格式 - 修正了原代码中
cv2.TrackerCSST_create()的拼写错误,正确API为cv2.TrackerCSRT_create() - 增加了异常分支的资源释放逻辑,避免程序异常退出后相机被占用
内容的提问来源于stack exchange,提问作者Colin Warn
相关产品推荐
相关产品推荐

