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

如何从含噪图像中提取蓝红箭头?OpenCV-Python实现遇阻

含噪图像中提取蓝红色箭头的优化方案

问题背景

我需要从一张含噪图像中提取仅有的4个箭头,但噪声过滤难度极大,且箭头处于蓝色和红色的HSV色域范围,颜色过滤存在不小的困难。已尝试以下OpenCV-Python操作,但均未达到理想的箭头过滤效果:

  • 应用GaussianBlur模糊降噪
  • 提取色相通道后使用Canny边缘检测
  • 轮廓检测与绘制
  • 先进行颜色过滤再执行Canny边缘检测

附相关图像:
原始含噪图像
中间处理图像1
中间处理图像2

针对性优化思路与实现

1. 分区间颜色掩码+形态学去噪

红色在HSV色域中属于跨0度的特殊区间,需要拆分两段提取;蓝色使用常规区间提取。合并两种颜色的掩码后,通过形态学闭操作填充箭头内部缝隙,开操作清除零散噪声点。

import cv2
import numpy as np

# 读取图像并转换为HSV色域
img = cv2.imread("your_image_path.png")
hsv_img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

# 提取红色掩码(HSV双区间)
lower_red1 = np.array([0, 50, 50])
upper_red1 = np.array([10, 255, 255])
lower_red2 = np.array([170, 50, 50])
upper_red2 = np.array([180, 255, 255])
red_mask1 = cv2.inRange(hsv_img, lower_red1, upper_red1)
red_mask2 = cv2.inRange(hsv_img, lower_red2, upper_red2)
red_mask = cv2.bitwise_or(red_mask1, red_mask2)

# 提取蓝色掩码
lower_blue = np.array([90, 50, 50])
upper_blue = np.array([120, 255, 255])
blue_mask = cv2.inRange(hsv_img, lower_blue, upper_blue)

# 合并红蓝掩码
combined_mask = cv2.bitwise_or(red_mask, blue_mask)

# 形态学操作优化掩码
kernel = np.ones((3, 3), np.uint8)
# 闭操作填充箭头内部空洞
combined_mask = cv2.morphologyEx(combined_mask, cv2.MORPH_CLOSE, kernel, iterations=2)
# 开操作去除小噪声点
combined_mask = cv2.morphologyEx(combined_mask, cv2.MORPH_OPEN, kernel, iterations=1)

2. 轮廓几何特征筛选

提取掩码中的轮廓后,通过面积范围、近似多边形边数等箭头特有的几何特征,过滤掉噪声轮廓:

# 提取外部轮廓
contours, _ = cv2.findContours(combined_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
arrow_contours = []

for cnt in contours:
    # 过滤面积异常的轮廓
    area = cv2.contourArea(cnt)
    if area < 100 or area > 5000:
        continue
    # 多边形近似,简化轮廓
    epsilon = 0.05 * cv2.arcLength(cnt, True)
    approx_shape = cv2.approxPolyDP(cnt, epsilon, True)
    # 箭头的近似多边形边数通常在6-9之间,以此为筛选条件
    if 6 <= len(approx_shape) <= 9:
        arrow_contours.append(cnt)

# 绘制筛选出的箭头轮廓
result_img = img.copy()
cv2.drawContours(result_img, arrow_contours, -1, (0, 255, 0), 2)
cv2.imshow("Extracted Arrows", result_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

3. 颜色掩码与边缘检测结合

先对原始图像做Canny边缘检测,再通过颜色掩码过滤掉非目标颜色的边缘,进一步减少噪声干扰:

# 提取原始图像边缘
edges = cv2.Canny(img, 50, 150)
# 保留颜色掩码范围内的边缘
masked_edges = cv2.bitwise_and(edges, combined_mask)
# 基于掩码边缘提取轮廓(后续可复用步骤2的筛选逻辑)
contours_from_edges, _ = cv2.findContours(masked_edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

内容的提问来源于stack exchange,提问作者Keefe Ho

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 14:45:33