Tesseract做图片验证码识别

2017-12-28  本文已影响0人  Joshua1919

linux下的安装参考这里

转载请标明出处:https://www.jianshu.com/p/c9cd23ea84fa

环境准备

yum -y update
yum -y install libstdc++ autoconf automake libtool autoconf-archive pkg-config gcc gcc-c++ make libjpeg-devel libpng-devel libtiff-devel zlib-devel

安装leptonica这里下载

tar -zvxf leptonica-1.74.4.tar.gz
cd leptonica-1.74.4
./autobuild
./configure
make
make install

安装tesseract这里下载

unzip tesseract-master.zip
cd tesseract-master
(1)./autogen.sh
(2)PKG_CONFIG_PATH=/usr/local/lib/pkgconfig LIBLEPT_HEADERSDIR=/usr/local/include ./configure –with-extra-includes=/usr/local/include –with-extra-libraries=/usr/local/lib
(3)LDFLAGS=”-L/usr/local/lib” CFLAGS=”-I/usr/local/include” make
(4)make install

下载数据这里下载

cd /usr/local/share/
上传eng.traineddata

到此就安装完成了。

Windows下的安装

windows上的安装就不介绍了,注意安装好了以后要添加环境变量:

(1)path中添加:D:\Program Files (x86)\Tesseract-OCR\tessdata
(2)新建TESSDATA_PREFIX:D:\Program Files (x86)\Tesseract-OCR\tessdata

使用

tesseract image1.jpg out –psm 7 -l eng

image1.jpg:是输入文件名
out:识别出来的文字存放在out.txt这个文件中
-l:代表文字的类型,eng就是英文。
–psm:代表不同的切割方式

为了提高识别率可以做灰度化二值化等处理.

JAVA代码如下

public class OCRUtil {
    private static final String EOL = System.getProperty("line.separator");
    public static String recognizeText(byte[] image) throws Exception {
        //图片预处理,灰度化+二值化
        image = preHandleImage(image);
        //把字节数组保存到临时目录
        String tempDir=System.getProperty("java.io.tmpdir");
        String uuid = UUIDUtil.uuid();
        String tempFileName = uuid +".jpg";
        String resultFileName = uuid;
        File tempFile = new File(tempDir, tempFileName);
        File resultFile = new File(tempDir, resultFileName);
        IOUtil.saveInputStream(new ByteArrayInputStream(image), new FileOutputStream(tempFile));
        //生成操作系统命令
        List<String> cmd = new ArrayList<String>();
        if(OSUtil.isUnixLikeSystem()) {
            cmd.add("tesseract");
        }else {
            cmd.add("cmd");
            cmd.add("/c");
            cmd.add("tesseract.exe");
        }
        cmd.add(tempFile.getAbsolutePath());
        cmd.add(resultFile.getAbsolutePath());
        cmd.add("-l");
        cmd.add("eng");
        cmd.add("--psm");
        cmd.add("7");
        FileInputStream fin = null;
        BufferedReader in = null;
        try {
            //调用操作系統命令
            StringBuffer sb = new StringBuffer();
            ProcessBuilder pb = new ProcessBuilder();
            pb.directory(new File(tempDir));
            pb.command(cmd);
            pb.redirectErrorStream(true);
            Process process = pb.start();
            int w = process.waitFor();
            if (w == 0){// 0代表正常退出
                fin = new FileInputStream(resultFile.getAbsolutePath() + ".txt");
                in = new BufferedReader(new InputStreamReader(fin, "UTF-8"));
                String str = null;
                while ((str = in.readLine()) != null) {
                    sb.append(str).append(EOL);
                }
                return sb.toString().replaceAll("(?is)\\s+", "");
            } else {
                String msg;
                switch (w) {
                case 1:
                    msg = "Errors accessing files. There may be spaces in your image's filename.";
                    break;
                case 29:
                    msg = "Cannot recognize the image or its selected region.";
                    break;
                case 31:
                    msg = "Unsupported image format.";
                    break;
                default:
                    msg = "Errors occurred.";
                }
                throw new RuntimeException(msg);
            }
        }finally {
            IOUtil.close(in,fin);
            if(tempFile != null) {
                tempFile.delete();
            }
            if(resultFile != null) {
                resultFile.delete();
                File file = new File(resultFile.getAbsolutePath()+".txt");
                if(file!=null && file.exists()) {
                    file.delete();
                }
            }
        }
    }
    public static byte[] preHandleImage(byte[] imgBytes) throws IOException {
        if(imgBytes == null) {
            return null;
        }
        BufferedImage bufferedImage = ImageIO.read(new ByteArrayInputStream(imgBytes));
        int h = bufferedImage.getHeight();
        int w = bufferedImage.getWidth();
        // 灰度化
        int[][] gray = new int[w][h];
        for (int x = 0; x < w; x++) {
            for (int y = 0; y < h; y++) {
                int argb = bufferedImage.getRGB(x, y);
                // 图像加亮(调整亮度识别率非常高)
                int r = (int) (((argb >> 16) & 0xFF) * 1.1 + 30);
                int g = (int) (((argb >> 8) & 0xFF) * 1.1 + 30);
                int b = (int) (((argb >> 0) & 0xFF) * 1.1 + 30);
                if (r >= 255) {
                    r = 255;
                }
                if (g >= 255) {
                    g = 255;
                }
                if (b >= 255) {
                    b = 255;
                }
                gray[x][y] = (int) Math.pow(
                        (Math.pow(r, 2.2) * 0.2973 + Math.pow(g, 2.2) * 0.6274 + Math.pow(b, 2.2) * 0.0753), 1 / 2.2);
            }
        }
        // 二值化
        int threshold = ostu(gray, w, h);
        BufferedImage binaryBufferedImage = new BufferedImage(w, h, BufferedImage.TYPE_BYTE_BINARY);
        for (int x = 0; x < w; x++) {
            for (int y = 0; y < h; y++) {
                if (gray[x][y] > threshold) {
                    gray[x][y] |= 0x00FFFF;
                } else {
                    gray[x][y] &= 0xFF0000;
                }
                binaryBufferedImage.setRGB(x, y, gray[x][y]);
            }
        }
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ImageIO.write(binaryBufferedImage, "jpg", out);
        out.close();
        return out.toByteArray();
    }
    private static int ostu(int[][] gray, int w, int h) {
        int[] histData = new int[w * h];
        // Calculate histogram
        for (int x = 0; x < w; x++) {
            for (int y = 0; y < h; y++) {
                int red = 0xFF & gray[x][y];
                histData[red]++;
            }
        }
        // Total number of pixels
        int total = w * h;
        float sum = 0;
        for (int t = 0; t < 256; t++)sum += t * histData[t];
        float sumB = 0;
        int wB = 0;
        int wF = 0;
        float varMax = 0;
        int threshold = 0;
        for (int t = 0; t < 256; t++) {
            wB += histData[t]; // Weight Background
            if (wB == 0)    continue;
            wF = total - wB; // Weight Foreground
            if (wF == 0)    break;
            sumB += (float) (t * histData[t]);
            float mB = sumB / wB; // Mean Background
            float mF = (sum - sumB) / wF; // Mean Foreground
            // Calculate Between Class Variance
            float varBetween = (float) wB * (float) wF * (mB - mF) * (mB - mF);
            // Check if new maximum found
            if (varBetween > varMax) {
                varMax = varBetween;
                threshold = t;
            }
        }
        return threshold;
    }
}
上一篇下一篇

猜你喜欢

热点阅读