5

I have images similar to the one below. First of all, I am trying to detect the curves in these images. The curves I want to capture are marked on the image. Next, I want to fit these curves into the circle. I will use the radii of these circles as result. But I have problem with detecting curves in images. Any help much appreciated. Thanks in advance.

Input Image

Expected

Cropped Image ExpectedCropped

Here's the code I'm using to detect and draw the curves:

import cv2
import numpy as np
from skimage.feature import peak_local_max
from skimage.morphology import watershed
from scipy import ndimage

image = cv2.imread("croppedImage.png")

img = cv2.medianBlur(image,13)

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

thresh = cv2.adaptiveThreshold(gray,255,cv2.ADAPTIVE_THRESH_MEAN_C,\
            cv2.THRESH_BINARY,45,0)

kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,3))
kernel1 = np.ones((3, 3), np.uint8)
kernel2 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3))
dilate = cv2.dilate(thresh, kernel1, iterations=1)
erode = cv2.erode(dilate, kernel,iterations=1)

# Remove small noise by filtering using contour area
cnts = cv2.findContours(erode, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]

for c in cnts:
    if cv2.contourArea(c) < 800:
        if len(c)>0:
            cv2.drawContours(thresh,[c], 0, (0,0,0), -1)
        
# Compute Euclidean distance from every binary pixel
# to the nearest zero pixel then find peaks
distance_map = ndimage.distance_transform_edt(erode)
local_max = peak_local_max(distance_map, indices=False, min_distance=1, labels=thresh)

# Perform connected component analysis then apply Watershed
markers = ndimage.label(local_max, structure=np.ones((3, 3)))[0]
labels = watershed(-distance_map, markers, mask=erode)

# Iterate through unique labels
for label in np.unique(labels):
    if label == 0:
        continue

    # Create a mask
    mask = np.zeros(thresh.shape, dtype="uint8")
    mask[labels == label] = 255

    # Find contours and determine contour area
    cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    cnts = cnts[0] if len(cnts) == 2 else cnts[1]
    c = max(cnts, key=cv2.contourArea)
    
    cv2.drawContours(image, [c], -1, (36,255,12), -1)

        

cv2.imwrite('Results/drawedImage.png',image)

thresh = 155
im_bw = cv2.threshold(image, thresh, 255, cv2.THRESH_BINARY)[1]

cv2.imwrite("Results/binary.png",im_bw)

Result Image

Binary Result

From the images like below, I can fit circles. But I don't have clean images like this one.

gray_blurred = cv2.GaussianBlur(img,(11,11),0)

ret3,thresh= cv2.threshold(gray_blurred,100,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)

# Apply Hough transform on the blurred image. 
detected_circles = cv2.HoughCircles(thresh,  
                   cv2.HOUGH_GRADIENT, 1, 80, param1 = 20, 
               param2 = 9, minRadius = 120, maxRadius = 200) 

  
# Draw circles that are detected. 
if detected_circles is not None: 
  
    # Convert the circle parameters a, b and r to integers. 
    detected_circles = np.uint16(np.around(detected_circles)) 

    for pt in detected_circles[0, :]: 
        a, b, r = pt[0], pt[1], pt[2] 
        
        # Draw the circumference of the circle. 
        cv2.circle(img, (a, b), r, (0, 255, 0), 2) 
  
        # Draw a small circle (of radius 1) to show the center. 
        cv2.circle(img, (a, b), 1, (0, 0, 255), 3) 
 
else:
    print("Circle is not found")

Binary Curved Lines

Detected Circles

denizekiz
  • 51
  • 1
  • 3

0 Answers0