How to filter only curved/incomplete circle line with contour detection?

I am working on a program that can detect a crescent moon/incomplete circle shape with contour detection. The problem is I don’t know the best method to filter only the crescent shape, the method I currently used is filter the contour using cv2.approxPolyDP() and the none-crescent shape still not all filtered, is there anyone here know how to filter only curved/crescent shape?

Here’s the code:

contours,hierarchy = cv2.findContours(img,cv2.RETR_EXTERNAL,1)
contour_crescent_line = []

for contour in contours:
    approx = cv2.approxPolyDP(contour,0.04*cv2.arcLength(contour,True),True))
    area = cv2.contourArea(contour)
    if ((len(approx) > 2) & (len(approx) < 40) & (area > 1000) & (area < 30000)):
        contour_crescent_line.append(contour)

test = img.copy()
to_rgb = cv2.cvtColor(test,cv2.COLOR_GRAY2RGB)

cv2.drawContours(to_rgb, contour_crescent_line,  -1, (0,255,0), 2)

This is example of the input:

I’m seeing jpeg artefacts. how did you threshold the input, did you at all?

if that mask image is all you have to work with, you may need hough transform for circles.

you should show unfiltered source data.

actually that example of input have gone through several processes, first is adaptive thresholding and second is binary area opening to reduce the noise, I still need a method to only detect the crescent shape with contour detection because after that the result will go through the circle hough transform, the hough transform algorithm can detect the crescent shape if I use low number in param2 argument. Because of that a lot of false circle get detected because the non-crescent shape didn’t filtered from contour detection method, here’s the raw img