我正在尝试检测某些图像中的椭圆。 经过一些功能后,我得到了这个边缘图:
我尝试使用Hough变换来检测椭圆,但是这种变换具有很高的复杂性,因此我的计算机即使在5个小时后也没有完成运行transform命令(!)。
我也尝试做连接的组件并得到了:
在最后一种情况下,我还尝试了继续并将图像二值化。
在所有情况下,我都受困于这些步骤,并且不知道如何从这里继续。
我的任务是检测图像中的西红柿。我正在通过尝试检测圆和椭圆并找到每个圆的半径(或椭圆的平均半径)来解决这个问题。
编辑:
我为第一种方法添加了代码(结果是上面的边缘贴图):
img = cv2.imread(r'../images/assorted_tomatoes.jpg')
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
imgAfterLight=lightreduce(img)
imgAfterGamma=gamma_correctiom(imgAfterLight,0.8)
th2 = 255 - cv2.adaptiveThreshold(imgAfterGamma,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,5,3)
median2 = cv2.medianBlur(th2,3)
其中位数2是上面在边缘图中显示的结果
以及所连接组件的代码:
import scipy
from scipy import ndimage
import matplotlib.pyplot as plt
import cv2
import numpy as np
fname=r'../images/assorted_tomatoes.jpg'
blur_radius = 1.0
threshold = 50
img = scipy.misc.imread(fname) # gray-scale image
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
print(img.shape)
# smooth the image (to remove small objects)
imgf = ndimage.gaussian_filter(gray_img, blur_radius)
threshold = 80
# find connected components
labeled, nr_objects = ndimage.label(imgf > threshold)
其中标记的是上面的结果
另一个编辑:
这是输入图像:
问题在于边缘检测后,子区域中有很多不必要的边缘,这些边缘会干扰平滑的边缘图
答案 0 :(得分:0)
在我看来,这似乎是分水岭算法的经典问题。它设计用于分割触摸对象,例如西红柿。我的示例在Matlab中(我今天使用的计算机错误),但是它应该可以轻松地转换为python。首先像您一样转换为灰度,然后反转图像
I=rgb2gray(img)
I2=imcomplement(I)
图像原样会超出片段,因此我们删除了太浅的最小值。这可以通过h-minima变换完成
I3=imhmin(I2,50);
您可能需要使用50的值,这是抑制浅最小值的高度阈值。现在运行分水岭算法,我们得到以下结果。
L=watershed(I3);
结果并不完美。它需要附加的逻辑来删除一些小区域,但是会给出合理的估计。分水岭和h-minima包含在python的skimage.morphology包中。