如何通过Python+ImageAI+OpenCV显示带目标标记的实时摄像头画面
报错原因
你写的逐帧检测代码报错,是因为调用detectObjectsFromImage()时缺少input_type="array"参数。该接口默认将输入值当作图片文件路径处理,你直接传入OpenCV读取的numpy格式帧数据时,程序会尝试把数组当路径传给cv2.imread()读取,最终触发参数校验错误。
你的需求完全可以通过ImageAI实现,下面给出两种可行的实现方案:
实现方案
方案1:修正逐帧检测逻辑(灵活度最高)
只需要补全检测接口的input_type参数,同时修正原代码里摄像头对象名的笔误(原代码最后写的vid.release()不存在对应对象,你定义的摄像头实例名为camera),即可实现实时预览带检测标记的画面。修正后的完整代码如下:
from imageai.Detection import ObjectDetection import cv2 camera = cv2.VideoCapture(0) # 可选:降低摄像头分辨率提升运行帧率 camera.set(cv2.CAP_PROP_FRAME_WIDTH, 640) camera.set(cv2.CAP_PROP_FRAME_HEIGHT, 480) detector = ObjectDetection() detector.setModelTypeAsYOLOv3() detector.setModelPath(r"C:\Users\Luca\Desktop\image\yolo.h5") detector.loadModel() while True: ret, frame = camera.read() if not ret: break returned_image, detections = detector.detectObjectsFromImage( input_image=frame, input_type="array", # 关键参数:声明输入是numpy数组格式的图像 output_type="array" ) # 打印检测结果 for eachObject in detections: print(eachObject["name"], " : ", eachObject["percentage_probability"], " : ", eachObject["box_points"]) print("--------------------------------") # 实时显示带检测框的画面 cv2.imshow('实时目标检测', returned_image) # 按q键退出程序 if cv2.waitKey(1) & 0xFF == ord('q'): break # 释放资源 camera.release() cv2.destroyAllWindows()
该方案自由度最高,你可以自行添加检测框自定义、按键截图、结果记录等扩展逻辑。
方案2:调用VideoObjectDetection的帧回调实现预览
如果你不需要自定义太多逻辑,可以直接用视频检测接口自带的帧回调功能,不需要等程序终止就能实时看到处理后的画面,同时会自动保存检测完成的视频文件。示例代码如下:
from imageai.Detection import VideoObjectDetection import cv2 camera = cv2.VideoCapture(0) # 可选:降低摄像头分辨率提升运行帧率 camera.set(cv2.CAP_PROP_FRAME_WIDTH, 640) camera.set(cv2.CAP_PROP_FRAME_HEIGHT, 480) detector = VideoObjectDetection() detector.setModelTypeAsYOLOv3() detector.setModelPath(r"C:\Users\Luca\Desktop\image\yolo.h5") detector.loadModel() # 定义每一帧处理完成后触发的回调函数 def frame_process_callback(frame_number, output_array, output_count, returned_frame): # 打印检测结果 for eachObject in output_array: print(eachObject["name"], " : ", eachObject["percentage_probability"], " : ", eachObject["box_points"]) print("--------------------------------") # 显示带标记的检测画面 cv2.imshow("实时目标检测", returned_frame) # 按q键退出 if cv2.waitKey(1) & 0xFF == ord('q'): camera.release() cv2.destroyAllWindows() exit() # 启动视频检测 detector.detectObjectsFromVideo( camera_input=camera, output_file_path=r"C:\Users\Luca\Desktop\image\footage_detected", frames_per_second=20, per_frame_function=frame_process_callback, return_detected_frame=True, # 关键参数:返回处理后的带标记帧供回调使用 log_progress=True ) camera.release() cv2.destroyAllWindows()
该方案运行帧率比逐帧检测方案稍高,适合不需要额外定制逻辑的场景。
内容的提问来源于stack exchange,提问作者jerico
相关产品推荐
相关产品推荐

