日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > Android >内容正文

Android

Android ORC文字识别之识别身份证号等(附源码)

發(fā)布時(shí)間:2023/12/18 Android 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android ORC文字识别之识别身份证号等(附源码) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
項(xiàng)目地址
https://github.com/979451341/OrcTest

我們說(shuō)說(shuō)實(shí)現(xiàn)這個(gè)項(xiàng)目已實(shí)現(xiàn)的功能,能夠截圖手機(jī)界面的某一塊,將這個(gè)某一塊圖片的Bitmap傳給tess-two的代碼來(lái)獲取掃描結(jié)果

我這里在貼出tess-two這個(gè)專(zhuān)為Android而創(chuàng)建的文字識(shí)別框架的地址
https://github.com/rmtheis/tess-two

接下來(lái)我就說(shuō)我如何一步一步的實(shí)現(xiàn)項(xiàng)目

1.實(shí)現(xiàn)基礎(chǔ)界面,我這里貼出已完成的界面


這樣是為了模仿掃描二維碼的界面,因?yàn)閽呙枭矸葑C號(hào)碼或者是手機(jī)號(hào)那樣長(zhǎng)條的數(shù)字,就將掃描區(qū)域也做成長(zhǎng)條狀,這個(gè)掃描區(qū)域是有意義的,因?yàn)榈綍r(shí)候截圖會(huì)只將掃描區(qū)域里的圖片信息拿去掃描,這也是為了提高掃描速度和精度。

首先要實(shí)現(xiàn)這個(gè)界面,我們需要畫(huà)出四個(gè)灰色長(zhǎng)方體的位置大小,上下左右。

left是掃描區(qū)域左邊離手機(jī)屏幕左邊的距離是手機(jī)屏幕寬度的1/10,right就是掃描區(qū)域右邊離手機(jī)屏幕左邊的距離是手機(jī)屏幕寬度的9/10,top是掃描區(qū)域頂部離手機(jī)屏幕頂部的距離是手機(jī)屏幕寬度的1/3,bottom是掃描區(qū)域底部離手機(jī)屏幕頂部的距離是手機(jī)屏幕寬度的4/9

WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);Display display = manager.getDefaultDisplay();PMwidth = display.getWidth();PMheight = display.getHeight();left = PMwidth/10;top = PMheight/3;right = PMwidth*9/10;bottom = PMheight*4/9;mFrameRect = new Rect(left,top,right,bottom);

畫(huà)畫(huà)

