【问题标题】:Detect circles and ellipses from binary image when the shapes are not closed当形状未闭合时从二进制图像中检测圆形和椭圆
【发布时间】:2021-11-18 08:47:49
【问题描述】:

我尝试在 RGB 图像中检测葡萄串(通常具有圆形和椭圆形)中的葡萄浆果。 我的数据集的几个例子:

我不关心检测所有浆果,但我确实希望检测到的浆果尽可能准确。检测图像中大约 30%-40% 的浆果就足够了。

到目前为止,我设法达到了这个阶段,您可以更清楚地看到葡萄串和一些浆果的边界

我是通过以下步骤完成的:

  1. 将图像转换为灰度
  2. 高斯滤波器
  3. canny 算法,使用 THRESH_OTSU 方法
  4. cv2.connectedComponentsWithStats 减少点和细线
  5. 形态扩张使线条变粗

我正在寻找一种方法来将图像中的浆果检测为形状,以便以后从中提取指标,例如半径、面积、长度等。我想到了看起来与我非常相似的圆形和椭圆形,但是我当然愿意接受其他想法。

显然也欢迎使用与我使用的不同预处理阶段的解决方案!

我用来生成这个的代码:

import cv2 as cv
import numpy as np


def connected_dots(binary_map):
    # do connected components processing
    nlabels, labels, stats, centroids = cv.connectedComponentsWithStats(binary_map, None, None, None, 8, cv.CV_32S)

    # get CC_STAT_AREA component as stats[label, COLUMN]
    areas = stats[1:, cv.CC_STAT_AREA]
    result = np.zeros((labels.shape), np.uint8)
    for i in range(0, nlabels - 1):
        if areas[i] >= 30:  # keep
            result[labels == i + 1] = 255
    result = cv.dilate(result, kernel=np.ones((2, 2), np.uint8), iterations=1)  # make the lines thicker
    return result


# load the masked image containing only the grape bunch
img_rgb = cv.imread("grape.jpg")
img_rgb = cv.cvtColor(img_rgb, cv.COLOR_BGR2RGB)
grayscale = cv.cvtColor(img_rgb, cv.COLOR_RGB2GRAY)  # convert to grayscale
threshValue = 140
_, binaryImage = cv.threshold(grayscale, threshValue, 255, cv.THRESH_TOZERO_INV)  # remove white areas

kernel_size = 3
gaussian_blurred = cv.GaussianBlur(binaryImage, (kernel_size, kernel_size), 0)
binaryImage = gaussian_blurred
th, bw = cv.threshold(binaryImage, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)  # calc threshold for canny
edges = cv.Canny(binaryImage, th / 2, th)
edges = connected_dots(edges)

编辑 1

@Abhi25t 建议的灰度图像直方图

编辑 2

按照@Micka 的建议使用 cv2.equalizeHist 函数后,我得到了看起来更好的结果(再次,我关心的是准确检测一些葡萄)。仍在寻找检测葡萄浆果的好方法(看起来像椭球体)

【问题讨论】:

  • 在你的位置上,我会看到更好的照片(也有更好的照明)。这些图片分辨率低、模糊、几乎没有对比度
  • 我希望我能做到!不幸的是,这是我必须使用的数据集。
  • 我认为 Hough circles 会找到不完整的圆。然而,这些物体实际上是椭球体。查看[this question],它有一个使用scikit库的解决方案
  • 将它们转换为灰度并扩展直方图以增加对比度。那么其他算法比如 otsu 会更好地工作
  • cv2.equalizeHist 函数

标签: python opencv image-processing object-detection edge-detection


【解决方案1】:

我会做的是

  1. 使用阈值检测黑色像素(例如,otsu,或者使用大多数图像是黑色的事实,因此黑色像素应该在中值颜色 +- 5% 左右,并且具有大致相同的 r、g 和 b值)
  2. 使用 canny-edge 检测边缘,并抑制靠近黑色部分的边缘
  3. 对结果应用椭圆霍夫变换,并在距离上有足够的阈值

注意:您可能想要简单地缩小图像的比例,而不是使用扩张来扩大边界,这也将加快计算速度。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-23
    • 2015-08-06
    • 1970-01-01
    • 2019-06-18
    • 2012-04-21
    • 2011-09-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多