音效素材网提供各类素材,打造精品素材网站!

站内导航 站长工具 投稿中心 手机访问

音效素材

Android调用OpenCV2.4.10实现二维码区域定位
日期:2021-06-18 09:29:04   来源:脚本之家

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> 

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

    您感兴趣的教程

    在docker中安装mysql详解

    本篇文章主要介绍了在docker中安装mysql详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编...

    详解 安装 docker mysql

    win10中文输入法仅在桌面显示怎么办?

    win10中文输入法仅在桌面显示怎么办?

    win10系统使用搜狗,QQ输入法只有在显示桌面的时候才出来,在使用其他程序输入框里面却只能输入字母数字,win10中...

    win10 中文输入法

    一分钟掌握linux系统目录结构

    这篇文章主要介绍了linux系统目录结构,通过结构图和多张表格了解linux系统目录结构,感兴趣的小伙伴们可以参考一...

    结构 目录 系统 linux

    PHP程序员玩转Linux系列 Linux和Windows安装

    这篇文章主要为大家详细介绍了PHP程序员玩转Linux系列文章,Linux和Windows安装nginx教程,具有一定的参考价值,感兴趣...

    玩转 程序员 安装 系列 PHP

    win10怎么安装杜比音效Doby V4.1 win10安装杜

    第四代杜比®家庭影院®技术包含了一整套协同工作的技术,让PC 发出清晰的环绕声同时第四代杜比家庭影院技术...

    win10杜比音效

    纯CSS实现iOS风格打开关闭选择框功能

    这篇文章主要介绍了纯CSS实现iOS风格打开关闭选择框,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作...

    css ios c

    Win7如何给C盘扩容 Win7系统电脑C盘扩容的办法

    Win7如何给C盘扩容 Win7系统电脑C盘扩容的

    Win7给电脑C盘扩容的办法大家知道吗?当系统分区C盘空间不足时,就需要给它扩容了,如果不管,C盘没有足够的空间...

    Win7 C盘 扩容

    百度推广竞品词的投放策略

    SEM是基于关键词搜索的营销活动。作为推广人员,我们所做的工作,就是打理成千上万的关键词,关注它们的质量度...

    百度推广 竞品词

    Visual Studio Code(vscode) git的使用教程

    这篇文章主要介绍了详解Visual Studio Code(vscode) git的使用,小编觉得挺不错的,现在分享给大家,也给大家做个参考。...

    教程 Studio Visual Code git

    七牛云储存创始人分享七牛的创立故事与

    这篇文章主要介绍了七牛云储存创始人分享七牛的创立故事与对Go语言的应用,七牛选用Go语言这门新兴的编程语言进行...

    七牛 Go语言

    Win10预览版Mobile 10547即将发布 9月19日上午

    微软副总裁Gabriel Aul的Twitter透露了 Win10 Mobile预览版10536即将发布,他表示该版本已进入内部慢速版阶段,发布时间目...

    Win10 预览版

    HTML标签meta总结,HTML5 head meta 属性整理

    移动前端开发中添加一些webkit专属的HTML5头部标签,帮助浏览器更好解析HTML代码,更好地将移动web前端页面表现出来...

    移动端html5模拟长按事件的实现方法

    这篇文章主要介绍了移动端html5模拟长按事件的实现方法的相关资料,小编觉得挺不错的,现在分享给大家,也给大家...

    移动端 html5 长按

    HTML常用meta大全(推荐)

    这篇文章主要介绍了HTML常用meta大全(推荐),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参...

    cdr怎么把图片转换成位图? cdr图片转换为位图的教程

    cdr怎么把图片转换成位图? cdr图片转换为

    cdr怎么把图片转换成位图?cdr中插入的图片想要转换成位图,该怎么转换呢?下面我们就来看看cdr图片转换为位图的...

    cdr 图片 位图

    win10系统怎么录屏?win10系统自带录屏详细教程

    win10系统怎么录屏?win10系统自带录屏详细

    当我们是使用win10系统的时候,想要录制电脑上的画面,这时候有人会想到下个第三方软件,其实可以用电脑上的自带...

    win10 系统自带录屏 详细教程

    + 更多教程 +
    Windows系统Linux系统苹果MACAndroidiOS系统鸿蒙系统