OpenCV如何检测轮廓位置 识别车辆驶出车道并绘制红色轮廓
车道车辆越线轮廓绘制实现方案
核心修改逻辑
- 提前加载黑白车道掩码图转成单通道灰度格式,移出循环避免重复读取损耗性能,其中白色像素对应车道区域、黑色像素对应非车道区域
- 对每个符合面积阈值的车辆轮廓,计算其外接矩形中心坐标(也可采样多个轮廓点提升判断精度)
- 判断坐标对应掩码的像素值,若像素值低于127即处于黑色非车道区域,轮廓用红色绘制,否则用绿色绘制
完整可运行代码
import cv2 import numpy as np def frameDiffer(path): cap = cv2.VideoCapture(path) ret,oldFrame = cap.read() if not ret: print("视频读取失败") return oldGrayFrame = cv2.cvtColor(oldFrame, cv2.COLOR_BGR2GRAY) # 提前加载车道掩码和绘制底图 Roi = cv2.imread('blackAndWhiteRoad.jpg') road_mask = cv2.cvtColor(Roi, cv2.COLOR_BGR2GRAY) mask_h, mask_w = road_mask.shape[:2] while ret: ret, newFrame = cap.read() if not ret: break newGrayFrame = cv2.cvtColor(newFrame, cv2.COLOR_BGR2GRAY) result = cv2.absdiff(newGrayFrame,oldGrayFrame) if np.max(result)>10 : result = cv2.threshold(result, 30, 255, cv2.THRESH_BINARY)[1] result = cv2.GaussianBlur(result,(7,7),4) contours,_ = cv2.findContours(result,cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE) for cnt in contours: if cv2.contourArea(cnt)>150: # 计算轮廓重心 M = cv2.moments(cnt) if M["m00"] == 0: continue cX = int(M["m10"] / M["m00"]) cY = int(M["m01"] / M["m00"]) # 坐标越界直接跳过 if not (0<=cX<mask_w and 0<=cY<mask_h): continue # 判断是否处于非车道区域 if road_mask[cY, cX] < 127: draw_color = (0,0,255) # 越线标红 else: draw_color = (0,255,0) # 正常标绿 cv2.drawContours(Roi,[cnt],-1,draw_color,2) cv2.imshow('result',cv2.resize(Roi,(960,600))) cv2.imshow('newFrame',cv2.resize(newFrame,(960,600))) oldGrayFrame = newGrayFrame if cv2.waitKey(1)==ord('q'): break cap.release() cv2.destroyAllWindows()
可选精度优化
如果需要避免重心刚好落在车道但车身大部分越线的误判,可以采样轮廓上的多个点做判断,替换原有重心判断逻辑即可:
sample_count = min(5, len(cnt)) out_cnt = 0 for i in range(0, len(cnt), max(1, len(cnt)//sample_count)): x,y = cnt[i][0] if 0<=x<mask_w and 0<=y<mask_h and road_mask[y,x]<127: out_cnt +=1 # 超过一半采样点在非车道区域则判定为越线 draw_color = (0,0,255) if out_cnt >= sample_count//2 else (0,255,0)
内容的提问来源于stack exchange,提问作者Tiran
相关产品推荐
相关产品推荐

