pythonopencvimage-processingcomputer-vision

Remove a tiny repeated object from an image using OpenCV


I use OpenCV and Python and I want to remove the "+" sign that is repeated on my image.

The following is an example of an image in question.

Image With The "+" Signs

The goal is to produce the same image, but with the "+" signs removed.

How can I achieve this?

I've tried using the below code to achieve this.

img = cv2.imread(image_path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

img_inverted = cv2.bitwise_not(gray)

thresh = cv2.adaptiveThreshold(img_inverted, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 15, -2)

cross_structure = cv2.getStructuringElement(cv2.MORPH_CROSS, (3, 3))
detected_cross = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, cross_structure)

mask = detected_cross

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
dilated_mask = cv2.dilate(mask, kernel, iterations=1)

output_telea = cv2.inpaint(img, dilated_mask, 3, cv2.INPAINT_TELEA)

But it seems like the detected_cross isn't really detecting the expected objects, and as a result, it returns the same threshold image.

This is the result I end up with.

Actual Result


Solution

  • This is basically implementing the comment of fmw42; that is, create the mask by thresholding for white regions (also I increased your dilation to 2 iterations for a visually slightly better result):

    import cv2
    import numpy as np
    
    image_path = ...  # TODO: adjust as necessary
    
    img = cv2.imread(image_path)
    mask = (cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) > 250).astype(np.uint8)
    
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
    dilated_mask = cv2.dilate(mask, kernel, iterations=2)
    
    output_telea = cv2.inpaint(img, dilated_mask, 3, cv2.INPAINT_TELEA)
    cv2.imshow("result", output_telea)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    Result:

    inpainting result

    In general, I agree with Cris Luengo's comments though: