tess-two 身份证识别


最近工作中遇到身份证上次需要验证问题,在网上搜索了大量信息,大概都是用tess-two库实现,但识别率不是很高,在它基础上,做了点优化,识别率比它高那么点


所做的优化方式就是,对图片进行二值化以及灰度化,然后再获取图片上的信息,至少能获取到身份证号码,其他中文字实在是无法匹配。


编程工具为:eclipse


首先需要做的步骤是:1、有下载tess-two库,当然,需要包括.so文件的,不然你还需要编译一遍,编译步骤需要在网上找,在上篇文章中写了编译过程中出现的问题,可以借鉴下, 现在提供下未做修改的代码下载地址:http://download.csdn.net/detail/a1031359915/9523864

2、将chi_sim.traineddata文件拷贝到/mnt/sdcard/tesseract/目录下。


下面是优化的代码:


import java.io.File;

import com.googlecode.tesseract.android.TessBaseAPI;
import com.googlecode.tesseract.android.test.R;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.TextView;

public class TestActivity extends Activity {
	private static final String TESSBASE_PATH = "/mnt/sdcard/tesseract/";  
    private static final String DEFAULT_LANGUAGE = "eng";  
    private static final String CHINESE_LANGUAGE = "chi_sim"; // chi_tra chi_sim
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.test);
		ImageView img = (ImageView) findViewById(R.id.img);
	       
	         
	              TessBaseAPI baseApi = new TessBaseAPI();  
	              baseApi.init(TESSBASE_PATH, CHINESE_LANGUAGE);  
//	       baseApi.setPageSegMode(TessBaseAPI.PageSegMode.PSM_AUTO);  
//	       File file = new File("/mnt/sdcard/sf.jpg");
//	       if (file.exists()){
//	    	   baseApi.setImage(file);  
//	       }
	         Bitmap bitmap = BitmapFactory.decodeFile("/mnt/sdcard/sf.jpg");
	         bitmap =  ImageFilter.gray2Binary(bitmap);// 图片二值化
	         bitmap =  ImageFilter.grayScaleImage(bitmap);// 图片灰度化
	         img.setImageBitmap(bitmap);
	         baseApi.setImage(bitmap);  
	       // Ensure that the result is correct.  
	       final String outputText = baseApi.getUTF8Text();  
	       TextView view = (TextView) findViewById(R.id.tv_test);
	       view.setText(outputText);
	       baseApi.end(); 
	}
}

图片处理类:

import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;
import android.util.Log;

public class ImageFilter {

	// 图像灰度化
	public static Bitmap bitmap2Gray(Bitmap bmSrc) {
		// 得到图片的长和宽
		int width = bmSrc.getWidth();
		int height = bmSrc.getHeight();
		// 创建目标灰度图像
		Bitmap bmpGray = null;
		bmpGray = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
		// 创建画布
		Canvas c = new Canvas(bmpGray);
		Paint paint = new Paint();
		ColorMatrix cm = new ColorMatrix();
		cm.setSaturation(0);
		ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
		paint.setColorFilter(f);
		c.drawBitmap(bmSrc, 0, 0, paint);
		return bmpGray;
	}
	
	// 图像灰度化
	public static Bitmap grayScaleImage(Bitmap src) {
        // constant factors
        final double GS_RED = 0.299;
        final double GS_GREEN = 0.587;
        final double GS_BLUE = 0.114;
		
//      final double GS_RED = 0.235;
//      final double GS_GREEN = 0.589;
//      final double GS_BLUE = 0.119;
        
        // create output bitmap
        Bitmap bmOut = Bitmap.createBitmap(src.getWidth(), src.getHeight(), src.getConfig());
        // pixel information
        int A, R, G, B;
        int pixel;
        
        // get image size
        int width = src.getWidth();
        int height = src.getHeight();
        
        // scan through every single pixel
        for(int x = 0; x < width; ++x) {
         for(int y = 0; y < height; ++y) {
          // get one pixel color
          pixel = src.getPixel(x, y);
          // retrieve color of all channels
          A = Color.alpha(pixel);
          R = Color.red(pixel);
          G = Color.green(pixel);
          B = Color.blue(pixel);
          // take conversion up to one single value
          R = G = B = (int)(GS_RED * R + GS_GREEN * G + GS_BLUE * B);
          // set new pixel color to output bitmap
          bmOut.setPixel(x, y, Color.argb(A, R, G, B));
         }
        }
        
        // return final image
        return bmOut;
       }

	// 对图像进行线性灰度变化
	public static Bitmap lineGrey(Bitmap image) {
		// 得到图像的宽度和长度
		int width = image.getWidth();
		int height = image.getHeight();
		// 创建线性拉升灰度图像
		Bitmap linegray = null;
		linegray = image.copy(Config.ARGB_8888, true);
		// 依次循环对图像的像素进行处理
		for (int i = 0; i < width; i++) {
			for (int j = 0; j < height; j++) {
				// 得到每点的像素值
				int col = image.getPixel(i, j);
				int alpha = col & 0xFF000000;
				int red = (col & 0x00FF0000) >> 16;
				int green = (col & 0x0000FF00) >> 8;
				int blue = (col & 0x000000FF);
				// 增加了图像的亮度
				red = (int) (1.1 * red + 30);
				green = (int) (1.1 * green + 30);
				blue = (int) (1.1 * blue + 30);
				// 对图像像素越界进行处理
				if (red >= 255) {
					red = 255;
				}

				if (green >= 255) {
					green = 255;
				}

				if (blue >= 255) {
					blue = 255;
				}
				// 新的ARGB
				int newColor = alpha | (red << 16) | (green << 8) | blue;
				// 设置新图像的RGB值
				linegray.setPixel(i, j, newColor);
			}
		}
		return linegray;
	}

