Follow the ridges with OpenCV - return an array of "ridges"

I am looking for a method that finds ridges (local maxima) in an image and returns them as an array of ridges (where the ridge is a vector of points defining the ridge). That is, a method that behaves exactly the same as findContours (which finds contours and returns them as an array of vectors defining the contours), except for ridges.

Is this, and if not, how could I achieve this effect? (I use the Emgu CV shell for OpenCV)

I have this image (it's a little weak, sorry), obtained using distance conversion from a binary image of a road system:

Remote binary image conversion of a road system

I can easily use findContours on the source binary to get road outlines as point vectors. However, I am interested in the road center line . The center line of the road is represented by the local maxima of the image above.

Obviously, using findContours in this image again gives me the outline of the road. I planned to use non-maximum suppression to remove everything except the center line and use findContours, but I don't know how to do non-maxim suppression, so my question is here

+5
source share
1 answer

You want to do maximum suppression along the gradient direction of each line.

  • Calculate the direction of the gradient.
  • For each point, find the maximum value along the line in the direction of the local gradient. 2.1 If the current point is the maximum mark, as otherwise the sign is zero
import cv2 import numpy as np import math from matplotlib import pyplot as plt # Read image Irgb = cv2.imread('road.png') I = Irgb[:,:,0] # Find the gradient direction 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) for y in range(I.shape[0]): for x in range(I.shape[1]): gradDirection[y, x] = np.float64(math.atan2(sobely[y,x], sobelx[y,x])) # Iterate on all points and do max suppression points = np.nonzero(I) points = zip(points[0], points[1]) maxSuppresion = np.zeros_like(I) for point in points: y = point[0] x = point[1] # Look at local line along the point in the grad direction direction = gradDirection[y, x] pointValues = [] for l in range(-1,2): yLine = int(np.round(y + l * math.sin(direction))) xLine = int(np.round(x + l * math.cos(direction))) if(yLine < 0 or yLine >= maxSuppresion.shape[0] or xLine < 0 or xLine >= maxSuppresion.shape[1]): continue pointValues.append(I[yLine,xLine]) # Find maximum on line maxVal = np.max(np.asarray(pointValues)) # Check if the current point is the max val if I[y,x] == maxVal: maxSuppresion[y, x] = 1 else: maxSuppresion[y, x] = 0 # Remove small areas im2, contours, hierarchy = cv2.findContours(maxSuppresion,cv2.RETR_CCOMP,cv2.CHAIN_APPROX_NONE ) minArea = 5 maxSuppresionFilter = np.zeros_like(maxSuppresion) finalShapes = [] for contour in contours: if contour.size > minArea: finalShapes.append(contour) cv2.fillPoly(maxSuppresionFilter, finalShapes, 1) cv2.imshow('road',maxSuppresionFilter*255) 

At the end, the following image will appear: enter image description here

You can see that there are still problems, especially around intersections, where local maximum suppression suppresses points near the center of intersection. You can try to use morphological operations to overcome these problems.

0
source

Source: https://habr.com/ru/post/1246946/


All Articles