我正在寻找一种方法,在图像中找到脊(局部最大值)并将它们作为脊的阵列返回(其中脊是定义脊的点的矢量) . 也就是说,一种方法,其行为与findContours完全相同(查找轮廓并将其作为定义轮廓的矢量数组返回),除了脊 .
这是否存在,如果不存在,我将如何实现这种效果? (我正在使用OpenCV的Emgu CV包装器)
我有这个图像(它有点模糊,对不起),使用道路系统的二进制图像的距离变换获得:
我可以很容易地在原始二进制图像上使用findContours来获得 road outlines 作为点的向量 . 但是我对 road centerline 很感兴趣 . 道路中心线由上面的图像的局部最大值表示 .
显然,在这张图片上使用findContours再次为我提供了道路轮廓 . 我打算使用非最大值抑制除去中心线以外的所有内容,并使用findContours,但我不知道如何进行非最大值抑制,因此我的问题here
1 回答
您希望沿每条线的渐变方向进行最大抑制 .
计算梯度方向 .
对于每个点,沿着局部渐变方向的线搜索最大值 . 2.1如果当前点是最大标记,则标记为零
#读取图像
Irgb = cv2.imread('road.png')
I = Irgb [:,:,0]
#找到渐变方向
sobelx = cv2.Sobel(I,cv2.CV_64F,1,0,ksize = 1)
sobely = cv2.Sobel(I,cv2.CV_64F,0,1,ksize = 1)
gradDirection = np.zeros(I.shape,np.float64)
对于范围内的y(I.shape [0]):
对于范围内的x(I.shape [1]):
gradDirection [y,x] = np.float64(math.atan2(sobely [y,x],sobelx [y,x]))
#迭代所有点并进行最大抑制
points = np.nonzero(I)
points = zip(points [0],points [1])
maxSuppresion = np.zeros_like(I)
点数:
y =点[0]
x =点[1]
#查看渐变方向上的点的局部线
direction = gradDirection [y,x]
pointValues = []
对于l in范围(-1,2):
yLine = int(np.round(y l * math.sin(direction)))
xLine = int(np.round(x l * math.cos(direction)))
if(yLine <0或yLine> = maxSuppresion.shape [0]或xLine <0或xLine> = maxSuppresion.shape [1]):
继续
pointValues.append(I [YLINE,XLINE])
#在线查找最大值
maxVal = np.max(np.asarray(pointValues))
#检查当前点是否为最大值
如果我[y,x] == maxVal:
maxSuppresion [y,x] = 1
其他:
maxSuppresion [y,x] = 0
#删除小区域
im2,contours,hierarchy = cv2.findContours(maxSuppresion,cv2.RETR_CCOMP,cv2.CHAIN_APPROX_NONE)
minArea = 5
maxSuppresionFilter = np.zeros_like(maxSuppresion)
finalShapes = []
轮廓轮廓:
if contour.size> minArea:
finalShapes.append(轮廓)
cv2.fillPoly(maxSuppresionFilter,finalShapes,1)
cv2.imshow( '路',maxSuppresionFilter * 255)
最后会得到以下图片:
您可以看到,在交叉点周围仍然存在问题,其中局部最大抑制抑制了交叉点中心旁边的点 . 您可以尝试使用形态学操作来克服这些问题 .