opencv mat 转 bitmap4android 中的2个Mat(Mat的值为2个Bitmap)如何变成一个Mat(即图片融合)

来源:互联网 发表时间: 22:50:16 责任编辑:李志喜字体:
为了帮助网友解决“opencv4android 3.0实现三帧差分法无法正确显示结果”相关的问题,学网通过互联网对“opencv4android 3.0实现三帧差分法无法正确显示结果”相关的解决方案进行了整理,用户详细问题包括:opencvopencv4android三帧差分法运动目标检测android我想在android上实现三帧差分法,效果同电脑上那样,但是做三帧差分运算后结果无法显示出来,请问用什么方法显示运算结果。(1)电脑上的三帧差分程序(正确)://&25MotionDetetion_ThreeDiff.cpp&:&定义控制台应用程序的入口点。&&//三帧差分法&&&&#include&&iostream&#include&&cv.h&&&&&#include&&cxcore.h&&&&&#include&&highgui.h&&&&&//CAM定义用摄像头获得视频else文件&&//#define&CAM&&&&&&int&apos=30;&&&&void&on_trackbar(int&pos)&&&&{&&&&&&&&&&&&apos=&&&&&}&&&&&&&&&&int&main(&int&argc,&char**&argv&)&&&&{&&&&&&&&//声明IplImage指针&&&&&&&&IplImage*&pFrame&=&NULL;&//原始视频帧&&&&&&&&IplImage*&pFrImg&=&NULL;&//提取的前景图像,即运动目标&&&&&&&&IplImage*&pBkImg&=&NULL;&//背景图像&&&&&&&IplImage*&pMiImg&=&NULL;&//中间帧图像&&&&&&&&&&CvMat*&pFrameMat&=&NULL;&//原始视频矩阵&&&&&&&CvMat*&pFrMat&=&NULL;&&&&//前景矩阵&&第一帧&&&&&&CvMat*&pBkMat&=&NULL;&&&&//背景矩阵&&第三帧&&&&&&CvMat*&pMiMat&=&NULL;&&&&//中间帧矩阵&第二帧&&&&&&CvMat*&pRe1Mat&=&NULL;&&&//结果1&&&&&&CvMat*&pRe2Mat&=&NULL;&&&//结果2&&&&&&CvCapture*&pCapture&=&NULL;&&&&&&&&//帧数&&&&&&int&nFrmNum&=&0;&&&&&&&&&&&&//创建窗口&&&&&&&&cvNamedWindow("video",&1);&&&&&&&&cvNamedWindow("background",1);&&&&&&&&cvNamedWindow("foreground",1);&&&&&&&&//使窗口有序排列&&&&&&&&cvMoveWindow("video",&30,&0);&&&&&&&&cvMoveWindow("background",&360,&0);&&&&&&&&cvMoveWindow("foreground",&690,&0);&&&&&&&//&滑动条&&&&&&&&&&&&&&&&int&nThreshold&=&30;&&&&&&&&&&&&&&cvCreateTrackbar("阀值",&"foreground",&&nThreshold,&100,&on_trackbar);&&&&&&&&&&&&if(&argc&==&1&||&(argc&==&2&&&&strlen(argv[1])&==&1&&&&isdigit(argv[1][0])))&&&&&&&&//打开摄像头&&&&&&&&pCapture&=&cvCaptureFromCAM(&argc&==&2&?&argv[1][0]&-&'0'&:&0&);&&&&else&if(&argc&==&2&)&&&&&&&&//打开avi&&&&&&&&pCapture&=&cvCaptureFrom***I(&argv[1]&);&&&&&&if(&!pCapture&)&&&&//打开视频流失败&&&&{&&&&&&&&fprintf(stderr,"Could¬&initialize&capturing...\n");&&&&&&&&return&-1;&&&&}&&&&//逐帧读取视频&&&&&&&&while(pFrame&=&cvQueryFrame(&pCapture&))&&&&&&&&{&&&&&&&&&&&&nFrmNum++;&&&&&&&&&&&&&&&&//如果是第一帧,需要申请内存,并初始化&&&&&&&&&&&&if(nFrmNum&==&1)&&&&&&&&&&&&{&&&&&&&&&&&&&&&&pBkImg&=&cvCreateImage(cvSize(pFrame-&width,&pFrame-&height),&&IPL_DEPTH_8U,1);&&&&&&&&&&&&&&&&pFrImg&=&cvCreateImage(cvSize(pFrame-&width,&pFrame-&height),&&IPL_DEPTH_8U,1);&&&&&&&&&&&&&&&&&&&&pBkMat&=&cvCreateMat(pFrame-&height,&pFrame-&width,&CV_32FC1);&&&&&&&&&&&&&&&&pFrMat&=&cvCreateMat(pFrame-&height,&pFrame-&width,&CV_32FC1);&&&&&&&&&&&&&&&&pFrameMat&=&cvCreateMat(pFrame-&height,&pFrame-&width,&CV_32FC1);&&&&&&&&&&&&&&&&pMiMat&=&cvCreateMat(pFrame-&height,&pFrame-&width,&CV_32FC1);&&&&&&&&&&&&&&//转化成单通道图像再处理&&&&&&&&&&&&&&&&cvCvtColor(pFrame,&pBkImg,&CV_BGR2GRAY);&//第一帧作为背景了&&&&&&&&&&&&&&&//cvCvtColor(pFrame,&pFrImg,&CV_BGR2GRAY);&//&&&&&&&&&&&&&&&//转换成矩阵&&&&&&&&&&&&&&cvConvert(pBkImg,&pFrameMat);&&//虽然没用,相当于给矩阵赋了初值&&&&&&&&&&&&&&cvConvert(pBkImg,&pFrMat);&&&&&//虽然没用,相当于给矩阵赋了初值&&&&&&&&&&&&&&cvConvert(pBkImg,&pBkMat);&&&&&&&&&&&&}&&&&&&&&&&//如果是第er帧,需要申请内存,并初始化&&&&&&&&&&else&if(nFrmNum==2)&&&&&&&&&&{&&&&&&&&&&&&&&pMiImg&=&cvCreateImage(cvSize(pFrame-&width,&pFrame-&height),&&IPL_DEPTH_8U,1);&&&&&&&&&&&&&&&&pMiMat&=&cvCreateMat(pFrame-&height,&pFrame-&width,&CV_32FC1);&&&&&&&&&&&&&&pRe1Mat&=&cvCreateMat(pFrame-&height,&pFrame-&width,&CV_32FC1);&&&&&&&&&&&&&&pRe2Mat&=&cvCreateMat(pFrame-&height,&pFrame-&width,&CV_32FC1);&&&&&&&&&&&&&&cvCvtColor(pFrame,&pMiImg,&CV_BGR2GRAY);&&&&&&&&&&&&&&cvConvert(pMiImg,&pMiMat);&&&&&&&&&&}&&&&&&&&&&else&&&&&&&&&&&&{&&&&&&&&&&&&&&&&cvCvtColor(pFrame,&pFrImg,&CV_BGR2GRAY);&&&&&&&&&&&&&&&&cvConvert(pFrImg,&pFrameMat);&&&&&&&&&&&&&&&&//高斯滤波先,以平滑图像&&&&&&&&&&&&&&&&//cvSmooth(pFrameMat,&pFrameMat,&CV_GAUSSIAN,&3,&0,&0);&&&&&&&&&&&&&&&&&&&&//当前帧跟背景图相减&计算两个数组差的绝对值&&&&&&&&&&&&&&&cvAbsDiff(pMiMat,&pBkMat,&pRe1Mat);&&&&&&&&&&&&&&cvAbsDiff(pFrameMat,&pMiMat,&pRe2Mat);&&&&&&&&&&&&&&&&cvAnd(pRe1Mat,pRe2Mat,pFrMat,NULL);&&&&&&&&&&&&&&&//二值化前景图&&&&&&&&&&&&&&&&cvThreshold(pFrMat,&pFrImg,&apos,&255.0,&CV_THRESH_BINARY);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&//进行形态学滤波,去掉噪音&&&&&&&&&&&&&&&&&&//cvErode(pFrImg,&pFrImg,&0,&1);&&&&&&&&&&&&&&&&//cvDilate(pFrImg,&pFrImg,&0,&1);&&&&&&&&&&&&&&&&/*cvDilate(pFrImg,&pFrImg,&0,&1);&&&&&&&&&&&&&cvErode(pFrImg,&pFrImg,&0,&1);&&*/&&&&&&&&&&&&&&//更新背景&&&&&&&&&&&&&&&&//cvRunningAvg(pFrameMat,&pBkMat,&0.003,&0);&&&&&&&&&&&&&&&&//将背景转化为图像格式,用以显示&&&&&&&&&&&&&&&&cvConvert(pBkMat,&pBkImg);&&&&&&&&&&&&&&&cvCopy(pMiMat,pBkMat,NULL);&&&&&&&&&&&&&&cvCopy(pFrameMat,pMiMat,NULL);&&&&&&&&&&&&&&//pBkMat=pFrameM&&&&&&&&&&&&&&//显示图像&&&&&&&&&&&&&&&&cvShowImage("video",&pFrame);&&&&&&&&&&&&&&&&cvShowImage("background",&pBkImg);&&&&&&&&&&&&&&&&cvShowImage("foreground",&pFrImg);&&&&&&&&&&&&&&&&&&&&//如果有按键事件,则跳出循环&&&&&&&&&&&&&&&&//此等待也为cvShowImage函数提供时间完成显示&&&&&&&&&&&&&&&&//等待时间可以根据CPU速度调整&&&&&&&&&&&&&&&&if(&cvWaitKey(20)&&=&0&)&&&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&}&&&&&&&&}&&&&&&&&cvWaitKey();&&&&&&&&&&&&//销毁窗口&&&&&&&&cvDestroyWindow("video");&&&&&&&&cvDestroyWindow("background");&&&&&&&&cvDestroyWindow("foreground");&&&&&&&&&&&&//释放图像和矩阵&&&&&&&&cvReleaseImage(&pFrImg);&&&&&&&&cvReleaseImage(&pBkImg);&&&&&&&&cvReleaseImage(&pMiImg);&&&&&&&&cvReleaseMat(&pFrameMat);&&&&&&&&cvReleaseMat(&pFrMat);&&&&&&&&cvReleaseMat(&pBkMat);&&&&&&cvReleaseMat(&pMiMat);&&&&&&&&&&cvReleaseCapture(&pCapture);&&&&&&&&&&&&return&0;&&&&}&&&(2)仿照pc上写的android上的三帧差分程序(有问题):package&com.jack.import&org.opencv.android.BaseLoaderCimport&org.opencv.android.CameraBridgeViewBimport&org.opencv.android.CameraBridgeViewBase.CvCameraViewFimport&org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2;import&org.opencv.android.LoaderCallbackIimport&org.opencv.android.OpenCVLimport&org.opencv.core.Cimport&org.opencv.core.Mimport&org.opencv.core.Pimport&org.opencv.core.Simport&org.opencv.core.Simport&org.opencv.imgproc.Iimport&org.opencv.samples.colorblobdetect.R;import&android.app.Aimport&android.os.Bimport&android.view.SurfaceVimport&android.view.WindowMimport&android.widget.SeekBimport&android.widget.SeekBar.OnSeekBarChangeLpublic&class&DetectionActivity&extends&Activity&implementsCvCameraViewListener2&{private&int&nFrmNum&=&0;//&帧数private&int&nThreshold&=&30;//&阈值private&SeekBar&private&Mat&mRgba,&mGprivate&Mat&pFstMat,&pSecMat,&pThrM//&第一帧、第二帧、第三帧private&Mat&pResMat1,&pResMat2,&pResAnd,&private&Mat&outWprivate&Size&private&CameraBridgeViewBase&mOpenCvCameraVprivate&BaseLoaderCallback&mLoaderCallback&=&new&BaseLoaderCallback(this)&{@Overridepublic&void&onManagerConnected(int&status)&{switch&(status)&{case&LoaderCallbackInterface.SUCCESS:&{mOpenCvCameraView.enableView();}default:&{super.onManagerConnected(status);}}}};@Overridepublic&Mat&onCameraFrame(CvCameraViewFrame&inputFrame)&{nFrmNum++;//&mRgba做为背景图mRgba&=&inputFrame.rgba();Size&sizeRgba&=&mRgba.size();int&rows&=&(int)&sizeRgba.int&cols&=&(int)&sizeRgba.int&left&=&cols&/&8;int&top&=&rows&/&8;int&width&=&cols&*&3&/&4;int&height&=&rows&*&3&/&4;Imgproc.cvtColor(mRgba,&mGray,&Imgproc.COLOR_BGR2GRAY);if&(nFrmNum&==&1)&{pFstMat&=&mG}&else&if&(nFrmNum&==&2)&{pSecMat&=&mG}&else&{pThrMat&=&mG//&三帧差分Core.subtract(pFstMat,&pSecMat,&pResMat1);Core.subtract(pSecMat,&pThrMat,&pResMat2);Core.bitwise_and(pResMat1,&pResMat2,&pResAnd);//&二值化处理Imgproc.threshold(pResAnd,&out,&nThreshold,&255.0,&0);//&更新背景pFstMat&=&pSecMpSecMat&=&pThrM}if&(out.size().height&!=&0)&{outWindow&=&out.submat(top,&top&+&height,&left,&left&+&width);wsize&=&out.size();Imgproc.rectangle(outWindow,&new&Point(1,&1),&new&Point(wsize.width&-&2,&wsize.height&-&2),&new&Scalar(255,&0,&0,255),&20);//&边缘检测Imgproc.Canny(mRgba,&outWindow,&80,&90);Imgproc.cvtColor(outWindow,&mRgba,&Imgproc.COLOR_GRAY2BGRA);}return&mR}@Overridepublic&void&onCameraViewStarted(int&width,&int&height)&{mGray&=&new&Mat();pFstMat&=&new&Mat();pSecMat&=&new&Mat();pThrMat&=&new&Mat();pResMat1&=&new&Mat();pResMat2&=&new&Mat();pResAnd&=&new&Mat();out&=&new&Mat();}@Overrideprotected&void&onCreate(Bundle&savedInstanceState)&{super.onCreate(savedInstanceState);setContentView(R.layout.color_blob_detection_surface_view);getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);mOpenCvCameraView&=&(CameraBridgeViewBase)&findViewById(R.id.color_blob_detection_activity_surface_view);mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);mOpenCvCameraView.setCvCameraViewListener(this);thrsh&=&(SeekBar)&findViewById(R.id.threshold1);thrsh.setOnSeekBarChangeListener(new&OnSeekBarChangeListener()&{@Overridepublic&void&onStopTrackingTouch(SeekBar&arg0)&{}@Overridepublic&void&onStartTrackingTouch(SeekBar&arg0)&{}@Overridepublic&void&onProgressChanged(SeekBar&arg0,&int&progress,boolean&arg2)&{nThreshold&=&}});}public&void&onResume()&{super.onResume();OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3,&this,mLoaderCallback);};@Overridepublic&void&onCameraViewStopped()&{}}布局文件:&&&&&org.opencv.android.JavaCameraView&&&&&&&&android:id="@+id/color_blob_detection_activity_surface_view"&&&&&&&&android:layout_width="fill_parent"&&&&&&&&android:layout_height="500dp"&&&&&&&/org.opencv.android.JavaCameraView&&&&&&LinearLayout&&&&&&&&android:layout_width="fill_parent"&&&&&&&&android:layout_height="131dp"&&&&&&&&android:orientation="vertical"&&&&&&&&&&&SeekBar&&&&&&&&&&&&android:id="@+id/threshold1"&&&&&&&&&&&&android:layout_width="fill_parent"&&&&&&&&&&&&android:layout_height="fill_parent"&&&&&&&&&&&&android:max="255"&&&&&&&&&&&&android:progress="30"&/&&&&&&/LinearLayout&,具体解决方案如下:解决方案1:字数限制,布局文件没有写全,现在补上&LinearLayout&xmlns:android="//apk/res/android"&&&&xmlns:tools="//tools"&&&&android:layout_width="fill_parent"&&&&android:layout_height="fill_parent"&&&&android:background="#ADADAD"&&&&android:orientation="vertical"&&&&&&&org.opencv.android.JavaCameraView&&&&&&&&android:id="@+id/color_blob_detection_activity_surface_view"&&&&&&&&android:layout_width="fill_parent"&&&&&&&&android:layout_height="500dp"&&&&&&&/org.opencv.android.JavaCameraView&&&&&&LinearLayout&&&&&&&&android:layout_width="fill_parent"&&&&&&&&android:layout_height="131dp"&&&&&&&&android:orientation="vertical"&&&&&&&&&&&SeekBar&&&&&&&&&&&&android:id="@+id/threshold1"&&&&&&&&&&&&android:layout_width="fill_parent"&&&&&&&&&&&&android:layout_height="fill_parent"&&&&&&&&&&&&android:max="255"&&&&&&&&&&&&android:progress="30"&/&&&&&&/LinearLayout&&/LinearLayout&解决方案2:太长了,没时间全看过来,关键要看矩阵里有没有值。解决方案3:为什么不直接将您的&c++/c&&代码&采用&jni&ndk&开发方式实现在Android中呢?解决方案4:博主最后是怎么解决的???我也遇到同样的问题解决方案5:额,我最后用的是背景差分法,没用三帧差分法。解决方案6:引用&4&楼&k97923&的回复:博主最后是怎么解决的???我也遇到同样的问题我最后用的是背景差分法,做腐蚀膨胀来实现的。没用三帧差分法。
1个回答1个回答1个回答1个回答1个回答1个回答1个回答1个回答1个回答1个回答
相关文章:
OpenCV4Android开发环境搭建两种方式加上图像二值化
1.环境搭建
进行android开发所需要的环境一般为:eclipse + android sdk + ADT,而OpenCV的开发由于需要编写本地代码(C/C++),因此还需要***以下工具:NDK,Cygwin,CDT。网上都有大量详细的***讲解,本文只描述下其中关键步骤。
1.1 NDK的***
(1) NDK下载后解压到固定目录即可,无需***。本文解压到D盘根目录下,其路径为:D:\android-ndk-r8d;
(2) 添加环境变量,将其***路径添加到系统path变量中,并添加系统变量NDKROOT:D:\android-ndk-r8d。
1.2 Cygwin的***
(1) ***包当然可以选择全部,只是如此以来则比较耗时。你也可以只***开发NDK用得着的包:autoconf2.1、automake1.10、binutils、gcc-core、gcc-g++、gcc4-core、gcc4-g++、gdb、pcre、pcre-devel、gawk、make;
(2) 将***路径添加系统变量path中;
(3) 为了方便的在命令行下调用Android NDK,找到&C:\cygwin\home\(你的用户名)&这个目录,打开文件&.bash_profile&,在文件的最下面加上下面两行内容:
NDK=/cygdrive/f/android-ndk-r6b-windows/android-ndk-r6b
export NDK
1.3 CDT的***
,找到对应的repository地址,注意这个地址对应的Eclipse版本要与第二步中你下载的版本一致。接着,打开Eclipse软件Help-&Install New Software菜单***即可。
2.OpenCV4Android
进入官网(
)下载OpenCV4Android并解压,其目录结构如下:
图1 OpenCV-2.4.3.2-android-sdk目录结构
其中,sdk目录即是我们开发
所需要的类库;samples目录中存放着若干opencv应用示例(包括人脸检测等),可为我们进行android下的opencv开发提供参考;doc目录为opencv类库的使用说明及api文档等;而apk目录则存放着对应于各内核版本的OpenCV_2.4.3.2_Manager_2.4应用***包。此应用用来管理手机设备中的opencv类库,在运行opencv应用之前,必须确保手机中已经***了OpenCV_2.4.3.2_Manager_2.4_*.apk,否则opencv应用将会因为无法加载opencv类库而无法运行。
2.2 将SDK引入工作空间
(1) 选择一个路径,新建文件夹做为工作空间(我在E盘根目录下新建workspace目录来做为工作空间);
(2) 将OpenCV-2.4.3.2-android-sdk中的sdk目录copy至工作空间,并将其更名为OpenCV-SDK(是否更改名称无所谓,这是我个人习惯而已);
(3) 以新建的目录为工作空间,打开eclipse;
(4) 将OpenCV-SDK引入到工作空间中,如下图所示:
3&开发实例
在经过上述的环境配置之后,就可以进行opencv开发了。如
所述,android中opencv的开发有两种方式:直接调用opencv中的java api;利用JNI编写C++ OpenCV代码,通过Android NDK创建动态库。本文分别利用这两种方式实现图像的灰度处理操作。
3.1 工程一:通过调用OpenCV提供的java api实现灰度处理
3.1.1 创建工程
(1) 打开eclipse,创建android应用工程GrayProcess;
(2) 将测试图像lena.jpg添加到资源目录res/drawable-hdpi中;
(3) 在Package Explorer中选择项目GrayProcess,单击右键在弹出菜单中选择Properties,然后在弹出的Properties窗口中左侧选择Android,然后点击右下方的Add按钮,选择OpenCV Library 2.4.3并点击OK,操作完成后,会将OpenCV类库添加到GrayProcess的Android Dependencies中,如下图所示:
3.1.2&工程代码
(1) 字符串资源文件:strings.xml
&resources&&&
&&&&&string&name=&app_name&&GrayProcess&/string&&&
&&&&&string&name=&hello_world&&Hello&world!&/string&&&
&&&&&string&name=&menu_settings&&Settings&/string&&&
&&&&&string&name=&title_activity_main&&MainActivity&/string&&&
&&&&&string&name=&str_proc&&gray&process&/string&&&
&&&&&string&name=&str_desc&&image&description&/string&&&
&/resources&&&
(2) 布局文件:main.xml
&LinearLayout&xmlns:android=&/apk/res/android&&&
&&&&xmlns:tools=&/tools&&&
&&&&android:orientation=&vertical&&&
&&&&android:layout_width=&match_parent&&&
&&&&android:layout_height=&match_parent&&&&&
&&&&&Button&&&
&&&&&&&&android:id=&@+id/btn_gray_process&&&
&&&&&&&&android:layout_width=&fill_parent&&&
&&&&&&&&android:layout_height=&wrap_content&&&
&&&&&&&&android:text=&@string/str_proc&/&&&
&&&&&ImageView&&
&&&&&&&&android:id=&@+id/image_view&&&
&&&&&&&&android:layout_width=&wrap_content&&&
&&&&&&&&android:layout_height=&wrap_content&&&
&&&&&&&&android:contentDescription=&@string/str_proc&/&&&
&/LinearLayout&&&
(3) MainActivity.java
package&com.iron.&&
import&org.opencv.android.BaseLoaderC&&
import&org.opencv.android.LoaderCallbackI&&
import&org.opencv.android.OpenCVL&&
import&org.opencv.android.U&&
import&org.opencv.core.M&&
import&org.opencv.imgproc.I&&
import&android.os.B&&
import&android.app.A&&
import&android.graphics.B&&
import&android.graphics.BitmapF&&
import&android.graphics.Bitmap.C&&
import&android.view.V&&
import&android.view.View.OnClickL&&
import&android.widget.B&&
import&android.widget.ImageV&&
public&class&MainActivity&extends&Activity&implements&OnClickListener{&&
&&&&private&Button&btnP&&
&&&&private&ImageView&imageV&&
&&&&private&Bitmap&&&
&&&&//OpenCV类库加载并初始化成功后的回调函数,在此我们不进行任何操作&&
&&&&private&BaseLoaderCallback&&mLoaderCallback&=&new&BaseLoaderCallback(this)&{&&
&&&&&&&&@Override&&
&&&&&&&&public&void&onManagerConnected(int&status)&{&&
&&&&&&&&&&&&switch&(status)&{&&
&&&&&&&&&&&&&&&&case&LoaderCallbackInterface.SUCCESS:{&&
&&&&&&&&&&&&&&&&}&&&
&&&&&&&&&&&&&&&&default:{&&
&&&&&&&&&&&&&&&&&&&&super.onManagerConnected(status);&&
&&&&&&&&&&&&&&&&}&&&
&&&&&&&&&&&&}&&
&&&&&&&&}&&
&&&&@Override&&
&&&&public&void&onCreate(Bundle&savedInstanceState)&{&&
&&&&&&&&super.onCreate(savedInstanceState);&&
&&&&&&&&setContentView(R.layout.main);&&
&&&&&&&&btnProc&=&(Button)&findViewById(R.id.btn_gray_process);&&
&&&&&&&&imageView&=&(ImageView)&findViewById(R.id.image_view);&&
&&&&&&&&//将lena图像加载程序中并进行显示&&
&&&&&&&&bmp&=&BitmapFactory.decodeResource(getResources(),&R.drawable.lena);&&
&&&&&&&&imageView.setImageBitmap(bmp);&&
&&&&&&&&btnProc.setOnClickListener(this);&&
&&&&@Override&&
&&&&public&void&onClick(View&v)&{&&
&&&&&&&&Mat&rgbMat&=&new&Mat();&&
&&&&&&&&Mat&grayMat&=&new&Mat();&&
&&&&&&&&//获取lena彩色图像所对应的像素数据&&
&&&&&&&&Utils.bitmapToMat(bmp,&rgbMat);&&
&&&&&&&&//将彩色图像数据转换为灰度图像数据并存储到grayMat中&&
&&&&&&&&Imgproc.cvtColor(rgbMat,&grayMat,&Imgproc.COLOR_RGB2GRAY);&&
&&&&&&&&//创建一个灰度图像&&
&&&&&&&&Bitmap&grayBmp&=&Bitmap.createBitmap(bmp.getWidth(),&bmp.getHeight(),&Config.RGB_565);&&
&&&&&&&&//将矩阵grayMat转换为灰度图像&&
&&&&&&&&Utils.matToBitmap(grayMat,&grayBmp);&&
&&&&&&&&imageView.setImageBitmap(grayBmp);&&
&&&&@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_3,&this,&mLoaderCallback);&&
3.1.3 运行结果
3.2&工程二:利用JNI编写C++ OpenCV代码实现灰度处理
3.2.1 创建工程
步骤如工程一,创建新工程GrayProcess2,将lena.jpg添加到资源文件,并按3.1.1所示将opencv类库添加到工程中。
3.2.2 编写上层代码(java)
(1) res/values/strings.xml
&resources&&&
&&&&&string&name=&app_name&&GrayProcess2&/string&&&
&&&&&string&name=&hello_world&&Hello&world!&/string&&&
&&&&&string&name=&menu_settings&&Settings&/string&&&
&&&&&string&name=&title_activity_main&&GrayProcess2&/string&&&
&&&&&string&name=&str_proc&&gray&process&/string&&&
&&&&&string&name=&str_desc&&image&description&/string&&&
&/resources&&&
(2) res/layout/main.xml
&LinearLayout&xmlns:android=&/apk/res/android&&&
&&&&xmlns:tools=&/tools&&&
&&&&android:orientation=&vertical&&&
&&&&android:layout_width=&match_parent&&&
&&&&android:layout_height=&match_parent&&&&&
&&&&&Button&&&
&&&&&&&&android:id=&@+id/btn_gray_process&&&
&&&&&&&&android:layout_width=&fill_parent&&&
&&&&&&&&android:layout_height=&wrap_content&&&
&&&&&&&&android:text=&@string/str_proc&/&&&
&&&&&ImageView&&
&&&&&&&&android:id=&@+id/image_view&&&
&&&&&&&&android:layout_width=&wrap_content&&&
&&&&&&&&android:layout_height=&wrap_content&&&
&&&&&&&&android:contentDescription=&@string/str_proc&/&&&
&/LinearLayout&&&
(3)MainActivity.java
package&com.iron.grayprocess2;&&
import&org.opencv.android.BaseLoaderC&&
import&org.opencv.android.LoaderCallbackI&&
import&org.opencv.android.OpenCVL&&
import&android.os.B&&
import&android.app.A&&
import&android.graphics.B&&
import&android.graphics.BitmapF&&
import&android.graphics.Bitmap.C&&
import&android.view.V&&
import&android.view.View.OnClickL&&
import&android.widget.B&&
import&android.widget.ImageV&&
public&class&MainActivity&extends&Activity&implements&OnClickListener{&&
&&&&private&Button&btnP&&
&&&&private&ImageView&imageV&&
&&&&private&Bitmap&&&
&&&&//OpenCV类库加载并初始化成功后的回调函数,在此我们不进行任何操作&&
&&&&&private&BaseLoaderCallback&&mLoaderCallback&=&new&BaseLoaderCallback(this)&{&&
&&&&&&&&@Override&&
&&&&&&&&public&void&onManagerConnected(int&status)&{&&
&&&&&&&&&&&&switch&(status)&{&&
&&&&&&&&&&&&&&&&case&LoaderCallbackInterface.SUCCESS:{&&
&&&&&&&&&&&&&&&&&&&&System.loadLibrary(&image_proc&);&&
&&&&&&&&&&&&&&&&}&&&
&&&&&&&&&&&&&&&&default:{&&
&&&&&&&&&&&&&&&&&&&&super.onManagerConnected(status);&&
&&&&&&&&&&&&&&&&}&&&
&&&&&&&&&&&&}&&
&&&&&&&&}&&
&&&&@Override&&
&&&&public&void&onCreate(Bundle&savedInstanceState)&{&&
&&&&&&&&super.onCreate(savedInstanceState);&&
&&&&&&&&setContentView(R.layout.main);&&
&&&&&&&&btnProc&=&(Button)&findViewById(R.id.btn_gray_process);&&
&&&&&&&&imageView&=&(ImageView)&findViewById(R.id.image_view);&&
&&&&&&&&//将lena图像加载程序中并进行显示&&
&&&&&&&&&bmp&=&BitmapFactory.decodeResource(getResources(),&R.drawable.lena);&&
&&&&&&&&imageView.setImageBitmap(bmp);&&
&&&&&&&&btnProc.setOnClickListener(this);&&
&&&&@Override&&
&&&&public&void&onClick(View&v)&{&&
&&&&&&&&&&&
&&&&&&&&int&w&=&bmp.getWidth();&&
&&&&&&&&int&h&=&bmp.getHeight();&&
&&&&&&&&int[]&pixels&=&new&int[w*h];&&&&&&&
&&&&&&&&bmp.getPixels(pixels,&0,&w,&0,&0,&w,&h);&&
&&&&&&&&int[]&resultInt&=&ImageProc.grayProc(pixels,&w,&h);&&
&&&&&&&&Bitmap&resultImg&=&Bitmap.createBitmap(w,&h,&Config.ARGB_8888);&&
&&&&&&&&resultImg.setPixels(resultInt,&0,&w,&0,&0,&w,&h);&&
&&&&&&&&imageView.setImageBitmap(resultImg);&&&&&&
&&&&@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_3,&this,&mLoaderCallback);&&
代码第28行:System.loadLibrary(&image_proc&)用来当OpenCV类库初始化完成后加载类库image_proc。此类库由我们来生成,用于完成图像灰度处理的操作,此部分将在3.2.3中说明。
(4) ImageProc.java
package&com.iron.grayprocess2;&&
public&class&ImageProc&{&&
&&&&public&static&native&int[]&grayProc(int[]&pixels,&int&w,&int&h);&&
ImageProc.java中只定义了方法grayProc,关键字native表明,此方法的实现由本地代码(C/C++)来完成。
3.2.3 编写JNI及C相关代码
在项目中新建目录jni,在jni目录中分别添加文件Android.mk,Application.mk,ImageProc.h,ImageProc.cpp,这四个文件的内容分别如下所示。
(1) Android.mk
LOCAL_PATH&:=&$(call&my-dir)&&
include&$(CLEAR_VARS)&&
include&../OpenCV-SDK/native/jni/OpenCV.mk&&
LOCAL_SRC_FILES&&:=&ImageProc.cpp&&
LOCAL_MODULE&&&&&:=&image_proc&&
include&$(BUILD_SHARED_LIBRARY)&&
代码说明:
第一行:指明当前编译路径;
第二行:清空变量;
第三行:将OpenCV类库中的编译文件包含进来,如此一来在我们的工程中即可使用OpenCV类库;
第四行:指定需要编译的C++源文件;
第五行:指定编译生成的类库名称;
第六行:调用命令将源文件编译为静态库。
注:第三行指定的路径很关键,当opencv类库与工程路径相关位置发生改变时,此路径也要随之改变。
(2) Application.mk(配置文件)
APP_STL&:=&gnustl_static&&
APP_CPPFLAGS&:=&-frtti&-fexceptions&&
APP_ABI&:=&armeabi-v7a&&
APP_PLATFORM&:=&android-8&&
(3) ImageProc.h
#include&&jni.h&&&
extern&&C&&{&&
JNIEXPORT&jintArray&JNICALL&Java_com_iron_grayprocess2_ImageProc_grayProc&&
&&(JNIEnv&*,&jclass,&jintArray,&jint,&jint);&&
(4) ImageProc.cpp
#include&&ImageProc.h&&&
#include&&opencv2/core/core.hpp&&&
#include&&string&&&
#include&&vector&&&
using&namespace&&&
using&namespace&&&
JNIEXPORT&jintArray&JNICALL&Java_com_iron_grayprocess2_ImageProc_grayProc(JNIEnv*&env,&jclass&obj,&jintArray&buf,&jint&w,&jint&h){&&
&&&&jint&*&&
&&&&cbuf&=&env-&GetIntArrayElements(buf,&false);&&
&&&&if(cbuf&==&NULL){&&
&&&&&&&&return&0;&&
&&&&Mat&imgData(h,&w,&CV_8UC4,&(unsigned&char*)cbuf);&&
&&&&uchar*&ptr&=&imgData.ptr(0);&&
&&&&for(int&i&=&0;&i&&&w*h;&i&++){&&
&&&&&&&&//计算公式:Y(亮度)&=&0.299*R&+&0.587*G&+&0.114*B&&
&&&&&&&&//对于一个int四字节,其彩色值存储方式为:BGRA&&
&&&&&&&&int&grayScale&=&(int)(ptr[4*i+2]*0.299&+&ptr[4*i+1]*0.587&+&ptr[4*i+0]*0.114);&&
&&&&&&&&ptr[4*i+1]&=&grayS&&
&&&&&&&&ptr[4*i+2]&=&grayS&&
&&&&&&&&ptr[4*i+0]&=&grayS&&
&&&&int&size=w&*&h;&&
&&&&jintArray&result&=&env-&NewIntArray(size);&&
&&&&env-&SetIntArrayRegion(result,&0,&size,&cbuf);&&
&&&&env-&ReleaseIntArrayElements(buf,&cbuf,&0);&&
&&&&return&&&
3.2.4 运行
由于程序中涉及到了JNI编程,因此需要用cygwin对其中的C/C++代码进行编译。打开cygwin,进入到工程的根目录中执行命令:$NDK/ndk-build完成相关编译;之后在eclipse中刷新工程GrayProcess2,运行即可。编译及运行结果分别如下所示。
图10 使用cygwin对C代码进行编译
图11 程序运行结果图对比
已发表评论数()
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
主题不准确
没有分页内容
图片无法显示
视频无法显示
与原文不一致

参考资料

 

随机推荐