Search code examples
pythonopencvimage-processingocr

Remove unclear watermarks from a text document


Fellow OpenCV enthusiasts,

I'm facing a problem automating photographed documents reader and the document I'm trying to read has watermarks underneath the text, making OCR difficult. I have managed to adjust histograms and improve the overall quality of the image using Contrast Limited Adaptive Histogram Equalization (CLAHE) and some other matrix operations (code below). I need to figure out a way to further de-noise this type of images and improve OCR ability.

clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
gray_image = clahe.apply(gray_image)
height, width, channels = hsv_image.shape
histogram = cv2.calcHist([hsv_image], [2], None, [256], [0, 256])
brightness_value = sum([idx * value[0] for idx, value in enumerate(histogram)]) / (255 * height * width)
brightness = contrast = int(math.log(2 - brightness_value) * 100) + 30
gray_image = np.int16(gray_image)
gray_image = gray_image * (contrast / 127 + 1) - contrast + brightness
gray_image = np.clip(gray_image, 0, 255)
if sharpen:
    gray = np.uint8(gray_image)
    sharpening_kernel = np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]])
    gray = cv2.filter2D(gray, -1, sharpening_kernel)
    return gray
return np.uint8(gray_image)

Original Image enter image description here

Improved image enter image description here

Any suggestions/codes to improve this further is highly appreciated!


Solution

  • Here is one way to do that using Python/OpenCV by doing division normalization followed by thresholding.

    Input:

    enter image description here

    import cv2
    import numpy as np
    
    # read the image as grayscale
    img = cv2.imread('certificate.jpg', cv2.IMREAD_GRAYSCALE)
    
    # blur img
    blur = cv2.GaussianBlur(img, (0,0), sigmaX=99, sigmaY=99)
    
    # divide img by blur
    divide = cv2.divide(img, blur, scale=255)
    
    # threshold
    thresh = cv2.threshold(divide, 200, 255, cv2.THRESH_BINARY)[1]
    
    # save results
    cv2.imwrite('certificate_divide.jpg',divide)
    cv2.imwrite('certificate_thresh.jpg',thresh)
    
    # show results
    cv2.imshow("divide", divide)
    cv2.imshow("thresh", thresh)
    cv2.waitKey(0)
    

    Division Normalization:

    enter image description here

    Threshold

    enter image description here