身份证文字信息及人脸图片采集

结合openCV来做身份证上的人脸识别,并将识别到的人脸保存下来,再用Tesseract的java实现tess4j做身份证文字信息采集案例

注:身份证人脸截图能够实现,身份证文字信息采集识别率不高,需要自己训练中文识别器来提高识别率。如何训练不在这里讨论。

 

1.openCV相关包

下载地址:

https://download.csdn.net/download/l_sunrise/10965150

以idea为例配置openCV

1.1. 在VM options 中配置opencv_java320.dll文件的位置

 

身份证文字信息及人脸图片采集_第1张图片

1.2. 创建人脸识别器

注意路径问题 ,可直接根据lbpcascade_frontalface.xml文件所在磁盘位置绝对路径来创建,也可将此文件引入到工程资源文件夹下,根据其路径找到该文件创建人脸识别器

身份证文字信息及人脸图片采集_第2张图片

 

2.配置OCR

由于Tesseract默认支持的是英文和数字的检查,若想其支持中文检查,需要自己下载中文检测器并放入tessdata文件夹下,可将整个文件夹拷贝进工程资源文件夹下,然后指明tessdata文件夹位置和扫描时需要识别中文

身份证文字信息及人脸图片采集_第3张图片

 

OCR资料:

包含中文包,以tess4j的方式使用Tesseract做OCR,只需要其中的D:\tesseract\Tesseract-OCR\tessdata文件夹里的东西

下载地址:

https://download.csdn.net/download/l_sunrise/10988911

 

3.Maven依赖


    net.java.dev.jna
    jna
    4.1.0


    net.sourceforge.tess4j
    tess4j
    3.2.1
    
        
            com.sun.jna
            jna
        
    

4.代码实现:

package testTess4j;

import net.sourceforge.tess4j.ITesseract;
import net.sourceforge.tess4j.Tesseract;
import net.sourceforge.tess4j.TesseractException;
import net.sourceforge.tess4j.util.ImageHelper;
import org.opencv.core.*;
import org.opencv.objdetect.CascadeClassifier;
import util.ClassPathUtil;
import util.ImgChangeUtil;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

/**
 * @author LBW
 * @name 身份证信息采集及人脸图片采集
 * @date 2019/2/28 - 15:10
 */
public class Tess4jTest {

    static {
        //运行需要配置 VM options:-Djava.library.path=C:\\opencv\\build\\java\\x64(opencv_java320.dll的位置)
        //因为用到openCV,在调用之前,一定要加上这句话,目的是加载OpenCV API相关的DLL支持,没有它是不会正确运行的
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    }

    public static void main(String[] args) throws IOException {
        ITesseract instance = new Tesseract();

        //设置tessdata目录绝对路径
        instance.setDatapath(ClassPathUtil.getPath()+"tessdata");

        //如果需要识别英文之外的语种,需要指定识别语种,并且需要将对应的语言包放进项目中
        instance.setLanguage("chi_sim");

        // 指定需要识别的图片
        File imageFile = new File("F:\\imgs\\3225d9bc0bf5835aaacb5db0e1a3904.jpg");
        BufferedImage img= ImageIO.read(imageFile);

        /**************************************截取身份证人脸图 start***********************************/
        long startTime = System.currentTimeMillis();
        BufferedImage faceImg = img;
        //用来记录人脸坐标
        int[] rectPosition = new int[4];
        //从配置文件lbpcascade_frontalface.xml中创建一个人脸识别器
        //该文件在openCV包C:\opencv\sources\data\haarcascades\中
        CascadeClassifier faceDetector = new CascadeClassifier(ClassPathUtil.getPath()+"/haarcascades/haarcascade_frontalface_alt2.xml");
        //将BufferedImage转换为Mat对象
        Mat mat = ImgChangeUtil.BufImg2Mat(faceImg,BufferedImage.TYPE_3BYTE_BGR, CvType.CV_8UC3);
        //指定人脸识别的最大和最小像素范围
        Size minSize = new Size(500, 500);
        Size maxSize = new Size(1500, 1500);
        // 在图片中检测人脸,参数设置为scaleFactor=1.1f, minNeighbors=4, flags=0 以此来增加识别人脸的正确率
        MatOfRect faceDetections = new MatOfRect();
        faceDetector.detectMultiScale(mat, faceDetections,1.1f, 4, 0, minSize, maxSize);
        //人脸坐标
        Rect[] rects = faceDetections.toArray();
        //如果检测到人脸
        if (rects != null && rects.length >= 1) {
            System.out.println("识别到人脸,执行保存!");
            for (Rect rect : rects) {
                rectPosition[0]=rect.x-120;
                rectPosition[1]=rect.y-240;
                rectPosition[2]=rect.width+200;
                rectPosition[3]=rect.height+600;
            }
            //将Mat对象转换回BufferedImage对象
            faceImg = ImgChangeUtil.Mat2BufImg(mat,".jpg");
            //截取图片
            faceImg=ImageHelper.getSubImage(faceImg, rectPosition[0], rectPosition[1], rectPosition[2], rectPosition[3]);
            ImageIO.write(faceImg,"jpg",new File("F:\\imgs\\faceImg1.jpg"));
        }
        System.out.println("人脸图片检测并保存耗时:"+(System.currentTimeMillis()-startTime)+"ms");
        /**************************************截取身份证人脸图 end***********************************/


        /***************************************提高 OCR 效率 start**********************************/
        //int width=new Double(img.getWidth()*0.6).intValue();
        //int height=new Double(img.getHeight()*0.25).intValue();
        //如果需要识别的信息位置固定,可以截取图片,只识别那一部分,以提高识别效率
        //img=ImageHelper.getSubImage(img, width, height, 1100, 1200);
        //图片置灰
        img = ImageHelper.convertImageToGrayscale(img);
        //图片锐化
        img = ImageHelper.convertImageToBinary(img);
        //图片放大5倍,增强识别率
        //img = ImageHelper.getScaledInstance(img, img.getWidth() * 5, img.getHeight() * 5);
        /***************************************提高 OCR 效率 end***********************************/

        startTime = System.currentTimeMillis();
        String ocrResult = null;
        try {
            //执行OCR扫描识别文字
            ocrResult = instance.doOCR(img);
        } catch (TesseractException e) {
            System.out.println("识别失败!");
            e.printStackTrace();
        }

        // 输出识别结果
        System.out.println("OCR Result: \n" + ocrResult + "\n耗时:" + (System.currentTimeMillis() - startTime) + "ms");
    }
}

 

