1. 使用Python、OpenCV计算轮廓的中心并标记
2. 使用Python、OpenCV检测轮廓的形状并标记
3. 使用颜色通道统计信息来标记形状的实际颜色并标记
该博文可以看做是以上3篇的进阶版,这篇博客将介绍从图像中删除指定的轮廓;
1. 效果图
在保留矩形的同时删除圆/椭圆,效果图如下:
2. 步骤
从图像中删除轮廓的基本算法如下所示:
- 在图像中检测并找到轮廓;
- 分别在轮廓上循环;
- 确定轮廓是否需要删除,并应根据一些标准删除;
- 累积一个个需要被删除的轮廓的遮罩Mask;
- 使用按位“与”将累积的不良轮廓遮罩应用于原始图像。
算法本身非常简单,需要注意和考虑的主要是步骤3,确定是否应该删除轮廓。
3. 源码
# USAGE
# python remove_contours.py
# 导入必要的包
import numpy as np
import imutils
import cv2
# 在保留矩形的同时删除圆/椭圆,矩形有四条边。圆没有边。
# 如果近似有4个点(顶点),则轮廓将保持不变,表示轮廓是矩形。
def is_contour_bad(c):
# 近似轮廓
peri = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, 0.02 * peri, True)
# 如果不是矩形则认为是bad轮廓,需要删除
return not len(approx) == 4
# 加载图形图像,将其转换为灰度,并检测边缘
image = cv2.imread("shapes.png")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
edged = cv2.Canny(gray, 50, 100)
cv2.imshow("Original", image)
# 寻找轮廓,并初始化要删除的轮廓mask
cnts = cv2.findContours(edged.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts) #兼容不同opencv版本获取轮廓
mask = np.ones(image.shape[:2], dtype="uint8") * 255 #初始化一个mask
# 遍历轮廓
for c in cnts:
# 如果轮廓需要删除,则绘制在mask上以累积轮廓
if is_contour_bad(c):
cv2.drawContours(mask, [c], -1, 0, -1)
# 在图像上移除轮廓,并展示结果图像
# 注意轮廓是如何在白色背景上显示为黑色形状的。这是因为当应用cv2.bitwise功能时,原始图像的白色区域将被mask中的黑色区域替换。
image = cv2.bitwise_and(image, image, mask=mask)
cv2.imshow("Mask", mask)
cv2.imshow("After", image)
cv2.waitKey(0)