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,new MyPictureCallback()); } } private class MyPictureCallback implements PictureCallback{ @OverrIDe public voID onPictureTaken(byte[] data,Camera camera) { try { Bitmap bitmap = BitmapFactory.decodeByteArray(data,data.length); Matrix matrix = new Matrix(); matrix.preRotate(90); bitmap = Bitmap.createBitmap(bitmap,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,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,-1,new Scalar(255,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 二维码 生成和识别二维码 附源码下载 总结以上是内存溢出为你收集整理的Android调用OpenCV2.4.10实现二维码区域定位全部内容,希望文章能够帮你解决Android调用OpenCV2.4.10实现二维码区域定位所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)