1. download the OpenCV jar file and add into classpath or import as maven, then static import the OpenCV c++ library as below:
static { System.loadLibrary(Core.NATIVE_LIBRARY_NAME); }
2. read the credit card image into the program into the Mat object
public static void main(String[] args) { Mat srcImage = loadImage("img/card.jpg"); } public static Mat loadImage(String path) { Mat newImage = Imgcodecs.imread(path); return newImage; }
3. turn the card image into grey color (grey scale process)
public static void main(String[] args) { Mat srcImage = loadImage("img/card.jpg"); Mat grey = grey(srcImage); } public static Mat grey(Mat srcMat) { Mat dest = new Mat (); Imgproc.cvtColor(srcMat, dest, Imgproc.COLOR_RGB2GRAY); return dest; }
4. turn the grey scale image into a black & white image. (binary process)
public static void main(String[] args) { Mat srcImage = loadImage("img/card.jpg"); Mat grey = grey(srcImage); Mat binary = blackWhite(grey); } public static Mat blackWhite(Mat grayMat) { Mat binaryMat = new Mat(grayMat.height(),grayMat.width(),CvType.CV_8UC1); Imgproc.threshold(grayMat, binaryMat, 30, 200, Imgproc.THRESH_BINARY); return binaryMat; }
5. Erode the black & white image to make the word bolder and clearer so as to be easy to be recognized.
public static void main(String[] args) { Mat srcImage = loadImage("img/card.jpg"); Mat grey = grey(srcImage); Mat binary = blackWhite(grey); Mat erode = imageErode(binary); } public static Mat imageErode(Mat srcMat) { Mat destMat = new Mat(); Mat element = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(3, 3)); Imgproc.erode(srcMat,destMat,element); return destMat; }
6. crop the key region to remove the noise.
public static void main(String[] args) { Mat srcImage = loadImage("img/card.jpg"); Mat grey = grey(srcImage); Mat binary = blackWhite(grey); Mat erode = imageErode(binary); Mat adjust = filterAndcut(erode); } public static Mat filterAndcut(Mat destMat) { int a =0, b=0, state = 0; for (int y = 0; y < destMat.height(); y++) //row { int count = 0; for (int x = 0; x < destMat.width(); x++) //column { // get the row pixel value byte[] data = new byte[1]; destMat.get(y, x, data); if (data[0] == 0) count = count + 1; } if (state == 0)//not a valid row { if (count >= 150)//find a valid row {//valid row qualify a 10 pixel noise a = y; state = 1; } } else if (state == 1) { if (count <= 150)// find a valid row {//valid row qualify a 10 pixel noise b = y; state = 2; } } } System.out.println("filter upper bound "+Integer.toString(a)); System.out.println("filter lower bound "+Integer.toString(b)); //crop the valid region Rect rect = new Rect(0,a,destMat.width(),b - a); Mat resMat = new Mat(destMat,rect); return resMat; }
7. recognize and print the result.
public static void main(String[] args) { Mat srcImage = loadImage("img/card.jpg"); Mat grey = grey(srcImage); Mat binary = blackWhite(grey); Mat erode = imageErode(binary); Mat adjust = filterAndcut(erode); printResult(matToBufferImage(adjust)); } public static BufferedImage matToBufferImage(Mat grayMat) { if (grayMat == null) { return null; } byte[] data1 = new byte[grayMat.rows() * grayMat.cols() * (int)(grayMat.elemSize())]; grayMat.get(0, 0, data1); BufferedImage image1 = new BufferedImage(grayMat.cols(), grayMat.rows(),BufferedImage.TYPE_BYTE_GRAY); image1.getRaster().setDataElements(0, 0, grayMat.cols(), grayMat.rows(), data1); return image1; }
public static void printResult(BufferedImage src) { ITesseract instance = new Tesseract(); instance.setDatapath("F:/Tess4J-3.4.8-src/Tess4J/tessdata"); // Credit card trained data long startTime = System.currentTimeMillis(); String ocrResult; try { ocrResult = instance.doOCR(src); System.out.println("OCR Result: \n" + ocrResult + "\n spend:" + (System.currentTimeMillis() - startTime) + "ms"); } catch (TesseractException e) { e.printStackTrace(); } }
That's all for this project.