Android调用OpenCV2.4.10实现二维码区域定位

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<MatOfPoint> contours = new ArrayList<MatOfPoint>();
   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<Point> rectArea = new ArrayList<Point>();
    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 文件

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 tools:context=".MainActivity" > 

 <SurfaceView
  android:id="@+id/picSV"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  >
 </SurfaceView> 

 <ImageButton
  android:contentDescription="@string/desc"
  android:onClick="takepic"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:layout_gravity="right|top"
  android:src="@android:drawable/ic_menu_camera" /> 

</FrameLayout>

string.xml 文件

<resources>
 <string name="app_name">Code</string>
 <string name="desc">Take picture button</string>
</resources>

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

<resources> 

 <!--
  Base application theme, dependent on API level. This theme is replaced
  by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
 -->
 <style name="AppBaseTheme" parent="android:Theme.Light">
  <!--
   Theme customizations available in newer API levels can go in
   res/values-vXX/styles.xml, while customizations related to
   backward-compatibility can go here.
  -->
 </style> 

 <!-- Application theme. -->
 <style name="AppTheme" parent="AppBaseTheme">
  <!-- All customizations that are NOT specific to a particular API-level can go here. -->
  <item name="android:windowNoTitle">true</item>
  <item name="android:windowFullscreen">true</item>
 </style> 

</resources> 

AndroidManifest.xml 文件

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
 package="cn.hjq.android_capture"
 android:versionCode="1"
 android:versionName="1.0" > 

 <uses-permission
  android:name="android.permission.CAMERA"/>
 <uses-permission
  android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 

 <uses-sdk
  android:minSdkVersion="8"
  android:targetSdkVersion="19" /> 

 <application
  android:allowBackup="true"
  android:icon="@drawable/ic_launcher"
  android:label="@string/app_name"
  android:theme="@style/AppTheme" >
  <activity
   android:name=".capture" >
   <intent-filter >
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
   </intent-filter>
  </activity>
 </application> 

</manifest>

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

您可能感兴趣的文章:

  • Android实现二维码扫描和生成的简单方法
  • Android上使用ZXing识别条形码与二维码的方法
  • Android开发框架之自定义ZXing二维码扫描界面并解决取景框拉伸问题
  • iOS和Android用同一个二维码实现跳转下载链接的方法
  • 基于Android实现个性彩色好看的二维码
  • Android项目实战(二十八):使用Zxing实现二维码及优化实例
  • Android基于google Zxing实现各类二维码扫描效果
  • Android平台生成二维码并实现扫描 & 识别功能
  • Android编程实现二维码的生成与解析
  • Android 二维码 生成和识别二维码 附源码下载
(0)

