Android上使调用OpenCV 2.4.10 实现二维码区域定位(Z-xing 码),该文章主要用于笔者自己学习中的总结,暂贴出代码部分,待以后有时间再补充算法的详细细节。

Activity class Java 文件

package cn.hjq.android_capture;  import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.util.ArrayList; import java.util.List;  import org.opencv.android.BaseLoaderCallback; import org.opencv.android.LoaderCallbackInterface; import org.opencv.android.OpenCVLoader; import org.opencv.core.*; import org.opencv.highgui.*; import org.opencv.imgproc.*; import org.opencv.utils.Converters;  import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Matrix; import android.hardware.Camera; import android.hardware.Camera.AutoFocusCallback; import android.hardware.Camera.Parameters; import android.hardware.Camera.PictureCallback; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.app.Activity; import android.content.pm.ActivityInfo; import android.view.MotionEvent; import android.view.SurfaceHolder; import android.view.SurfaceHolder.Callback; import android.view.SurfaceView; import android.view.View;  public class capture extends Activity {  private SurfaceView picSV;  private Camera camera;  private String strPicPath;    //OpenCV类库加载并初始化成功后的回调函数,在此我们不进行任何操作  private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {   @Override   public void onManagerConnected(int status) {    switch (status) {     case LoaderCallbackInterface.SUCCESS:{     } break;     default:{      super.onManagerConnected(status);     } break;    }   }  };    @SuppressWarnings("deprecation")  @Override  protected void onCreate(Bundle savedInstanceState) {   super.onCreate(savedInstanceState);   this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);   setContentView(R.layout.main);   picSV = (SurfaceView) findViewById(R.id.picSV);   picSV.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);   picSV.getHolder().addCallback(new MyCallback());  }   private class MyCallback implements Callback{  //我们在SurfaceView创建的时候就要进行打开摄像头、设置预览取景所在的SurfaceView、设置拍照的参数、开启预览取景等操作   @Override   public void surfaceCreated(SurfaceHolder holder) {    try {     camera = Camera.open();//打开摄像头     camera.setPreviewDisplay(picSV.getHolder());//设置picSV来进行预览取景     Parameters params = camera.getParameters();//获取照相机的参数     params.setPictureSize(800, 480);//设置照片的大小为800*480     params.setPreviewSize(800, 480);//设置预览取景的大小为800*480     params.setFlashMode("auto");//开启闪光灯     params.setJpegQuality(50);//设置图片质量为50       camera.setParameters(params);//设置以上参数为照相机的参数     camera.startPreview();    }    catch (IOException e) {    //开始预览取景,然后我们就可以拍照了     e.printStackTrace();    }   }     @Override   public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {   }     @Override   public void surfaceDestroyed(SurfaceHolder holder) {    //当SurfaceView销毁时,我们进行停止预览、释放摄像机、垃圾回收等工作    camera.stopPreview();    camera.release();    camera = null;   }  }   public void takepic(View v){   //在我们开始拍照前,实现自动对焦   camera.autoFocus(new MyAutoFocusCallback());  }   private class MyAutoFocusCallback implements AutoFocusCallback{   @Override   public void onAutoFocus(boolean success, Camera camera) {    //开始拍照    camera.takePicture(null, null, null, new MyPictureCallback());   }  }   private class MyPictureCallback implements PictureCallback{   @Override   public void onPictureTaken(byte[] data, Camera camera) {    try {     Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);     Matrix matrix = new Matrix();     matrix.preRotate(90);     bitmap = Bitmap.createBitmap(bitmap ,0,0, bitmap.getWidth(),             bitmap.getHeight(),matrix,true);     strPicPath =      Environment.getExternalStorageDirectory()+"/1Zxing/"+System.currentTimeMillis()+".jpg";     FileOutputStream fos = new FileOutputStream( strPicPath );     bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);     fos.close();     Handler mHandler = new Handler();     mHandler.post(mRunnable);     camera.startPreview();    }    catch (Exception e) {     e.printStackTrace();    }   }  }    public boolean onTouchEvent (MotionEvent event)  {   int Action = event.getAction();   if ( 1 == Action ) {    camera.autoFocus(new MyAutoFocusCallback1());   }   return true;  }    private class MyAutoFocusCallback1 implements AutoFocusCallback {   @Override   public void onAutoFocus(boolean success, Camera camera) {   }  }    @Override  public void onResume(){   super.onResume();   //通过OpenCV引擎服务加载并初始化OpenCV类库,所谓OpenCV引擎服务即是   //OpenCV_2.4.3.2_Manager_2.4_*.apk程序包,存在于OpenCV安装包的apk目录中   OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_10, this, mLoaderCallback);  }   Runnable mRunnable = new Runnable() {   public void run() {    List contours = new ArrayList();    String strMissingTime = null;    Mat srcColor = new Mat(), srcColorResize = new Mat();    Mat srcGray = new Mat(), srcGrayResize = new Mat(), srcGrayResizeThresh = new Mat();    srcGray = Highgui.imread(strPicPath, 0);    srcColor = Highgui.imread(strPicPath, 1);    Imgproc.resize(srcGray, srcGrayResize, new Size(srcGray.cols()*0.2,srcGray.rows()*0.2));    Imgproc.resize(srcColor, srcColorResize, new Size(srcGray.cols()*0.2,srcGray.rows()*0.2));    long start = System.currentTimeMillis();    //二值化加轮廓寻找    Imgproc.adaptiveThreshold(srcGrayResize, srcGrayResizeThresh, 255,           Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C,           Imgproc.THRESH_BINARY, 35, 5);    Imgproc.findContours(srcGrayResizeThresh, contours, new Mat(),          Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_NONE);    long end = System.currentTimeMillis();    strMissingTime = String.valueOf( end - start );    strMissingTime = strMissingTime + "\r";    //轮廓绘制    for ( int i = contours.size()-1; i >= 0; i-- )    {     MatOfPoint2f NewMtx = new MatOfPoint2f( contours.get(i).toArray() );     RotatedRect rotRect = Imgproc.minAreaRect( NewMtx );     Point vertices[] = new Point[4];     rotRect.points(vertices);     List rectArea = new ArrayList();     for ( int n = 0; n < 4; n ++ )     {      Point temp = new Point();      temp.x = vertices[n].x;      temp.y = vertices[n].y;      rectArea.add(temp);     }     Mat rectMat = Converters.vector_Point_to_Mat(rectArea);     double minRectArea = Imgproc.contourArea( rectMat );     Point center = new Point();     float radius[] = {0};     Imgproc.minEnclosingCircle(NewMtx, center, radius);     if(      Imgproc.contourArea( contours.get(i)) < 300 ||      Imgproc.contourArea( contours.get(i)) > 3000      || minRectArea < radius[0]*radius[0]*1.57     ) contours.remove(i);    }    Imgproc.drawContours(srcColorResize, contours, -1, new Scalar(255,0,0));    Highgui.imwrite(Environment.getExternalStorageDirectory()+"/1Zxing/"        +System.currentTimeMillis()+"contour.jpg", srcColorResize);      File file=new File(Environment.getExternalStorageDirectory()+"/1Zxing/","log.txt");    BufferedWriter out = null;    try {     out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file, true)));     out.write(strMissingTime);     out.close();    }    catch (Exception e) {     e.printStackTrace();    }      }  }; } 

layout.xml 文件

              

string.xml 文件

  Code  Take picture button  

style.xml 文件(理论上是可以自动生成,若自动生成内容有错,可以参考)

              

AndroidManifest.xml 文件

                                         

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

更多相关文章

  1. 一款常用的 Squid 日志分析工具
  2. GitHub 标星 8K+!一款开源替代 ls 的工具你值得拥有!
  3. RHEL 6 下 DHCP+TFTP+FTP+PXE+Kickstart 实现无人值守安装
  4. Linux 环境下实战 Rsync 备份工具及配置 rsync+inotify 实时同步
  5. Android培训班(19)
  6. Android(安卓)Studio项目混淆后输出的文件所在位置
  7. Android笔记(1)adb的使用
  8. android 使用xutils3 https详解
  9. Android下载文件,如果文件夹下有同名文件,则重命名规则为a(2)、a(3

随机推荐

  1. Android系统权限和root权限
  2. 修改android项目sdk版本的方法
  3. Android(安卓)入门 和 环境搭建
  4. iOS 与 Android(安卓)生命周期对比
  5. Android获取当前时间
  6. Android,TextView的所有属性和方法
  7. Android根据 uri 获得文件真实路径
  8. android源码浅析--notification
  9. Android腾讯微博客户端开发一:在下方的Ta
  10. ViewBinding的简单使用