其中用到的工具类:

ClassPathUtil:

package util;//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//


import java.net.URLDecoder;

public class ClassPathUtil {
    public ClassPathUtil() {
    }

    public static String getPath() {
        String path = null;

        try {
            path = ClassPathUtil.class.getClassLoader().getResource("").getPath().toString();
            String systemName = System.getProperty("os.name");
            if (systemName.startsWith("Windows")) {
                path = URLDecoder.decode(path.substring(1), "utf-8");
            } else {
                path = URLDecoder.decode(path, "utf-8");
            }
        } catch (Exception var2) {
            var2.printStackTrace();
        }

        return path;
    }
}

ImgChangeUtil:

package util;

import org.opencv.core.Mat;
import org.opencv.core.MatOfByte;
import org.opencv.imgcodecs.Imgcodecs;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.io.ByteArrayInputStream;
import java.io.InputStream;

/**
 * @author 
 * @name openCV - Mat 对象与 BufferedImage 互转
 * @date 2019/3/1 - 11:10
 */
public class ImgChangeUtil {

    /**
     * Mat转换成BufferedImage
     *
     * @param matrix
     *            要转换的Mat
     * @param fileExtension
     *            格式为 ".jpg", ".png", etc
     * @return
     */
    public static BufferedImage Mat2BufImg (Mat matrix, String fileExtension) {
        // convert the matrix into a matrix of bytes appropriate for
        // this file extension
        MatOfByte mob = new MatOfByte();
        Imgcodecs.imencode(fileExtension, matrix, mob);
        // convert the "matrix of bytes" into a byte array
        byte[] byteArray = mob.toArray();
        BufferedImage bufImage = null;
        try {
            InputStream in = new ByteArrayInputStream(byteArray);
            bufImage = ImageIO.read(in);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bufImage;
    }

    /**
     * BufferedImage转换成Mat
     *
     * @param original
     *            要转换的BufferedImage
     * @param imgType
     *            bufferedImage的类型 如 BufferedImage.TYPE_3BYTE_BGR
     * @param matType
     *            转换成mat的type 如 CvType.CV_8UC3
     */
    public static Mat BufImg2Mat (BufferedImage original, int imgType, int matType) {
        if (original == null) {
            throw new IllegalArgumentException("original == null");
        }

        // Don't convert if it already has correct type
        if (original.getType() != imgType) {

            // Create a buffered image
            BufferedImage image = new BufferedImage(original.getWidth(), original.getHeight(), imgType);

            // Draw the image onto the new buffer
            Graphics2D g = image.createGraphics();
            try {
                g.setComposite(AlphaComposite.Src);
                g.drawImage(original, 0, 0, null);
            } finally {
                g.dispose();
            }
        }

        byte[] pixels = ((DataBufferByte) original.getRaster().getDataBuffer()).getData();
        Mat mat = Mat.eye(original.getHeight(), original.getWidth(), matType);
        mat.put(0, 0, pixels);
        return mat;
    }
}

 

 

 

 

你可能感兴趣的:(OCR,OCR,身份证人脸图片截取,身份证信息采集,Tesseract,Tess4j)