I've an almost semicircular object in a grayscale image for which I intend to create a mask. I've tried some preprocessing + edge detections + filtering. however, there are still some irregularities .
Any suggestions on how to improve the mask?
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:
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:
Circle Information:
xcent: 687.5 ycent: 848.5 radius: 491.9