假设输入图像命名为“circles.jpg”。
首先,导入所需的库并加载灰度图像。使用 Numpy.where() 函数来净化图像的前景和背景。然后找到这张图片上的所有轮廓:
import cv2
import numpy as np
image_gray = cv2.imread("circles.jpg", 0)
image_gray = np.where(image_gray > 30, 255, image_gray)
image_gray = np.where(image_gray <= 30, 0, image_gray)
image_gray = cv2.adaptiveThreshold(image_gray, 255,
cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY, 115, 1)
_, contours, _ = cv2.findContours(image_gray, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
其次,创建一个具有相同宽度和高度的空图像。然后,在新创建的图像上绘制轮廓,带有过滤条件 - 轮廓必须是圆形:
image_copy = np.zeros_like(image_gray) # create a new emtpy image
for cnt in contours:
peri = cv2.arcLength(cnt, True)
approx = cv2.approxPolyDP(cnt, 0.04 * peri, True)
(x, y, w, h) = cv2.boundingRect(cnt)
ar = w / float(h)
if len(approx) > 5 and 0.9 < ar < 1.1: # filtering condition
cv2.drawContours(image_copy, [cnt], 0, 255, -1)
第三,您需要将每个轮廓的面积存储到一个列表中,并删除任何太小的轮廓:
cnt_areas = []
cnt_circles = []
for cnt in contours:
(x, y, w, h) = cv2.boundingRect(cnt)
cnt_areas.append(w*h)
cnt_circles.append(cnt)
import statistics
median_size_limit = statistics.median(cnt_areas) * 0.3
cnt_circles = [cnt for i, cnt in enumerate(cnt_circles)
if cnt_areas[i] > median_size_limit]
最后,显示并检查结果:
# Draw the result and display
image = cv2.cvtColor(image_gray, cv2.COLOR_GRAY2RGB)
cv2.drawContours(image, cnt_circles, -1, (0, 0,255), 2)
cv2.imshow("Result Preview", image)
cv2.waitKey()
最终结果的预览可以在这里看到: