Search code examples
pythonopencvimage-processingmathematical-morphology

How to remove bell curved shape from image using opencv


I hope you are doing well. I want to remove the bell-curved shape in the image. I have used OpenCV. I have implemented the following code which detects the curve shape, Now How can remove that curve shape and save the new image in the folder.

Input Image 1

I want to remove the area shown in the image below

Area i want to remove

import cv2 
import numpy as np
    # load image as grayscale
cell1 = cv2.imread("/content/savedImage.jpg",0)
    # threshold image
ret,thresh_binary = cv2.threshold(cell1,107,255,cv2.THRESH_BINARY)
    # findcontours
contours, hierarchy = cv2.findContours(image =thresh_binary , mode = cv2.RETR_TREE,method = cv2.CHAIN_APPROX_SIMPLE)

    # create an empty mask
mask = np.zeros(cell1.shape[:2],dtype=np.uint8)

    # loop through the contours
for i,cnt in enumerate(contours):
            # if the contour has no other contours inside of it
    if hierarchy[0][i][2] == -1 :
                    # if the size of the contour is greater than a threshold
       if  cv2.contourArea(cnt) > 10000:
             cv2.drawContours(mask,[cnt], 0, (255), -1)   
fig, ax = plt.subplots(1,2)
ax[0].imshow(cell1,'gray');
ax[1].imshow(mask,'gray');

Ouput Image after the above Code

How can I process to remove that curve shape?


Solution

  • Here is one way to do that in Python/OpenCV.

    Get the external contours. Then find the one that has the largest w/h aspect ratio. Draw that contour filled on a black background as a mask. Dilate it a little. Then invert it and use it to blacken out that region.

    Input:

    enter image description here

    import cv2
    import numpy as np
    
    # read image
    img = cv2.imread('the_image.jpg')
    ht, wd = img.shape[:2]
    
    # convert to grayscale
    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    
    # threshold
    thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)[1]
    
    # get external contours
    contours = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    contours = contours[0] if len(contours) == 2 else contours[1]
    
    max_aspect=0
    for cntr in contours:
        x,y,w,h = cv2.boundingRect(cntr)
        aspect = w/h
        if aspect > max_aspect:
            max_aspect = aspect
            max_contour = cntr
    
    # create mask from max_contour
    mask = np.zeros((ht,wd), dtype=np.uint8)
    mask = cv2.drawContours(mask, [max_contour], 0, (255), -1)
    
    # dilate mask
    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3))
    mask = cv2.morphologyEx(mask, cv2.MORPH_DILATE, kernel)
    
    # invert mask
    mask = 255 - mask
    
    # mask out region in input
    result = img.copy()
    result = cv2.bitwise_and(result, result, mask=mask)
    
    # save resulting image
    cv2.imwrite('the_image_masked.png',result)
    
    # show thresh and result    
    cv2.imshow("mask", mask)
    cv2.imshow("result", result)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    Result:

    enter image description here