You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

红色高亮断线与黄色高亮虚线的检测及补全方案求助

样例图像

可行解决方案

以下方案可同时解决红色区域断线被圆点拆分、黄色区域虚线无法拼接的问题:

1. 预处理:分离目标区域

先通过颜色阈值把红色、黄色标注的区域单独提取出来,排除其他无关内容的干扰:

  • 将图像转换为HSV色彩空间,分别设置红色、黄色的HSV阈值生成掩码
  • 用掩码和灰度原图做与运算,仅保留对应标注区域内的图形内容

2. 红色区域断线补全

针对红色区域内圆点打断主线段的问题,处理步骤如下:

  • 对红色区域做3x3圆形核的形态学开运算,消除区域内的小圆点噪声,不会腐蚀主线段
  • 用1x15的水平矩形核做形态学闭运算,填充被圆点打断的线段缝隙,将多段碎线连接为完整线段
  • 做轮廓检测后过滤长度不足的短轮廓,对保留的长轮廓用cv2.fitLine()做直线拟合,得到主线段参数后直接在对应位置绘制完整线条即可

3. 黄色区域虚线拼接

针对黄色区域虚线的拼接需求,处理步骤如下:

  • 对黄色区域做二值化处理,提取虚线的短段为前景
  • 调整概率霍夫变换的参数:将最小线段长度设为虚线单段的长度,最大线段间隙设为两段虚线之间的间隔,检测出所有属于虚线的短线段
  • 对检测到的短线段做分类:斜率接近0的归为水平虚线类,斜率绝对值极大的归为垂直虚线类
  • 对同一类的线段取坐标极值拼接:水平虚线取所有线段y坐标的平均值、x坐标的最小最大值,直接绘制完整水平线;垂直虚线取x坐标的平均值、y坐标的最小最大值,绘制完整垂直线

核心代码示例(Python + OpenCV)

import cv2
import numpy as np

# 读取输入图像
img = cv2.imread("input.png")
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

# 生成红色区域掩码
lower_red1 = np.array([0, 120, 70])
upper_red1 = np.array([10, 255, 255])
lower_red2 = np.array([170, 120, 70])
upper_red2 = np.array([180, 255, 255])
mask_red = cv2.inRange(hsv, lower_red1, upper_red1) + cv2.inRange(hsv, lower_red2, upper_red2)

# 生成黄色区域掩码
lower_yellow = np.array([20, 100, 100])
upper_yellow = np.array([30, 255, 255])
mask_yellow = cv2.inRange(hsv, lower_yellow, upper_yellow)

# ---------------------- 红色区域处理 ----------------------
red_gray = cv2.bitwise_and(cv2.cvtColor(img, cv2.COLOR_BGR2GRAY), mask_red)
# 开运算消除小圆点
kernel_open = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))
red_processed = cv2.morphologyEx(red_gray, cv2.MORPH_OPEN, kernel_open, iterations=1)
# 水平闭运算连接断线
kernel_close = cv2.getStructuringElement(cv2.MORPH_RECT, (15, 1))
red_processed = cv2.morphologyEx(red_processed, cv2.MORPH_CLOSE, kernel_close, iterations=2)
# 拟合主线段
contours, _ = cv2.findContours(red_processed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for cnt in contours:
    # 过滤长度不足的短轮廓
    if cv2.arcLength(cnt, closed=False) > 50:
        [vx, vy, x, y] = cv2.fitLine(cnt, cv2.DIST_L2, 0, 0.01, 0.01)
        # 计算直线两端点坐标
        left_y = int((-x * vy / vx) + y)
        right_y = int(((img.shape[1] - x) * vy / vx) + y)
        cv2.line(img, (0, left_y), (img.shape[1] - 1, right_y), (0, 255, 0), 2)

# ---------------------- 黄色区域处理 ----------------------
yellow_gray = cv2.bitwise_and(cv2.cvtColor(img, cv2.COLOR_BGR2GRAY), mask_yellow)
_, yellow_bin = cv2.threshold(yellow_gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
# 概率霍夫变换检测虚线短段
lines = cv2.HoughLinesP(yellow_bin, 1, np.pi / 180, threshold=10, minLineLength=8, maxLineGap=20)
horizontal_segs = []
vertical_segs = []
if lines is not None:
    for line in lines:
        x1, y1, x2, y2 = line[0]
        if abs(y2 - y1) < 5:
            horizontal_segs.append((x1, y1, x2, y2))
        elif abs(x2 - x1) < 5:
            vertical_segs.append((x1, y1, x2, y2))
# 拼接水平虚线
if horizontal_segs:
    y_avg = int(np.mean([seg[1] for seg in horizontal_segs]))
    x_min = min([min(seg[0], seg[2]) for seg in horizontal_segs])
    x_max = max([max(seg[0], seg[2]) for seg in horizontal_segs])
    cv2.line(img, (x_min, y_avg), (x_max, y_avg), (0, 255, 0), 2)
# 拼接垂直虚线
if vertical_segs:
    x_avg = int(np.mean([seg[0] for seg in vertical_segs]))
    y_min = min([min(seg[1], seg[3]) for seg in vertical_segs])
    y_max = max([max(seg[1], seg[3]) for seg in vertical_segs])
    cv2.line(img, (x_avg, y_min), (x_avg, y_max), (0, 255, 0), 2)

内容的提问来源于stack exchange,提问作者Taarun Srinivas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 15:15:03