如何在Python中平滑图像检测所得的锯齿状线条?
如何平滑颜色检测得到的锯齿状黑色线条?
我目前通过颜色值检测图像中的黑色区域,肉眼看是清晰的直线,但颜色检测后得到的是锯齿状线条,尝试了多种方法都无效,求帮助。
锯齿状线条:
原图:
我已尝试的方法:
- Hough变换
- Canny边缘检测后执行Hough变换
- 基于RGB通道、HSV通道、LAB通道及各通道差值的颜色分析
- 自定义线条检测算法
使用的代码如下:
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) r_channel = img[:, :, 2] b_channel = img[:, :, 0] r_mask = cv2.inRange(r_channel, 0, 145) mask1 = cv2.inRange(img_gray, 0,200) final_mask = cv2.bitwise_and(mask1, r_mask)
解决方案
1. 预处理阶段做高斯模糊
在颜色检测前对原图做高斯模糊,减少噪声干扰,从源头降低锯齿产生的可能:
# 先对原图做高斯模糊,核大小可根据实际情况调整 blur_img = cv2.GaussianBlur(img, (5,5), 0) # 基于模糊后的图像执行后续颜色检测 img_gray = cv2.cvtColor(blur_img, cv2.COLOR_BGR2GRAY) r_channel = blur_img[:, :, 2] r_mask = cv2.inRange(r_channel, 0, 145) mask1 = cv2.inRange(img_gray, 0,200) final_mask = cv2.bitwise_and(mask1, r_mask)
2. 对生成的掩码做形态学处理
通过闭操作填补掩码中的小缺口,开操作去除边缘毛刺,最后用模糊平滑边缘:
# 创建3x3的矩形结构元素,尺寸可按需调整 kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3)) # 闭操作:先膨胀再腐蚀,填补线条内部的小空隙 closed_mask = cv2.morphologyEx(final_mask, cv2.MORPH_CLOSE, kernel) # 开操作:先腐蚀再膨胀,清除边缘的锯齿状毛刺 opened_mask = cv2.morphologyEx(closed_mask, cv2.MORPH_OPEN, kernel) # 最后高斯模糊进一步平滑边缘 smoothed_mask = cv2.GaussianBlur(opened_mask, (3,3), 0)
3. 优化颜色检测阈值
当前阈值范围过宽,容易纳入边缘杂色。缩小阈值范围,精准锁定黑色区域:
# 收紧红色通道和灰度通道的阈值,仅保留更纯的黑色区域 r_mask = cv2.inRange(r_channel, 0, 80) mask1 = cv2.inRange(img_gray, 0, 100) final_mask = cv2.bitwise_and(mask1, r_mask)
4. 轮廓拟合优化线条
提取掩码中的轮廓,用多边形逼近得到平滑的直线轮廓:
import numpy as np # 提取掩码中的外部轮廓 contours, _ = cv2.findContours(final_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 创建空白画布用于绘制平滑线条 smooth_line_img = np.zeros_like(final_mask) for cnt in contours: # 计算轮廓周长,以此确定逼近精度 arc_len = cv2.arcLength(cnt, True) # 多边形逼近,epsilon越小越接近原轮廓,越大线条越平滑 approx = cv2.approxPolyDP(cnt, 0.01 * arc_len, True) # 绘制拟合后的平滑轮廓 cv2.drawContours(smooth_line_img, [approx], -1, 255, thickness=2)
可组合使用上述方法,比如先通过模糊+阈值优化得到干净的掩码,再做形态学处理+轮廓拟合,能有效得到平滑的直线效果。
内容的提问来源于stack exchange,提问作者박성호
相关产品推荐
相关产品推荐

