如何在OpenCV中为HoughLinesP指定特定检测区域?
实现HoughLines仅在视频指定区域检测并显示
核心思路
通过创建**区域掩码(Mask)**过滤非目标区域的边缘信息,让Hough变换只处理指定区域内的边缘,最终仅在该区域显示检测到的直线。
具体步骤
- 定义感兴趣区域(ROI):根据视频画面尺寸设置目标区域坐标(支持矩形或自定义多边形)
- 生成掩码:创建与帧尺寸一致的全黑图像,将ROI区域填充为白色
- 过滤边缘图:将Canny输出的边缘图与掩码做按位与操作,仅保留ROI内的边缘
- 执行Hough检测:基于过滤后的边缘图运行HoughLinesP,确保检测结果仅来自目标区域
修改后的完整代码
import cv2 import numpy as np import window_names import track_bars frame_counter = 0 vid = 'rain.mkv' cap = cv2.VideoCapture(vid) # 定义感兴趣区域(ROI),根据实际画面调整坐标 # 示例:取画面下半部分,(x_start, y_start) 到 (x_end, y_end) frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) roi_x1, roi_y1 = 0, int(frame_height * 0.5) roi_x2, roi_y2 = frame_width, frame_height while (True): ret, frame = cap.read() if not ret: break frame_counter += 1 if frame_counter == cap.get(cv2.CAP_PROP_FRAME_COUNT): frame_counter = 0 cap.set(cv2.CAP_PROP_POS_FRAMES, 0) grey = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) output = np.empty(grey.shape, dtype=np.uint8) cv2.normalize(grey, output, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX) hist = cv2.equalizeHist(output) track_bars.lower_threshold = cv2.getTrackbarPos("lower", window_names.window_canny) track_bars.upper_threshold = cv2.getTrackbarPos("upper", window_names.window_canny) track_bars.smoothing_neighbourhood = cv2.getTrackbarPos("smoothing", window_names.window_canny) track_bars.sobel_size = cv2.getTrackbarPos("sobel size", window_names.window_canny) track_bars.smoothing_neighbourhood = max(3, track_bars.smoothing_neighbourhood) if not (track_bars.smoothing_neighbourhood % 2): track_bars.smoothing_neighbourhood += 1 track_bars.sobel_size = max(3, track_bars.sobel_size) if not (track_bars.sobel_size % 2): track_bars.sobel_size += 1 smoothed = cv2.GaussianBlur(hist, (track_bars.smoothing_neighbourhood, track_bars.smoothing_neighbourhood), 0) edges = cv2.Canny(smoothed, track_bars.lower_threshold, track_bars.upper_threshold, apertureSize=track_bars.sobel_size) # 创建掩码并过滤边缘图 mask = np.zeros_like(edges) cv2.rectangle(mask, (roi_x1, roi_y1), (roi_x2, roi_y2), 255, thickness=cv2.FILLED) masked_edges = cv2.bitwise_and(edges, mask) rho = 1 theta = np.pi / 180 threshold = 15 min_line_length = 50 max_line_gap = 20 line_image = np.copy(frame) * 0 # 使用过滤后的边缘图执行Hough检测 lines = cv2.HoughLinesP(masked_edges, rho, theta, threshold, np.array([]), min_line_length, max_line_gap) if lines is not None: for line in lines: x1, y1, x2, y2 = line[0] cv2.line(frame, (x1, y1), (x2, y2), (255, 0, 0), 5) lines_edges = cv2.addWeighted(frame, 0.8, line_image, 1, 0) cv2.imshow(window_names.window_hough, frame) cv2.imshow(window_names.window_canny, masked_edges) # 可选:显示过滤后的边缘图 key = cv2.waitKey(27) if key == ord('x'): break cap.release() cv2.destroyAllWindows()
关键说明
- ROI自定义:可修改
roi_x1, roi_y1, roi_x2, roi_y2调整目标区域;若需多边形区域,用cv2.fillPoly()替代cv2.rectangle()绘制掩码即可 - 掩码作用:从根源上屏蔽非目标区域的边缘,确保Hough变换只处理指定区域的内容
- 调试优化:代码中将显示的边缘图替换为
masked_edges,可直观查看过滤效果,无需时改回edges即可
内容的提问来源于stack exchange,提问作者Isaac_E
相关产品推荐
相关产品推荐

