如何将处理后的Numpy帧作为video_reference传入Roboflow推理管道
解决方案
方案一:手动处理帧并调用推理(推荐)
由于video_reference仅支持视频路径、设备ID或RTSP流,无法直接传入处理后的帧,最直接的解决方式是手动控制帧的采集与处理流程,跳过InferencePipeline的自动流读取逻辑,直接调用推理接口并处理结果。
修改后的完整代码
import cv2 import os import time import numpy as np from roboflow import Roboflow from Cropping import ExtractAndStraightenFromImage from LocateGrid import DetectGrid # 初始化Roboflow模型 rf = Roboflow(api_key="<your-api-key>") project = rf.workspace().project("crap-object-detection") model = project.version(1).model IMAGE_FILE_PATH = os.path.join("Capture", "BoardPictures") # 创建截图保存目录 if not os.path.exists(IMAGE_FILE_PATH): os.makedirs(IMAGE_FILE_PATH) # 启动摄像头 vid = cv2.VideoCapture(0) is_automatic = False def apply_morphological_ops(img): kernel = np.ones((5,5),np.uint8) opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel) return opening def my_custom_sink(predictions, frame): # 这里保留你原有的结果处理逻辑,比如绘制检测框、输出结果等 print(predictions) try: while True: ret, frame = vid.read() if not ret: print("Failed to grab frame") break key = cv2.waitKey(1) # 空格键保存截图 if key == 32: unique_filename = time.strftime("%Y%m%d_%H%M%S") + ".png" screenshot_path = os.path.join(IMAGE_FILE_PATH, unique_filename) boardImg = ExtractAndStraightenFromImage(frame) cv2.imwrite(screenshot_path, boardImg) print(f"Screenshot saved as {screenshot_path}") # 裁剪校正帧 boardImg = ExtractAndStraightenFromImage(frame) # 调用Roboflow推理接口 predictions = model.predict(boardImg, confidence=40, overlap=30).json() # 传入自定义结果处理函数 my_custom_sink(predictions, boardImg) # 显示画面 cv2.imshow("Frame", frame) cv2.imshow("Board img", boardImg) finally: vid.release() cv2.destroyAllWindows()
方案二:创建虚拟视频流供Pipeline读取
如果一定要使用InferencePipeline的video_reference参数,可以将处理后的帧推送到本地虚拟视频流(如RTSP),再让Pipeline读取该流地址。
实现步骤
- 安装ffmpeg用于创建RTSP流服务;
- 在帧处理循环中,将校正后的
boardImg写入虚拟流; - 将虚拟流地址传入
video_reference。
示例代码
import cv2 import os import time import numpy as np from roboflow import Roboflow from Cropping import ExtractAndStraightenFromImage from LocateGrid import DetectGrid # 初始化推理管道,读取本地RTSP流 pipeline = Roboflow.InferencePipeline.init( model_id="crap-object-detection/1", api_key="<your-api-key>", video_reference="rtsp://localhost:8554/stream", on_prediction=my_custom_sink, ) pipeline.start() IMAGE_FILE_PATH = os.path.join("Capture", "BoardPictures") if not os.path.exists(IMAGE_FILE_PATH): os.makedirs(IMAGE_FILE_PATH) vid = cv2.VideoCapture(0) # 替换为你的boardImg实际宽高 BOARD_IMG_WIDTH = 640 BOARD_IMG_HEIGHT = 480 # 配置VideoWriter,推送帧到RTSP流 fourcc = cv2.VideoWriter_fourcc(*'H264') out = cv2.VideoWriter( 'rtsp://localhost:8554/stream', fourcc, 20.0, (BOARD_IMG_WIDTH, BOARD_IMG_HEIGHT) ) def apply_morphological_ops(img): kernel = np.ones((5,5),np.uint8) opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel) return opening def my_custom_sink(predictions, frame): # 自定义结果处理逻辑 print(predictions) try: while True: ret, frame = vid.read() if not ret: print("Failed to grab frame") break key = cv2.waitKey(1) if key == 32: unique_filename = time.strftime("%Y%m%d_%H%M%S") + ".png" screenshot_path = os.path.join(IMAGE_FILE_PATH, unique_filename) boardImg = ExtractAndStraightenFromImage(frame) cv2.imwrite(screenshot_path, boardImg) print(f"Screenshot saved as {screenshot_path}") boardImg = ExtractAndStraightenFromImage(frame) # 将处理后的帧写入虚拟流 out.write(cv2.resize(boardImg, (BOARD_IMG_WIDTH, BOARD_IMG_HEIGHT))) cv2.imshow("Frame", frame) cv2.imshow("Board img", boardImg) finally: vid.release() out.release() cv2.destroyAllWindows() pipeline.stop()
注意:此方案需提前启动ffmpeg的RTSP服务,例如执行命令:ffmpeg -listen 1 -i rtsp://localhost:8554/stream -c copy -f rtsp rtsp://localhost:8554/stream
内容的提问来源于stack exchange,提问作者doodle911
相关产品推荐
相关产品推荐

