思路
- 二值化方法选择
指定阈值
自动阈值( OTSU 和 Triangle )
- 轮廓发现
轮廓提取
干扰区域过滤
- 粘连字符分割
解决字符粘连问题—粘连字符分割
程序代码
- 完善算法类: TextImageProcessor.java
package com.example.bankcardrec.ocr.algo;
import android.net.Uri;
import android.os.Environment;
import android.util.Log;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfPoint;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class TextImageProcessor {
private String TAG = "OCR-Algorithm";
public List<Mat> splitNumberBlock(Mat textImage) {
List<Mat> numberImgs = new ArrayList<>();
Mat gray = new Mat();
Mat binary = new Mat();
Imgproc.cvtColor(textImage, gray, Imgproc.COLOR_BGR2GRAY);
Imgproc.threshold(gray, binary, 0, 255, Imgproc.THRESH_BINARY | Imgproc.THRESH_OTSU);
List<MatOfPoint> contours = new ArrayList<>();
Mat hireachy = new Mat();
Mat contourBin = binary.clone();
Core.bitwise_not(contourBin, contourBin);
Imgproc.findContours(contourBin, contours, hireachy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE, new Point(0, 0));
int minh = binary.rows() / 3;
for(int i=0; i<contours.size(); i++) {
Rect roi = Imgproc.boundingRect(contours.get(i));
double area = Imgproc.contourArea(contours.get(i));
if(area < 100) {
Imgproc.drawContours(binary, contours, i, new Scalar(255), -1);
continue;
}
if(roi.height <= minh) {
Imgproc.drawContours(binary, contours, i, new Scalar(255), -1);
continue;
}
}
contours.clear();
binary.copyTo(contourBin);
Core.bitwise_not(contourBin, contourBin);
Imgproc.findContours(contourBin, contours, hireachy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE, new Point(0, 0));
Rect[] textBoxes = new Rect[contours.size()];
int index = 0;
int minWidth = 1000000;
Mat contoursImage = new Mat(contourBin.size(), CvType.CV_8UC1);
contoursImage