zoukankan      html  css  js  c++  java
  • Android studio ocr初级app开发问题汇总(含工程代码)

      博客第一篇文章,稍作修改,增加文字介绍


      开发目的

        最近由于某些需求,需要在Android手机端实现OCR功能,大致为通过手机照相,识别出相片中的中文信息字段。但是由于新手光环+流程不熟悉,遇到了各种各样的问题,准备在本文中叙述一下,最好能派上用场。

      开发环境

        Android studio 2.3.3  Windows下,测试手机Android4.4版本

      环境搭建

        搭建安卓OCR开发环境.   

        使用的google提供的OCR识别引擎,可以选择多种语言。

        参考上述链接可以实现,最开始的搭建。这里需要注意的是:由于GitHub上的工程与当前新建的Gradle版本不匹配,导致android-maven错误,注意添加依赖。

      大文件拷贝

        由于OCR训练好的文件比较大,以中文识别为例,50MB左右大小,需要将文件放置于手机的SD卡中,便于TessBaseApi对象初始化。(init()函数需要文件路径,目前没想到更好的方式)。

      本文提出的解决方式:首先将chi_sim.traineddata文件放入asset文件夹中。在程序首次运行的时候,将文件拷贝到SD卡中,注意获取SD卡读写权限。拷贝函数如下:

      加入相机

      以上步骤顺利的话,可以实现对图片的文字进行识别功能。为了实现对照相机得到的相片进行识别,需要打开摄像机。

    Intent getImageByCamera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    startActivityForResult(getImageByCamera,REQUST_ORIGINAL);
    

      REQUST_ORIGINAL是自己定义的常量值,用于接收时,与requestcode值比对,判断是否为需要的数据。

      

     1 @Override
     2     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
     3         super.onActivityResult(requestCode, resultCode, data);
     4          if (resultCode == Activity.RESULT_OK && requestCode == REQUST_ORIGINAL){
     5           Bundle bdl = data.getExtras();
     6             Bitmap bmp = (Bitmap) bdl.get("data");
     7             ImageView im_camera = (ImageView)findViewById(R.id.img_camera);
     8             im_camera.setImageBitmap(bmp);
     9             mTess.clear();
    10             mTess.setImage(bmp);
    11             String result = mTess.getUTF8Text();
    12             TextView txtget = (TextView)findViewById(R.id.txt_get);
    13             txtget.setText(result);
    14         }
    15 }

       在回调函数里,处理返回的图片数据,就可以实现初步的图片文字识别。但是这样返回的图片数据为缩略图,清晰的很低。如果想要对原始图片进行处理的话,需要换一种图片获取的方式。

    首先,调用相机的时候,添加图片为文件存储的路径。

     1  Intent getImageByCamera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
     2         Uri uri;
     3         if(Build.VERSION.SDK_INT>=24)
     4         {
     5             File g= new File(picPath);//测试错误
     6             try {
     7                 g.createNewFile();
     8             } catch (IOException e) {
     9                 e.printStackTrace();
    10             }
    11             uri = FileProvider.getUriForFile(this,"xueyu404",g);
    12         }else{
    13             uri = Uri.fromFile(new File(picPath));
    14         }
    15 
    16         getImageByCamera.putExtra(MediaStore.EXTRA_OUTPUT,uri);
    17         startActivityForResult(getImageByCamera,REQUST_ORIGINAL);

      PicPath为String变量,意义为相机图片在sd卡上的存储路径。然后在回调函数里对图片进行处理。

    由于Android 7.0在跨应用数据调用增加了限制,需要使用FileProvider获取uri,具体FileProvider配置参考一下链接

    http://blog.csdn.net/hehe26/article/details/52921056

     1 if (resultCode == Activity.RESULT_OK && requestCode == REQUST_ORIGINAL){
     2             FileInputStream fis = null;
     3             try{
     4                 Log.e("sdpath2",picPath);
     5                 fis = new FileInputStream(picPath);
     6                 Bitmap bm = BitmapFactory.decodeStream(fis);
     7                 ImageView im_camera = (ImageView)findViewById(R.id.img_camera);
     8                 im_camera.setImageBitmap(bm);
     9                 mTess.setImage(bm );
    10                 String result = mTess.getUTF8Text();
    11                 TextView txtget = (TextView)findViewById(R.id.txt_get);
    12                 txtget.setText(result);
    13             }catch (FileNotFoundException e){
    14                 e.printStackTrace();
    15             }finally {
    16                 try {
    17                     fis.close();
    18                 } catch (IOException e) {
    19                     e.printStackTrace();
    20                 }
    21             }
    22         }
    23         else {
    24             Toast.makeText(this,"没有拍到照片",Toast.LENGTH_SHORT).show();
    25         }

        运行效率

        通过上述的过程,可以完成,基本的文字识别的功能。但仍然存在着不能忽略的问题。

        一,使用缩略图进行识别的时候,运行速率可以接受,对于特别大的文字识别还可以。但是由于图片被压缩过,如果图片中存在比较小的文字基本不能识别。

        二,使用后面提到的原始图片进行识别的话,由于手机的计算能力有限,识别的计算过程相当耗时。识别过程要放到另外的线程中单独运行,否则会卡死UI线程,假死。但是即使新建线程,需要的时间也远超用户的忍耐限度。

        改进优化

        由于图片原图比较大的原因,对整个图片进行识别的效果也不理想。所以本文建议在拍摄照片之后,用户用手指圈定识别区域文字。圈定区域 的控件,见我的另外一篇博客

        Android 通过触摸动态地在屏幕上画矩形

        此外,识别过程,控件初始化过程比较耗时,放置在UI线程中卡顿不可忍耐。本文采用线程池的方式,处理上述两个过程。

        最终效果图

        

          先点击相机拍照按钮,拍要识别的照片,再点击选取区域按钮,用手指画一个矩形框,圈好识别区域(如果矩形没画好可以再点击选取区域重新画),

    最后点击文字识别等待结果显示。

    工程代码链接:https://github.com/dutxueyu/Android_ocr_app

      

    本博客所有内容为原创,转载需征求作者同意。
  • 相关阅读:
    iOS NSString的常用用法
    有序数组在数据量较少时候的查找效率比较
    【转载】gdb基本命令总结
    从一个笔误引起的思考
    常见性能优化小技巧原理
    使用T-SQL进行活动目录查询
    你需要一条怎样的牛仔裤?
    #VSTS日志# 2015/12/10 – 终于可以删除工作项了
    #VSTS定制#全新的模版定制能力
    混合使用TFVC和GIT配置库的优化方案
  • 原文地址:https://www.cnblogs.com/xueyudlut/p/7156218.html
Copyright © 2011-2022 走看看