折腾了一大圈,最后还是移植到java上了…………
插段代码留个底。
1 import net.sourceforge.tess4j.ITesseract; 2 import net.sourceforge.tess4j.Tesseract; 3 import org.opencv.core.*; 4 import org.opencv.imgproc.Imgproc; 5 6 import javax.imageio.ImageIO; 7 import java.awt.image.BufferedImage; 8 import java.io.ByteArrayInputStream; 9 import java.io.InputStream; 10 import java.util.ArrayList; 11 import java.util.HashMap; 12 import java.util.List; 13 import java.util.Map; 14 15 import static org.opencv.imgcodecs.Imgcodecs.imencode; 16 import static org.opencv.imgcodecs.Imgcodecs.imread; 17 import static org.opencv.imgcodecs.Imgcodecs.imwrite; 18 import static org.opencv.imgproc.Imgproc.*; 19 20 public class textDetection { 21 static { 22 System.loadLibrary(Core.NATIVE_LIBRARY_NAME); 23 } 24 25 public static ITesseract instance = new Tesseract(); 26 27 public static void main(String[] args) { 28 System.out.println("hello"); 29 30 //ocr初始化 31 instance.setDatapath("C:\\Program Files (x86)\\Tesseract-OCR\\tessdata"); 32 //此处的-psm 7为参数,指定了识别目标为单行从左到右的字母,增加该参数可以提高识别率。 33 //但是不知道java怎么加这个参数。 34 // List<String> config=new ArrayList<String>(); 35 // config.add("-psm 7"); 36 // instance.setConfigs(config); 37 38 //文字提取和识别 39 Mat img = imread("test2.jpg"); 40 List<Mat> pre = preprocess(img); 41 imwrite("test_1.jpg", pre.get(0)); 42 Map<Rect, String> region = dectection(pre.get(0), pre.get(1)); 43 57 } 58 59 // 图片预处理 60 //返回值中,0为二值化结果,1为腐蚀膨胀后的结果 61 public static List<Mat> preprocess(Mat img) { 62 List<Mat> re=new ArrayList<Mat>(); 63 Mat gray = new Mat(); 64 cvtColor(img, gray, COLOR_BGR2GRAY); 65 Mat th = new Mat(); 66 Imgproc.threshold(gray, th, 48, 255, THRESH_BINARY_INV); 67 re.add(th); 68 69 Mat element1=getStructuringElement(MORPH_RECT, new Size(10,10)); 70 Mat element2=getStructuringElement(MORPH_RECT, new Size(30,30)); 71 72 //腐蚀和膨胀 73 Mat erosion=new Mat(); 74 erode(th, erosion, element1); 75 Mat dilation=new Mat(); 76 dilate(erosion, dilation, element2); 77 Mat dilation2=new Mat(); 78 dilate(dilation, dilation2, element2); 79 Mat dilation3=new Mat(); 80 dilate(dilation2, dilation3, element2); 81 re.add(dilation3); 82 83 //中间图输出 84 // imwrite("binary.png", th); 85 // imwrite("dilation.png", dilation); 86 // imwrite("erosion.png", erosion); 87 // imwrite("dilation2.png", dilation2); 88 89 90 return re; 91 } 92 93 // 文字提取和识别 94 //参数img为二值化结果,用于文字识别。position为腐蚀膨胀结果,用于文字提取。 95 //返回值为矩形框和其对应的文字识别结果的map 96 public static Map<Rect, String> dectection(Mat img, Mat position) { 97 List<MatOfPoint> pointlist=new ArrayList<MatOfPoint>(); 98 Mat mat=new Mat(); 99 findContours(position, pointlist, mat, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE); 100 int i=1; 101 Map<Rect, String> re=new HashMap<Rect, String>(); 102 for (MatOfPoint point:pointlist) { 103 Rect rect = boundingRect(point); 104 System.out.println(i+" "+rect.x+" "+rect.y+" "+rect.width+" "+rect.height); 105 i++; 106 rectangle(img, new Point(rect.x, rect.y), new Point(rect.x+rect.width, rect.y+rect.height), new Scalar(255, 0, 0)); 107 Mat sub_mat=img.submat(rect.y, rect.y+rect.height, rect.x, rect.x+rect.width); 108 BufferedImage bimage=getImage(sub_mat); 109 try { 110 String answer = instance.doOCR(bimage); 111 //System.out.println(answer); 112 re.put(rect, answer); 113 } catch (Exception e) { 114 e.printStackTrace(); 115 } 116 } 117 //imwrite("test_2.jpg", img); 118 return re; 119 } 120 121 // mat转bufferedimage 122 public static BufferedImage getImage(Mat img) { 123 MatOfByte mob= new MatOfByte(); 124 imencode(".jpg", img, mob); 125 byte[] byteArray = mob.toArray(); 126 BufferedImage bufImage = null; 127 try { 128 InputStream in = new ByteArrayInputStream(byteArray); 129 bufImage = ImageIO.read(in); 130 } catch (Exception e) { 131 e.printStackTrace(); 132 } 133 return bufImage; 134 } 135 166 167 //两点距离 168 public static Double dis(Double[] a, Double[] b) { 169 return Math.sqrt(dis_s(a, b)); 170 } 171 172 //两点距离的平方 173 public static Double dis_s(Double[] a, Double[] b) { 174 return ((a[0]-b[0])*(a[0]-b[0])+(a[1]-b[1])*(a[1]-b[1])); 175 } 176 177 }