Skip to content
MSD_11 edited this page Jan 4, 2021 · 13 revisions

Very often we scan documents like purchase invoice, class notes, books, office documents etc. Such documents mostly contain characters, alphabets, numbers, diagrams (printed or hand-written) and less often they contain pictures.

When a document's image is passed through a high pass filter; sentences, characters, numbers, diagrams printed on the sheet of paper pass through the filter whereas low frequency contents like shadow, color of the sheet of paper, etc are filtered out. Long story short, high pass filter allows features of the images that have well defined boundaries to pass through it.

Using high pass filter subsequently followed by white point selection & black point selection, outputs very soothing scanned images of documents and I have named this scanning technique as the GCMODE ("GC" in the name "GCMODE" has no technical significance). Firstly, I'll be talking about how to implement a high pass filter using OpenCV and then on how the GCMODE works.

High Pass Filter

High Pass Filter can be designed with help of low pass filter (LPF) functions (eg: average filter, Gaussian filter) of OpenCV. Subtracting output of a low pass filter from the input image itself, gives high pass filtered (HPF) image as the final output. Following representation makes the things clear,

HPF(img) = img - LPF(img)

Now, I'll be talking about how to actually implemented the HPF in Python as well as in Java. Implementation of HPF in both languages are based on the same fundamentals.

Python

Luckily I came across the perfect Stackoverflow question to help myself out with high pass filters for images. This question has pretty much everything that one needs to implement the HPF. I have used the code provided in Jason Mayo's answer to implement the HPF.

Using lower kernel size gives high pass filter with higher cutoff frequency i-e very small kernels like (3,3) will only allow very high frequency features like very sharp boundaries to pass through the high pass filter whereas a using a (101,101) kernel will allow almost the complete image to pass through.

Java

Luckily I came across the perfect Stackoverflow question to help myself out with high pass filters for images. This post has pretty much everything that one needs to implement the HPF.

In the link given above, Jason Mayo's answer shows us one of the ways to implement HPF on Python. I have implemented the exact same thing on Java and the only difference is OpenCV-Java is based on Mat whereas in Python it uses numpy

EXAMPLE of high pass filter :

The same Stackoverflow link has a perfect example of how the HPF's output will look like.

The GCMODE

GCMODE works in three steps,

  1. High Pass Filter
  2. White point selection
  3. Black point selection

Hence, to process an image in GCMODE, we need to execute the above operations one after other.

To scan in Java, we need to read the image and create an object of Scan class. This class' object takes image, kernelSize, black point & white point values as arguments in its constructor and contains all the methods, namely, highPassFilter, whitePointSelect, blackPointSelect and blackAndWhite. scanImage method of the class uses a switch-case block to call appropriate set of methods to implement desired mode, in this case it is the GCMODE.

Code snipet of the main method:

public static void main(String[] args) {

    System.loadLibrary(Core.NATIVE_LIBRARY_NAME);

    Mat image = Imgcodecs.imread("C:/Users/Sourabh Khemka/Desktop/RScan/ML/dataset/data_img_078.jpg");

    Scan scanner = new Scan(image, 51, 50, 160);
    Mat scannedImg = scanner.scanImage(Scan.ScanMode.GCMODE);
}

Second argument of the Scan class' constructor is kernelSize requried for high pass filter (see the code below)

Scan scanner = new Scan(image, 51, 50, 160);

Third argument is the black point value and the fourth argument is the white point value. White point value provided in the contructor has no significance in GCMODE as GCMODE uses a fixed value of 127 for white point.

Unlike the other two modes, in GCMODE white point selection is performed before black point selection and value for white point is 127 whereas black point value needs to be provided by user while creating Scan's object

EXAMPLE OF GCMODE :

Input image:

Output image:

Clone this wiki locally