相关推荐

  • 基于Android实现个性彩色好看的二维码

    我编码的风格,先给大家展示下效果图,亲们感觉效果还不错,很满意的话,请继续往下阅读. 之前呢,也写过用安卓实现二维码生成彩色的二维码和带logo的二维码,也知道可以使用QRCode和ZXing两种方式,然后这一篇呢也是写二维码使用BarcodeFormat.QR_CODE,主要也是看见很多的非常漂亮的二维码,这里呢主要模仿qq的二维码,并且也高仿实现了长按发送给朋友和保存到图库的功能,觉得不错呢就请多支持下,哪里不好呢也可以说出来.好了我们一步一步来. 第一步:简单二维码实现 先来个最简单的二维

  • Android开发框架之自定义ZXing二维码扫描界面并解决取景框拉伸问题

    先给大家展示下效果图: 扫描内容是下面这张,二维码是用zxing库生成的 由于改了好几个类,还是去年的事都忘得差不多了,所以只能上这个类的代码了,主要就是改了这个CaptureActivity.java package com.zxing.activity; import java.io.IOException; import java.util.Vector; import android.app.Activity; import android.content.Intent; import

  • Android项目实战(二十八):使用Zxing实现二维码及优化实例

    前言: 多年之前接触过zxing实现二维码,没想到今日项目中再此使用竟然使用的还是zxing,百度之,竟是如此牛的玩意. 当然,项目中我们也许只会用到二维码的扫描和生成两个功能,所以不必下载完整的jar包,使用简化版的即可,下文可见. 这篇文章讲述: 1.如果快速在项目中集成zxing,实现扫描和生成二维码功能 2.根据项目需求去修改源码实现我们的要求并进行优化 一.快速集成zxing二维码 1.下载库文件 :http://xiazai.jb51.net/201611/yuanma/ZXingB

  • iOS和Android用同一个二维码实现跳转下载链接的方法

    前言 最近一个项目需要iOS和安卓使用一个二维码,让扫描的机器自己识别操作系统实现跳转到相应的下载链接.比如iPhone用微信进行扫描就让他跳转appStore的下载页面,安卓机器使用微信扫描就直接跳浏览器下载.但是这二维码还有一个需求就是,用户已经下载了这个app,当用户打开app进入到注册页面时,再次扫描这个二维码时,自动填写邀请码进行注册.那么该如何实现,细节就不说了,直接上代码. 使用js实现,其实代码非常简单. 使用时直接拷贝代码,改掉相应的链接就好. PS:该链接在微信环境打开时还是

  • Android上使用ZXing识别条形码与二维码的方法

    目前有越来越多的手机具备自动对焦的拍摄功能,这也意味着这些手机可以具备条码扫描的功能.手机具备条码扫描的功能,可以优化购物流程,快速存储电子名片(二维码)等. 本文所述实例就使用了ZXing 1.6实现条码/二维码识别.ZXing是个很经典的条码/二维码识别的开源类库,早在很久以前,就有开发者在J2ME上使用ZXing了,只不过需要支持JSR-234规范(自动对焦)的手机才能发挥其威力,而目前已经有不少Android手机具备自动对焦的功能. 本文代码运行的结果如下,使用91手机助手截图时,无法截

  • Android编程实现二维码的生成与解析

    本文实例讲述了Android编程实现二维码的生成与解析.分享给大家供大家参考,具体如下: 直接上代码,代码上面有具体的解析,并且提供jar供下载:二维码Jar包.rar. 根据文本生成对应的二维码: // 生成QR图 private void createImage() { try { // 需要引入core包 QRCodeWriter writer = new QRCodeWriter(); String text = qr_text.getText().toString(); Log.i(T

  • Android 二维码 生成和识别二维码 附源码下载

    今天讲一下目前移动领域很常用的技术--二维码.现在大街小巷.各大网站都有二维码的踪迹,不管是IOS.Android.WP都有相关支持的软件.之前我就想了解二维码是如何工作,最近因为工作需要使用相关技术,所以做了初步了解.今天主要是讲解如何使用ZXing库,生成和识别二维码.这篇文章实用性为主,理论性不会讲解太多,有兴趣可以自己查看源码. 1.ZXing库介绍 这里简单介绍一下ZXing库.ZXing是一个开放源码的,用Java实现的多种格式的1D/2D条码图像处理库,它包含了联系到其他语言的端口

  • Android基于google Zxing实现各类二维码扫描效果

    随着微信的到来,二维码越来越火爆,随处能看到二维码,比如商城里面,肯德基,餐厅等等,对于二维码扫描我们使用的是google的开源框架Zxing,我们可以去http://code.google.com/p/zxing/下载源码和Jar包,之前我项目中的二维码扫描功能只实现了扫描功能,其UI真的是其丑无比,一个好的应用软件,其UI界面也要被大众所接纳,不然人家就不会用你的软件啦,所以说应用软件功能和界面一样都很重要,例如微信,相信微信UI被很多应用软件所模仿,我也仿照微信扫描二维码效果进行模仿,虽然

  • Android实现二维码扫描和生成的简单方法

    这里简单介绍一下ZXing库.ZXing是一个开放源码的,用Java实现的多种格式的1D/2D条码图像处理库,它包含了联系到其他语言的端口.Zxing可以实现使用手机的内置的摄像头完成条形码的扫描及解码.该项目可实现的条形码编码和解码.目前支持以下格式:UPC-A,UPC-E.EAN-8,EAN-13.39码.93码.ZXing是个很经典的条码/二维码识别的开源类库,以前在功能机上,就有开发者使用J2ME运用ZXing了,不过要支持JSR-234规范(自动对焦)的手机才能发挥其威力. ZXing

  • Android平台生成二维码并实现扫描 & 识别功能

    1.二维码的前世今生 "二维条码/二维码(2-dimensional bar code)是用某种特定的几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形记录数据符号信息的:在代码编制上巧妙地利用构成计算机内部逻辑基础的"0"."1"比特流的概念,使用若干个与二进制相对应的几何形体来表示文字数值信息,通过图象输入设备或光电扫描设备自动识读以实现信息自动处理:它具有条码技术的一些共性:每种码制有其特定的字符集:每个字符占有一定的宽度:具有一定的校验功能

随机推荐