折腾了一大圈,最后还是移植到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 // Listconfig=new ArrayList (); 35 // config.add("-psm 7"); 36 // instance.setConfigs(config); 37 38 //文字提取和识别 39 Mat img = imread("test2.jpg"); 40 List pre = preprocess(img); 41 imwrite("test_1.jpg", pre.get(0)); 42 Map region = dectection(pre.get(0), pre.get(1)); 43 57 } 58 59 // 图片预处理 60 //返回值中,0为二值化结果,1为腐蚀膨胀后的结果 61 public static List preprocess(Mat img) { 62 List re=new ArrayList (); 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 dectection(Mat img, Mat position) { 97 List pointlist=new ArrayList (); 98 Mat mat=new Mat(); 99 findContours(position, pointlist, mat, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);100 int i=1;101 Map re=new HashMap ();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转bufferedimage122 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 }