	// 该函数实现对图像进行二值化处理
	public static Bitmap gray2Binary(Bitmap graymap) {
		// 得到图形的宽度和长度
		int width = graymap.getWidth();
		int height = graymap.getHeight();
		// 创建二值化图像
		Bitmap binarymap = null;
		binarymap = graymap.copy(Config.ARGB_8888, true);
		// 依次循环,对图像的像素进行处理
		for (int i = 0; i < width; i++) {
			for (int j = 0; j < height; j++) {
				// 得到当前像素的值
				int col = binarymap.getPixel(i, j);
				// 得到alpha通道的值
				int alpha = col & 0xFF000000;
				// 得到图像的像素RGB的值
				int red = (col & 0x00FF0000) >> 16;
				int green = (col & 0x0000FF00) >> 8;
				int blue = (col & 0x000000FF);
				// 用公式X = 0.3×R+0.59×G+0.11×B计算出X代替原来的RGB
				int gray = (int) ((float) red * 0.3 + (float) green * 0.59 + (float) blue * 0.11);
				// 对图像进行二值化处理
				if (gray <= 95) {
					gray = 0;
				} else {
					gray = 255;
				}
				// 新的ARGB
				int newColor = alpha | (gray << 16) | (gray << 8) | gray;
				// 设置新图像的当前像素值
				binarymap.setPixel(i, j, newColor);
			}
		}
		return binarymap;
	}

	/**
     * 将彩色图转换为黑白图
     * 
     * @param 位图
     * @return 返回转换好的位图
     */
    public static Bitmap convertToBlackWhite(Bitmap bmp) {
        int width = bmp.getWidth(); // 获取位图的宽
        int height = bmp.getHeight(); // 获取位图的高
        int[] pixels = new int[width * height]; // 通过位图的大小创建像素点数组
        bmp.getPixels(pixels, 0, width, 0, 0, width, height);
        int alpha = 0xFF << 24;
        for (int i = 0; i < height; i++) {
            for (int j = 0; j < width; j++) {
                int grey = pixels[width * i + j];
                int red = ((grey & 0x00FF0000) >> 16);
                int green = ((grey & 0x0000FF00) >> 8);
                int blue = (grey & 0x000000FF);
                grey = (int) (red * 0.3 + green * 0.59 + blue * 0.11);
                grey = alpha | (grey << 16) | (grey << 8) | grey;
                pixels[width * i + j] = grey;
            }
        }
        Bitmap newBmp = Bitmap.createBitmap(width, height, Config.ARGB_8888);
        newBmp.setPixels(pixels, 0, width, 0, 0, width, height);
        return newBmp;
    }
    
    /**
     * 图片锐化(拉普拉斯变换)
     * 
     * @param bmp
     * @return
     */
    public static Bitmap sharpenImageAmeliorate(Bitmap bmp) {
        // 拉普拉斯矩阵
        int[] laplacian = new int[] { -1, -1, -1, -1, 9, -1, -1, -1, -1 };
        int width = bmp.getWidth();
        int height = bmp.getHeight();
        Bitmap bitmap = Bitmap.createBitmap(width, height,
                Bitmap.Config.ARGB_8888);
        int pixR = 0;
        int pixG = 0;
        int pixB = 0;
        int pixColor = 0;
        int newR = 0;
        int newG = 0;
        int newB = 0;
        int idx = 0;
        float alpha = 0.3F;
        int[] pixels = new int[width * height];
        bmp.getPixels(pixels, 0, width, 0, 0, width, height);
        for (int i = 1, length = height - 1; i < length; i++) {
            for (int k = 1, len = width - 1; k < len; k++) {
                idx = 0;
                for (int m = -1; m <= 1; m++) {
                    for (int n = -1; n <= 1; n++) {
                        pixColor = pixels[(i + n) * width + k + m];
                        pixR = Color.red(pixColor);
                        pixG = Color.green(pixColor);
                        pixB = Color.blue(pixColor);
                        newR = newR + (int) (pixR * laplacian[idx] * alpha);
                        newG = newG + (int) (pixG * laplacian[idx] * alpha);
                        newB = newB + (int) (pixB * laplacian[idx] * alpha);
                        idx++;
                    }
                }
                newR = Math.min(255, Math.max(0, newR));
                newG = Math.min(255, Math.max(0, newG));
                newB = Math.min(255, Math.max(0, newB));
                pixels[i * width + k] = Color.argb(255, newR, newG, newB);
                newR = 0;
                newG = 0;
                newB = 0;
            }
        }
        bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
        return bitmap;
    }
}

xml文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    
    <TextView 
        android:id="@+id/tv_test"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#000000"
        android:text="sdfjahk"/>
    
    <ImageView 
        android:id="@+id/img"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@drawable/icon"/>

</LinearLayout>

至此,身份证号码应该能获取到,再声明下,识别率不是很好,希望能有大神能够完善下,谢谢!


  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值