image-processingcomputer-visionedge-detection

Accurately detect the semicircular region in the given grayscale image


I've an almost semicircular object in a grayscale imageOriginal image for which I intend to create a mask. I've tried some preprocessing + edge detections + filtering. however, there are still some irregularities Erroneous mask.

Any suggestions on how to improve the mask?


Solution

  • If we assume that you have a half circle or (axis aligned) half ellipse, then one approach would be to make a copy of the image, flip it vertically and then vertically stack the two images. Then try HoughCircle (assuming it is close to a circle) in Python/OpenCV.

    Input:

    enter image description here

    import cv2
    import numpy as np
    
    # read the image as grayscale
    img = cv2.imread('disk_blob.png', cv2.IMREAD_GRAYSCALE)
    hh, ww = img.shape[:2]
    
    # remove 4 px bright border at top and left
    img2 = img[4:hh, 4:ww]
    
    # make copy, flip vertically and vstack
    img3 = img2.copy()
    img3 = np.flipud(img3)
    img3 = np.vstack((img2,img3))
    
    # apply hough circle
    circles = cv2.HoughCircles(img3, cv2.HOUGH_GRADIENT, 1, minDist=ww, param1=150, param2=10, minRadius=ww//4, maxRadius=ww//2)
    
    # draw circle on copy of img3 in red
    result = img3.copy()
    result = cv2.merge([result,result,result])
    
    for circle in circles[0]:
        # draw the circle in the output image, then draw a rectangle
        # corresponding to the center of the circle
        (x,y,r) = circle
        print("xcent:",x,"ycent:",y,"radius:",r)
        x = int(x)
        y = int(y)
        r = int(r)
        cv2.circle(result, (x, y), r, (0, 0, 255), 2)
    
    # save results
    cv2.imwrite('disk_blob_circle.png', result)
    
    # show results
    cv2.imshow('img3', img3)
    cv2.imshow('result', result)
    cv2.waitKey(0)
    

    Result:

    enter image description here

    Circle Information:

    xcent: 687.5 ycent: 848.5 radius: 491.9