前言
前面五篇我们已经打通了 图像预处理、降噪、二值化、形态学修复、轮廓筛选,解决了画面噪点、光线干扰、细碎误检问题。
但真实厂区监控还有一个最大、最难解决的工程问题:
监控画面太大、背景太杂、无效区域太多。
比如:
-
只需要检测作业区,但是画面包含天空、路面、远处建筑
-
人员出画面边缘、过道路人、无关人员频繁误触发告警
-
大范围画面导致YOLO算力分散、小目标精度下降
工业安防落地标准方案:不检测全图,只检测有效作业区域。
本节课讲解 ROI感兴趣区域截取 + 局部精细化检测 ,是所有厂区定点监控、区域合规检测、离岗检测、作业区穿戴检测的必备核心技术。
一、什么是 ROI 区域(工业定义)
ROI(Region of Interest)感兴趣区域
通俗理解:只保留我想要检测的区域,其余画面全部屏蔽、变黑、失效。
工业项目价值:
-
屏蔽无效背景干扰,彻底解决远处路人误检
-
缩小检测范围,YOLO聚焦目标区域,小目标精度暴涨
-
减少推理像素,提升视频流帧率
-
实现 指定区域违规才告警,场外人员不触发
二、固定矩形 ROI 截取(最常用、所有项目必用)
厂区监控绝大多数场景:作业区是固定矩形范围,直接坐标截取即可。
完整可运行代码
import cv2 img = cv2.imread("factory.jpg") # 获取画面宽高 h, w = img.shape[:2] # ========== 自定义工业检测区域(根据你的摄像头微调) ========== # 格式:y起始:y结束, x起始:x结束 roi = img[int(h*0.2):int(h*0.9), int(w*0.1):int(w*0.9)] cv2.imshow("Original", img) cv2.imshow("ROI作业区域", roi) cv2.waitKey(0) cv2.destroyAllWindows()
工程技巧:使用百分比截取,适配不同分辨率视频,不用每次改固定像素值。
三、高级玩法:ROI掩码遮罩(推荐工业最终方案)
直接裁剪画面会导致:YOLO坐标错乱、无法回显原图位置。
工业正式项目统一用 掩码 Mask 方案:
原图尺寸不变,无效区域全部涂黑,只保留作业区有效画面
优点:坐标完全对应原图、可直接画框、可截图告警、适配所有YOLO版本。
掩码 ROI 完整代码
import cv2 import numpy as np img = cv2.imread("factory.jpg") h, w = img.shape[:2] # 新建纯黑掩码画布 mask = np.zeros_like(img) # 设定有效检测区域(白色保留,黑色屏蔽) x1, y1 = int(w*0.1), int(h*0.2) x2, y2 = int(w*0.9), int(h*0.9) # 绘制白色有效区域 cv2.rectangle(mask, (x1, y1), (x2, y2), (255, 255, 255), -1) # 原图与掩码相与,只保留作业区 roi_img = cv2.bitwise_and(img, mask) cv2.imshow("Mask", mask) cv2.imshow("ROI工业检测画面", roi_img) cv2.waitKey(0) cv2.destroyAllWindows()
效果:画面外围全部变黑,模型只会处理白色作业区域,场外干扰直接归零。
四、不规则多边形 ROI(适配异形作业区)
部分厂区检测区域不是矩形,是斜坡、梯形、不规则地块,需要多边形ROI精准框选。
import cv2 import numpy as np img = cv2.imread("factory.jpg") h, w = img.shape[:2] mask = np.zeros_like(img) # 自定义多边形点位(根据你的厂区画面微调) pts = np.array([ [int(w*0.05), int(h*0.25)], [int(w*0.95), int(h*0.2)], [int(w*0.98), int(h*0.85)], [int(w*0.02), int(h*0.9)] ], np.int32) # 填充多边形区域 cv2.fillPoly(mask, [pts], (255, 255, 255)) roi_img = cv2.bitwise_and(img, mask) cv2.imshow("Poly ROI", roi_img) cv2.waitKey(0) cv2.destroyAllWindows()
该方案常用于:楼梯口、斜坡作业、局部异形危险区域检测。
五、ROI + 全套预处理 整合流水线
把前面所有课程:降噪、灰度、二值化、形态学、轮廓筛选,全部叠加 ROI 区域限制,形成纯CV完整净化链路。
import cv2 import numpy as np img = cv2.imread("factory.jpg") h, w = img.shape[:2] # 1. ROI掩码区域锁定 mask = np.zeros_like(img) cv2.rectangle(mask, (int(w*0.1), int(h*0.2)), (int(w*0.9), int(h*0.9)), (255,255,255), -1) img_roi = cv2.bitwise_and(img, mask) # 2. 高斯降噪 blur = cv2.GaussianBlur(img_roi, (5,5), 0) # 3. 灰度化 gray = cv2.cvtColor(blur, cv2.COLOR_BGR2GRAY) # 4. 自适应二值化 binary = cv2.adaptiveThreshold(gray,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,15,3) # 5. 形态学去杂点、补孔洞 kernel = np.ones((3,3),np.uint8) binary = cv2.morphologyEx(binary, cv2.MORPH_OPEN, kernel) binary = cv2.morphologyEx(binary, cv2.MORPH_CLOSE, kernel) cv2.imshow("Final Preprocess", binary) cv2.waitKey(0) cv2.destroyAllWindows()
六、工业终极落地:ROI + YOLO 精准区域检测
这是你项目可以直接部署上线的最终版本:
只在作业区内检测安全帽、防护服、人员裸露,区域外人员、杂物完全不干扰。
import cv2 import numpy as np from ultralytics import YOLO model = YOLO("best.onnx") frame = cv2.imread("factory.jpg") h, w = frame.shape[:2] # 1. 构建ROI区域掩码 mask = np.zeros_like(frame) x1, y1 = int(w*0.1), int(h*0.2) x2, y2 = int(w*0.9), int(h*0.9) cv2.rectangle(mask, (x1, y1), (x2, y2), (255,255,255), -1) frame_roi = cv2.bitwise_and(frame, mask) # 2. YOLO推理(仅区域内有效) results = model.predict(frame_roi, imgsz=1280, conf=0.25, iou=0.4) # 3. 绘制结果 + 绘制检测区域框 for res in results: img_out = res.plot() # 画出ROI区域提示框 cv2.rectangle(img_out, (x1, y1), (x2, y2), (0, 0, 255), 2) cv2.putText(img_out, "Detect Area", (x1, y1-10), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0,0,255), 2) cv2.imwrite("roi_yolo_result.jpg", img_out) cv2.imshow("ROI-YOLO Detect", img_out) cv2.waitKey(0) cv2.destroyAllWindows()
七、工业项目落地总结
ROI区域检测是从"实验室模型"变成"上线工程"的关键一步:
-
解决场外路人、背景杂物误检问题
-
聚焦作业区,提升小目标准确率
-
降低算力消耗,视频流更流畅
-
实现合规业务:进入危险区域才检测违规
八、下篇预告
下一篇是 综合实战第一篇:RTSP视频流实时预处理 + YOLO实时检测
正式从图片处理,进入工业监控视频实时推理阶段,全程对接厂区摄像头!