如何隔离地图图像中的红灰色矩形并去噪用于神经网络训练
方案优化与问题解决
灰色、红色矩形同步隔离方法
灰色线条和背景的核心差异在HSV颜色空间的饱和度通道:灰色属于无彩色,饱和度值极低,和普通带颜色的背景/其他线条区分度极高,不需要提前修改颜色,直接通过多阈值过滤即可同时提取两类矩形:
修正后的掩码提取代码
import cv2 import numpy as np im = cv2.imread("你的地图图片路径.png") hsv = cv2.cvtColor(im, cv2.COLOR_BGR2HSV) # 1. 提取红色掩码(修正原阈值范围,避免混入其他颜色) # 红色在HSV中分布在0°-10°和170°-180°两个区间 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_red1 = cv2.inRange(hsv, lower_red1, upper_red1) mask_red2 = cv2.inRange(hsv, lower_red2, upper_red2) mask_red = mask_red1 | mask_red2 # 2. 提取灰色掩码(低饱和度+亮度区间过滤,适配和背景相近的灰色) # 可根据实际灰度亮度调整lower_gray和upper_gray的V值 lower_gray = np.array([0, 0, 50]) upper_gray = np.array([180, 30, 220]) mask_gray = cv2.inRange(hsv, lower_gray, upper_gray) # 形态学去噪,修复原代码的输入错误(原代码第二次形态学操作错误使用thresh而非clean后的结果) kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (9,9)) mask_red = cv2.morphologyEx(mask_red, cv2.MORPH_OPEN, kernel) mask_gray = cv2.morphologyEx(mask_gray, cv2.MORPH_OPEN, kernel) kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (15,15)) mask_red = cv2.morphologyEx(mask_red, cv2.MORPH_CLOSE, kernel) mask_gray = cv2.morphologyEx(mask_gray, cv2.MORPH_CLOSE, kernel)
之后你可以直接把两个掩码合并后反转,就能得到白底黑矩形的训练用图,不需要做蓝色区域的inpaint操作。
整体需求的更优实现思路
67万张量级的数据集完全可以用传统几何判断实现需求,无需训练CNN,耗时和准确率都更可控:
- 提前提取蓝色掩码:和上面的逻辑一致,用HSV阈值提取蓝色线条的掩码,再提取所有蓝色矩形的轮廓和最小外接矩形参数
- 问题1判断:计算
mask_red & (~mask_gray)的非零像素数,超过设定的噪声阈值(比如10个像素)即可判定存在未覆盖在灰色线条上的红色线条 - 问题2判断:提取红色线条的最小外接矩形的四个顶点,调用
cv2.pointPolygonTest()判断是否有顶点落在蓝色矩形的轮廓内部,只要有至少2个顶点在内部,即可判定红色矩形部分处于蓝色矩形内部
原方案的可优化点
- 原第一步的蓝色区域inpaint完全不必要,直接保留蓝色掩码做几何判断即可,inpaint反而可能引入额外的噪声影响后续线条提取
- 原红色阈值范围设置过宽(0-120的H值),会混入蓝色、紫色等其他颜色的像素,修正为两个红色区间的阈值后准确率会大幅提升
- 原形态学操作第二步错误使用原始阈值图作为输入,导致第一次开运算的去噪效果完全失效,修正为使用前一步处理后的掩码作为输入即可
内容的提问来源于stack exchange,提问作者redwytnblakII
相关产品推荐
相关产品推荐

