【发布时间】:2021-11-18 08:47:49
【问题描述】:
我尝试在 RGB 图像中检测葡萄串(通常具有圆形和椭圆形)中的葡萄浆果。 我的数据集的几个例子:
我不关心检测所有浆果,但我确实希望检测到的浆果尽可能准确。检测图像中大约 30%-40% 的浆果就足够了。
到目前为止,我设法达到了这个阶段,您可以更清楚地看到葡萄串和一些浆果的边界
我是通过以下步骤完成的:
- 将图像转换为灰度
- 高斯滤波器
- canny 算法,使用 THRESH_OTSU 方法
- cv2.connectedComponentsWithStats 减少点和细线
- 形态扩张使线条变粗
我正在寻找一种方法来将图像中的浆果检测为形状,以便以后从中提取指标,例如半径、面积、长度等。我想到了看起来与我非常相似的圆形和椭圆形,但是我当然愿意接受其他想法。
显然也欢迎使用与我使用的不同预处理阶段的解决方案!
我用来生成这个的代码:
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