当前位置:网站首页>Opencv: how to remove the seal on the bill

Opencv: how to remove the seal on the bill

2022-07-22 02:53:00 wzw12315

 

 

Recently, I encountered some problems in the coding of bill recognition , That is, there are often some red seals on the bill, covering some important information areas , For example, some invoicers stamp at will , Easy, some key areas are obscured , This makes the next bill identification difficult , therefore , We must first preprocess the bill image to remove the interference of the seal , Then carry out character recognition , In this way, the recognition accuracy can be guaranteed .

Let's start with a simple example , For example, we have the following note , It has a red seal on it , Although the seal does not block key information , But we're still going to remove it , So what do we do? ? The first thought is to remove the red pixels , This method needs to find the color range of red , Then traverse the pixels of the whole picture , Pixels in the range set it to white . This method is actually not very good to use , After all, this “ Red range ” It's still a difficult thing to set . Now let me talk about my method , Remove the red seal with a few lines of code .

Original picture

 

Graying

 

Two valued

To do bill recognition, we generally need to convert the bill into a binary image , We can see from the binary image above , There are still large seal marks on the bill , Our task now is , Remove it from the ticket !

In fact, the implementation method is very simple , The key is Separate the color channels + Threshold segmentation . Steps are as follows :

  1. Separate channels for color map , Get the red channel map
  2. Perform threshold segmentation

Let's take a look at it first split Function to separate the three channel image

the red channel

Green channel

Blue channel

 

From the images of the above channels , The image of each channel is slightly different , The difference lies in the sensitivity to different colors . Look at the picture of the red channel , We found that the red color in the original picture was basically missing ! So in summary , The closer the color in the original picture is to red, the closer the red channel is to white . In the place of pure red, pure white will appear in the red channel . green 、 The same goes for blue .

But look carefully, there are still some seal marks in the bill image , At this time, some seal marks can be removed by using threshold segmentation technology .

The above is the image after threshold segmentation , It can be seen that , The binary image has completely lost the trace of the seal , At this time, we can say that it is better to remove the interference of seals .

Code

#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"


using namespace cv;


int main()
{

    Mat src = imread("100.bmp");
    //resize(src, src, Size(700, 500));
    Mat gray;
    cvtColor(src, gray, CV_RGB2GRAY);
    if (src.empty())
    {
        printf("fail to open image!\n");
        return -1;
    }

    //  Global binarization 
    int th = 180; // The threshold should be adjusted according to the actual situation 
    Mat binary;
    threshold(gray, binary, th, 255, CV_THRESH_BINARY);


    vector<Mat> channels;
    split(src, channels);
    Mat red = channels[2];
    Mat blue = channels[0];
    Mat green = channels[1];

    Mat red_binary;
    threshold(red, red_binary, th, 255, CV_THRESH_BINARY);

    imshow("src", src);
    imshow("gray", gray);
    imshow("binary", binary);
    imshow("red channel", red);
    imshow("blue channel", blue);
    imshow("green channel", green);
    imshow("red+binary", red_binary);

    waitKey();


    return 0;
}

python edition

import cv2

image = cv2.imread("9.png",cv2.IMREAD_COLOR)
red_channel = image[:,:,2]
green_channel = image[:,:,1]
blue_channel = image[:,:,0]

# Or use cv2 Self contained function , But it takes a lot of time 
#channels = cv2.split(image)

gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
_,binary = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)

ret,red_binary = cv2.threshold(red_channel,160,255,cv2.THRESH_BINARY)

# Merge functions of various channels 
merge = cv2.merge([blue_channel,green_channel,red_channel])

cv2.imshow("red_binary",red_binary)
cv2.imshow("red_channel",red_channel)
cv2.imshow("binary",binary)
cv2.waitKey(0)

 

Let's have a few more invoices to see the effect

Before removal

After removing

Before removal

 

After removing

The following situation is classic , Because the seal just puts some key areas ( amount of money ) Covered , Now it is difficult for human eyes to distinguish its specific number , Can the machine recognize correctly ? If nothing is done , There is no way to recognize the machine , But after pretreatment , The machine can recognize its numbers accurately .

Before removal

After removing

Of course , This separation channel + The method of threshold segmentation can also be used in other occasions , For example, in the detection of traffic lights , This method can also be used for reference . I found a photo of a traffic light on the Internet to test , Let's see the effect ~

Detect the red light

 

Detect green light

 

 

原网站

版权声明
本文为[wzw12315]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/203/202207211003556961.html