Background image cleaning for OCR

后端 未结 1 372
礼貌的吻别
礼貌的吻别 2020-12-18 13:12

Through tesseract-OCR I am trying to extract text from the following images with a red background.

I have problems extracting the text in boxes B and D beca

相关标签:
1条回答
  • 2020-12-18 14:00

    Here are two methods to clean the image using Python OpenCV

    Method #1: Numpy thresholding

    Since the vertical lines, horizontal lines, and the background are in red we can take advantage of this and use Numpy thresholding to change all red pixels above a threshold to white.

    import cv2
    import numpy as np
    
    image = cv2.imread('1.jpg')
    
    image[np.where((image > [0,0,105]).all(axis=2))] = [255,255,255]
    
    cv2.imshow('image', image)
    cv2.waitKey()
    

    Method #2: Traditional image processing

    For a more general approach if the lines were not red we can use simple image processing techniques to clean the image. To remove the vertical and horizontal lines we can construct special kernels to isolate the lines and remove them using masking and bitwise operations. Once the lines are removed, we can use thresholding, morphological operations, and contour filtering to remove the red background. Here's a visualization of the process


    First we construct vertical and horizontal kernels then cv2.morphologyEx() to detect the lines. From here we have individual masks of the horizontal and vertical lines then bitwise-or the two masks to obtain a mask with all lines to remove. Next we bitwise-or with the original image to remove all lines

    Now that the lines are removed, we can work on removing the red background. We threshold to obtain a binary image and perform morphological operations to smooth the text

    There are still little dots so to remove them, we find contours and filter using a minimum threshold area to remove the small noise

    Finally we invert the image to get our result

    import cv2
    
    image = cv2.imread('1.jpg')
    
    # Remove vertical and horizontal lines
    kernel_vertical = cv2.getStructuringElement(cv2.MORPH_RECT, (1,50))
    temp1 = 255 - cv2.morphologyEx(image, cv2.MORPH_CLOSE, kernel_vertical)
    horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (50,1))
    temp2 = 255 - cv2.morphologyEx(image, cv2.MORPH_CLOSE, horizontal_kernel)
    temp3 = cv2.add(temp1, temp2)
    removed = cv2.add(temp3, image)
    
    # Threshold and perform morphological operations
    gray = cv2.cvtColor(removed, cv2.COLOR_BGR2GRAY)
    thresh = cv2.threshold(gray, 180, 255, cv2.THRESH_BINARY_INV)[1]
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (2,2))
    close = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel, iterations=1)
    
    # Filter using contour area and remove small noise
    cnts = cv2.findContours(close, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    cnts = cnts[0] if len(cnts) == 2 else cnts[1]
    for c in cnts:
        area = cv2.contourArea(c)
        if area < 10:
            cv2.drawContours(close, [c], -1, (0,0,0), -1)
    
    final = 255 - close 
    cv2.imshow('removed', removed)
    cv2.imshow('thresh', thresh)
    cv2.imshow('close', close)
    cv2.imshow('final', final)
    cv2.waitKey()
    
    0 讨论(0)
提交回复
热议问题