I'm doing work where the output is a faint large circle.
I can see the circle is there, and I know from the experiment that it is a uniform solid circle. But I am having issues recognising it with python. I tried using Hough Transforms, because the edges aren't sharp I get multiple circles. I followed the tutorial below I tried using Canny Edge detection, but I get a very noisy result no matter what value of sigma I use
I have also tried dilating the image
https://docs.opencv.org/4.5.2/da/d53/tutorial_py_houghcircles.html
https://learnopencv.com/filling-holes-in-an-image-using-opencv-python-c/
The "hack" that I am currently doing is to just freehand select the circle, but would love to be able to automate the process. The image is below and if anyone could point me in the right direction it would be greatly appreciated!
Adaptive thresholding and findContours
seems to help somewhat. The arguments to the blur and threshold functions will need tweaking for your data, I'm pretty sure...
import cv2 as cv
from matplotlib import pyplot as plt
orig_img = cv.imread("image.png", cv.IMREAD_COLOR)
img = cv.cvtColor(orig_img, cv.COLOR_BGR2GRAY)
img = cv.normalize(img, None, 0, 255, norm_type=cv.NORM_MINMAX)
img = cv.medianBlur(img, 11)
img = cv.adaptiveThreshold(img, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY, 45, 1)
img = 255 - img
contours, hierarchy = cv.findContours(img, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
largest_contour = max(contours, key=cv.contourArea)
cv.drawContours(orig_img, [largest_contour], -1, (0, 255, 0), 2)
x, y, w, h = cv.boundingRect(largest_contour)
midx = int(x + w / 2)
midy = int(y + h / 2)
cv.circle(orig_img, (int(midx), int(midy)), max(w, h) // 2, (255, 0, 0), 2)
plt.subplot(2, 1, 1)
plt.imshow(img, cmap="gray")
plt.colorbar()
plt.subplot(2, 1, 2)
plt.imshow(orig_img)
plt.show()