@Overridepublic void onDraw(Canvas canvas) {int width = PMwidth;int height = PMheight;Rect frame = mFrameRect;// 繪制焦點(diǎn)框外邊的暗色背景mPaint.setColor(mMaskColor);canvas.drawRect(0, 0, width, frame.top, mPaint);canvas.drawRect(0, frame.top, frame.left, frame.bottom + 1, mPaint);canvas.drawRect(frame.right + 1, frame.top, width, frame.bottom + 1, mPaint);canvas.drawRect(0, frame.bottom + 1, width, height, mPaint);}

還沒(méi)有完,還有布局文件放SurfaceView和按鈕,還有剛才做的自定義View

2.顯示Camera預(yù)覽和Camera拍攝


這里SurfaceView如何顯示Camera我不多說(shuō),只說(shuō)如何把Camera預(yù)覽變清晰,這里是通過(guò)循環(huán)自動(dòng)對(duì)焦來(lái)完成。

設(shè)置自動(dòng)對(duì)焦接口

mCamera.autoFocus(autoFocusCallback);

這個(gè)接口初始化傳入了Handler

autoFocusCallback.setHandler(handler,MSG_AUTOFUCS);

然后這個(gè)接口實(shí)現(xiàn)類(lèi)里,當(dāng)完成自動(dòng)對(duì)焦,會(huì)通過(guò)handler發(fā)送一個(gè)消息

@Overridepublic void onAutoFocus(boolean success, Camera camera) {Log.v("zzw", "autof focus "+success);if (mAutoFocusHandler != null) {mAutoFocusHandler.sendEmptyMessageDelayed(mAutoFocusMessage,AUTO_FOCUS_INTERVAL_MS); // mAutoFocusHandler = null;} else {Log.v(TAG, "Got auto-focus callback, but no handler for it");}}

然后handler如何執(zhí)行以下代碼,再進(jìn)行一次自動(dòng)對(duì)焦,這樣就完成了循環(huán)

case MSG_AUTOFUCS:cameraUtil.autoFocus();break;

然后給按鈕賦予拍攝功能,拍攝的還要停止聚焦

handler.removeCallbacksAndMessages(null);cameraUtil.takePicture(TwoActivity.this,TwoActivity.this,TwoActivity.this);

這個(gè)函數(shù)會(huì)被調(diào)用,data就是圖片數(shù)據(jù)

@Overridepublic void onPictureTaken(byte[] data, Camera camera)

這里要注意一件事,拍攝后Camera預(yù)覽界面就會(huì)停止,因?yàn)樗V咕劢沽?#xff0c;我們需要重新設(shè)置自動(dòng)對(duì)焦,并開(kāi)啟預(yù)覽

// 刷新相機(jī)public void refreshCamera(){if (surfaceHolder.getSurface() == null){// preview surface does not existreturn;}// stop preview before making changestry {mCamera.stopPreview();} catch(Exception e){// ignore: tried to stop a non-existent preview}// set preview size and make any resize, rotate or// reformatting changes here// start preview with new settingstry {mCamera.setPreviewDisplay(surfaceHolder);mCamera.startPreview();mCamera.autoFocus(autoFocusCallback);} catch (Exception e) {}surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);}

3.處理圖片數(shù)據(jù),完成局部截圖


繼續(xù)在onPictureTaken函數(shù)的data數(shù)據(jù)處理

因?yàn)樘幚韴D片是耗時(shí)任務(wù),所以開(kāi)啟子線程完成

這里先開(kāi)啟一個(gè)等待對(duì)話框

if(!mypDialog.isShowing())mypDialog.show();

然后開(kāi)啟子線程

if(data != null){new Thread(new BitmapThread(bitmap,data,handler,TwoActivity.this)).start();}

將data轉(zhuǎn)換為Bitmap數(shù)據(jù)

bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);

將圖片旋轉(zhuǎn)90度

bitmap = rotateBitmap(bitmap,90);這是旋轉(zhuǎn)Bitmap的函數(shù)
public static Bitmap rotateBitmap(Bitmap source, float angle) {Matrix matrix = new Matrix();matrix.postRotate(angle);return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, true);}

切割Bitmap,將掃描區(qū)域的圖片切割出來(lái)

int PMwidth = bitmap.getWidth(); // 得到圖片的寬,高int PMheight = bitmap.getHeight();int left = PMwidth/10;int top = PMheight/3;int right = PMwidth*9/10;int bottom = PMheight*4/9;int width = right - left;int height = bottom - top;Log.v("zzw",PMheight+" "+PMwidth);bitmap = Bitmap.createBitmap(bitmap, left, top, width, height, null,false);

4.掃描出結(jié)果


其實(shí)tess-two框架的使用很簡(jiǎn)單,但是使用這個(gè)框架需要依靠訓(xùn)練文件來(lái)完成掃描,我在res目錄下放了raw文件夾,里面的eng_traineddata文件就是這個(gè)用途,但是我們不能直接使用它們,我們需要將他們復(fù)制到手機(jī)存儲(chǔ)里

下面的代碼意思是在應(yīng)用私有路徑里創(chuàng)建tesseract/tessdata/eng.traineddata相關(guān)路徑的文件并使用輸入流將文件的數(shù)據(jù)讀出來(lái),然后使用輸出流將數(shù)據(jù)傳入eng.traineddata文件

