前些天下午沒什麼事,朋友有個需求,說要識別身份證上面的身份證號碼,恰好閒着,就幫他解決了一下,不說多完美,可是至少算是解決需求了,好了,閒話少說。html
先來看一下個人DEMO吧java
接下來咱們一個個介紹vim
也是從別人的Demo裏截出來的,其實也是用的別人的一個在線接口,可是我看了看應該算「非正常調用」(這個意思你們本身理解吧)。下面分析一下這個方法的優劣點吧。數組
優勢:速度極快,上傳照片,會返回身份證上全部信息,包括姓名 地址 出生等等網絡
缺點:「非正常」調用就有必定的不可靠性,若是哪天人家關了或者改了這個接口,就比較尷尬了,固然你能夠選擇購買人家的正式版。ide
基於Tess_two作的識別,這個你們可放心使用。先看一下大概怎麼使用吧!url
首先引用:spa
1
|
compile
'com.rmtheis:tess-two:6.0.0'
|
而後使用,其實使用起來很簡單,可是要注意幾點3d
1.要在SD卡有他的識別庫,這個庫你能夠理解爲一個字典,這個字典能夠本身訓練,由於我是用的別人訓練好的(只包含英文和數字),因此就不說怎麼訓練了,百度一下會有不少。code
2.須要注意的是,放他字典的路徑文件夾名必須爲「tessdata」,不然報錯
好了,準備工做作好了,接下來介紹怎麼使用,我直接貼核心代碼,代碼有註釋,看不懂的留言或者私信我
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
//訓練數據路徑,tessdata
static
final
String TESSBASE_PATH = Environment.getExternalStorageDirectory() +
"/"
;
//識別語言英文
static
final
String DEFAULT_LANGUAGE =
"eng"
;
/**
* 傳SD卡圖片路徑(固然大家也能夠傳Bitmap)
* @param url
*/
private
void
localre(String url) {
//把圖片轉爲Bitmap
Bitmap bmp = BitmapFactory.decodeFile(url);
//建立Tess
final
TessBaseAPI baseApi =
new
TessBaseAPI();
//下面這一塊代碼爲裁取身份證號碼區域(不然識別亂碼,不許確)
int
x, y, w, h;
x = (
int
) (bmp.getWidth() *
0.340
);
y = (
int
) (bmp.getHeight() *
0.800
);
w = (
int
) (bmp.getWidth() *
0.6
+
0
.5f);
h = (
int
) (bmp.getHeight() *
0.12
+
0
.5f);
Bitmap bit_hm = Bitmap.createBitmap(bmp, x, y, w, h);
//這個只是我將裁取的號碼區展現在了一個ImageView上,這個能夠沒有
iv_number.setImageBitmap(bit_hm);
//初始化OCR的訓練數據路徑與語言
baseApi.init(TESSBASE_PATH, DEFAULT_LANGUAGE);
//設置識別模式
baseApi.setPageSegMode(TessBaseAPI.PageSegMode.PSM_SINGLE_LINE);
//設置要識別的圖片
baseApi.setImage(bit_hm);
//設置字典白名單
baseApi.setVariable(
"tessedit_char_whitelist"
,
"0123456789Xx"
);
//把識別內容設置到EditText裏
tv_result.setText(baseApi.getUTF8Text());
//收尾
baseApi.clear();
baseApi.end();
}
|
OK,就這麼簡單,圖片清晰切裁取區域正確的狀況下,準確度幾乎100%;
給你們舉個身份證照片的例子吧,不然裁取號碼會不
上一張結果圖
實時識別
其實就是本地識別的拓展版,把攝像頭的數據轉爲Bitmap,去識別,仍是貼核心代碼吧,看不懂的本身下Demo研究。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
|
/**
* 攝像頭數據回調
* @param data
* @param camera
*/
@Override
public
void
onPreviewFrame(
byte
[] data, Camera camera) {
camera.addCallbackBuffer(data);
//將byte數組轉爲Bitmap
ByteArrayOutputStream baos;
byte
[] rawImage;
Bitmap bitmap;
Camera.Size previewSize = camera.getParameters().getPreviewSize();
//獲取尺寸,格式轉換的時候要用到
BitmapFactory.Options newOpts =
new
BitmapFactory.Options();
newOpts.inJustDecodeBounds =
true
;
YuvImage yuvimage =
new
YuvImage(
data,
ImageFormat.NV21,
previewSize.width,
previewSize.height,
null
);
baos =
new
ByteArrayOutputStream();
yuvimage.compressToJpeg(
new
Rect(
0
,
0
, previewSize.width, previewSize.height),
100
, baos);
// 80--JPG圖片的質量[0-100],100最高
rawImage = baos.toByteArray();
//將rawImage轉換成bitmap
BitmapFactory.Options options =
new
BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.RGB_565;
bitmap = BitmapFactory.decodeByteArray(rawImage,
0
, rawImage.length, options);
if
(bitmap ==
null
) {
Log.d(
"zka"
,
"bitmap is nlll"
);
return
;
}
else
{
//裁取圖片中央身份證區域
int
height = bitmap.getHeight();
int
width = bitmap.getWidth();
final
Bitmap bitmap1 = Bitmap.createBitmap(bitmap, width/
2
- dip2px(
150
),height /
2
- dip2px(
92
), dip2px(
300
), dip2px(
185
));
//截取身份證號碼區域
int
x, y, w, h;
x = (
int
) (bitmap1.getWidth() *
0.340
);
y = (
int
) (bitmap1.getHeight() *
0.800
);
w = (
int
) (bitmap1.getWidth() *
0.6
+
0
.5f);
h = (
int
) (bitmap1.getHeight() *
0.12
+
0
.5f);
Bitmap bit_hm = Bitmap.createBitmap(bitmap1, x, y, w, h);
// 識別
if
(bit_hm !=
null
){
String localre = localre(bit_hm);
if
(localre.length() ==
18
) {
Log.e(TAG,
"onPreviewFrame: "
+localre );
Toast.makeText(getApplicationContext(),localre,Toast.LENGTH_SHORT).show();
}
}
}
}
/**
* 識別
* @param bm
* @return
*/
private
String localre(Bitmap bm) {
String content =
""
;
bm = bm.copy(Bitmap.Config.ARGB_8888,
true
);
iv_result.setImageBitmap(bm);
TessBaseAPI baseApi =
new
TessBaseAPI();
baseApi.init(TESSBASE_PATH, DEFAULT_LANGUAGE);
//設置識別模式
baseApi.setPageSegMode(TessBaseAPI.PageSegMode.PSM_SINGLE_LINE);
//設置要識別的圖片
baseApi.setImage(bm);
baseApi.setVariable(
"tessedit_char_whitelist"
,
"0123456789Xx"
);
Log.e(TAG,
"localre: "
+ baseApi.getUTF8Text());
content = baseApi.getUTF8Text();
baseApi.clear();
baseApi.end();
return
content;
}
|
Ok,就這樣吧!核心也就這些東西,有問題的能夠留言或私信,有好的解決辦法也能夠交流,,出於隱私,就把人家的信息打碼, 不過識別出來準確度是100%。