【问题标题】:get contours of circles within a rectangle获取矩形内圆的轮廓
【发布时间】:2019-01-26 00:03:54
【问题描述】:

假设我有一个灰度阈值图像,如下所示:

我需要圆圈的轮廓。我该怎么做呢? 我尝试了findContours 的多个选项:

  • RETR_EXTERNAL:这里只返回外矩形的轮廓

  • RETR_TREE:返回的轮廓太多(外圆和内圆的轮廓)

每个圆圈我只需要 1 个轮廓。我想在原始圆圈(绿色或红色)上绘制另一个颜色圆圈。我预先指定了有多少个圆(在本例中为 120 个),但因为它生成 120 * 2 = 240 个轮廓(每个圆 2 个轮廓),所以程序失败了。

那么,有没有办法只获取矩形内的圆的轮廓,并且每个圆只能得到 1 个轮廓?

【问题讨论】:

标签: python opencv


【解决方案1】:

假设输入图像命名为“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()

最终结果的预览可以在这里看到:

【讨论】:

    猜你喜欢
    • 2018-03-11
    • 2019-08-15
    • 1970-01-01
    • 2021-05-05
    • 2012-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多