public static void initTessTrainedData(Context context){if(initiated){return;}File appFolder = context.getFilesDir();File folder = new File(appFolder, tessdir);if(!folder.exists()){folder.mkdir();}tesseractFolder = folder.getAbsolutePath();File subfolder = new File(folder, subdir);if(!subfolder.exists()){subfolder.mkdir();}File file = new File(subfolder, filename);trainedDataPath = file.getAbsolutePath();Log.d(TAG, "Trained data filepath: " + trainedDataPath);if(!file.exists()) {try {FileOutputStream fileOutputStream;byte[] bytes = readRawTrainingData(context);if (bytes == null){return;}fileOutputStream = new FileOutputStream(file);fileOutputStream.write(bytes);fileOutputStream.close();initiated = true;Log.d(TAG, "Prepared training data file");} catch (FileNotFoundException e) {Log.e(TAG, "Error opening training data file\n" + e.getMessage());} catch (IOException e) {Log.e(TAG, "Error opening training data file\n" + e.getMessage());}}else{initiated = true;}}

好了再說(shuō)說(shuō)tess-two框架的使用

創(chuàng)建TessBaseAPI

TessBaseAPI tessBaseAPI = new TessBaseAPI();

關(guān)閉測(cè)試

tessBaseAPI.setDebug(true);

設(shè)置訓(xùn)練數(shù)據(jù)路徑和識(shí)別文字是英文

tessBaseAPI.init(path, "eng");

?設(shè)置白名單

tessBaseAPI.setVariable(TessBaseAPI.VAR_CHAR_WHITELIST, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");

設(shè)置黑名單

tessBaseAPI.setVariable(TessBaseAPI.VAR_CHAR_BLACKLIST, "!@#$%^&*()_+=-[]}{;:'\"\\|~`,./<>?");

設(shè)置識(shí)別模式

tessBaseAPI.setPageSegMode(TessBaseAPI.PageSegMode.PSM_AUTO_OSD);

傳入bitmap數(shù)據(jù)

tessBaseAPI.setImage(bitmap);

獲取掃描結(jié)果

String inspection = tessBaseAPI.getHOCRText(0);

結(jié)束TestBaseAPI的使用

tessBaseAPI.end();

實(shí)現(xiàn)掃描身份證號(hào)碼,這里是通過(guò)正則表達(dá)式來(lái)判斷掃描出的結(jié)果是否有身份證號(hào)碼,也就是說(shuō)tess-two其實(shí)是只是掃描出Bitmap文件里面有哪些文字,然后使用正則表達(dá)式來(lái)篩選出我們需要的數(shù)據(jù)。也就是說(shuō)我們通過(guò)換取正則表達(dá)式就能做到掃描手機(jī)號(hào)等,帶有某種規(guī)律的數(shù)字或者字母

這是正則表達(dá)式的線上工具地址,大家可以自己試試 http://tool.oschina.net/regex/#

private static Pattern pattern = Pattern.compile("\\d{17}[\\d|x]|\\d{15}");public static String getTelNum(String sParam){if(TextUtils.isEmpty(sParam)){return "";}Matcher matcher = pattern.matcher(sParam);StringBuilder bf = new StringBuilder();while (matcher.find()) {bf.append(matcher.group()).append(",");}int len = bf.length();if (len > 0) {bf.deleteCharAt(len - 1);}return bf.toString();}

然后通過(guò)handler返回結(jié)果

Message message = Message.obtain();message.what = 1;Bundle bundle = new Bundle();bundle.putString("decode",strDecode);message.setData(bundle);message.what = TwoActivity.MSG_BITMAP;handler.sendMessage(message);

取消加載框,并將局部截圖的圖像和掃描的結(jié)果通過(guò)DialogFragment顯示出來(lái)

mypDialog.dismiss();String strDecode = msg.getData().getString("decode","掃描失敗");if(strDecode == null ||strDecode.equals(""))strDecode = "掃描失敗";imageDialogFragment.setImage(bitmap);imageDialogFragment.setText(strDecode);imageDialogFragment.show(getFragmentManager(), "ImageDialogFragment");


5.結(jié)論


其實(shí)還沒(méi)有結(jié)束因?yàn)槲冶鞠胱龀鲆粋€(gè)能夠掃描整張身份證的項(xiàng)目,我看一下網(wǎng)上有很多API都能實(shí)現(xiàn)這個(gè)功能,但都要錢(qián),如果要是能夠?qū)崿F(xiàn)這個(gè)功能,并發(fā)到github,我豈不是成為大神了。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

總結(jié)

以上是生活随笔為你收集整理的Android ORC文字识别之识别身份证号等(附源码)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。