我js获取手机设备型号号被封怎么解决啊!跪求解答!谢谢!

学习OpenCV范例(二十四)
1403人阅读
最近导师没给什么项目做,所以有那么一点点小时间,于是就研究起了前景检测,既然前景检测有很多种算法,那干脆就把这些模型都学起来吧,以后用到前景检测时至少还有那么几种方法可以选择,上次介绍的是GMM模型,其实GMM模型本身就是一个很不错的模型,现在也很多人在研究,并且做改进,主要是OpenCV有函数调用,用起来非常方便,当我们都在兴高采烈的讨论GMM各种好的时候,B哥不爽了,他说老子是搞前景检测的,怎么可能让你们这么嚣张,而且老子就不按照你那套路来,什么高斯模型,混合高斯模型,我统统不用,就来个简单的,气死你们,于是一挥笔,一篇著作就出来了ViBe:
A Universal Background Subtraction&Algorithm for Video Sequences,顿时震惊了所有人,现在就让我们一起来领略一下ViBe算法到底有什么过人之处吧。
一讲到原理,本人就喜欢推荐其他博主的博客,因为我觉得他们都已经写得非常好了,好资源就是要被传播,被共享的,所以对于原理的问题,我一样推荐一个博客给大家。
这篇文章可以说是ViBe原文的精华版,对这个算法的理论基础和精髓理解的非常透彻,甚至连实验对比结果和效果图都给大家贴出来了,都是原文的图片。
也希望大家看完这篇精华版之后,有初步了解之后可以去看一下原文,原文第一部分概述了各种各样的前景检测算法,第二部分开始讲ViBe,其中作者说了一句,背景减法技术一般都要解决三个问题:1、用到什么模型,并且它的工作原理,2、如何初始化这个模型,3、随着时间的推移,如何更新这个模型,于是作者也就从这三个方面介绍了ViBe算法,最后一部分就是各种实验结果和对比。
接下来给大家推荐一个代码版本,现在的OpenCV也有ViBe库函数提供,但是是在CUDA平台下的。
这位博主主要的代码都是用到OpenCV的Mat格式存储数据和调用数据,所以速度有点慢,于是本人做了小小的修改,快了些许,代码会在下面贴出。
同样也贴出另外一位博主的代码,没仔细看,希望有空可以研究一下
2、代码实现
[cpp] #include&&iostream&&&#include&"opencv2/opencv.hpp"&&&&using&namespace&&&using&namespace&&&&&#define&NUM_SAMPLES&20&&&&&&//每个像素点的样本个数&&#define&MIN_MATCHES&2&&&&&&&//#min指数&&#define&RADIUS&20&&&&&&&//Sqthere半径&&#define&SUBSAMPLE_FACTOR&16&//子采样概率&&&&&&class&ViBe_BGS&&{&&public:&&&&&&ViBe_BGS(void);&&&&&&~ViBe_BGS(void);&&&&&&&&void&init(const&Mat&_image);&&&//初始化&&&&&&void&processFirstFrame(const&Mat&_image);&&&&&&void&testAndUpdate(const&Mat&_image);&&//更新&&&&&&Mat&getMask(void){return&m_};&&&&&&void&deleteSamples(){delete&};&&&&private:&&&&&&unsigned&char&***&&//&&float&samples[][NUM_SAMPLES+1];//保存每个像素点的样本值&&&&/*&&&&&Mat&m_samples[NUM_SAMPLES];&&&&&Mat&m_foregroundMatchC*/&&&&&&&&Mat&m_&&};&&
[cpp] #include&"ViBe.h"&&&&using&namespace&&&using&namespace&&&&&int&c_xoff[9]&=&{-1,&&0,&&1,&-1,&1,&-1,&0,&1,&0};&&//x的邻居点&&int&c_yoff[9]&=&{-1,&&0,&&1,&-1,&1,&-1,&0,&1,&0};&&//y的邻居点&&&&ViBe_BGS::ViBe_BGS(void)&&{&&&&}&&ViBe_BGS::~ViBe_BGS(void)&&{&&&&}&&&&/****************&Assign&space&and&init&***************************/&&void&ViBe_BGS::init(const&Mat&_image)&&{&&&&&&//动态分配三维数组,samples[][][NUM_SAMPLES]存储前景被连续检测的次数&&&&&&samples=new&unsigned&char&**[_image.rows];&&&&&&for&(int&i=0;i&_image.i++)&&&&&&{&&&&&&&&&&samples[i]=new&unsigned&char&*[1024];&&&&&&&&&&for&(int&j=0;j&_image.j++)&&&&&&&&&&{&&&&&&&&&&&&&&samples[i][j]=new&unsigned&char&[NUM_SAMPLES+1];&&&&&&&&&&&&&&&&&&for&(int&k=0;k&NUM_SAMPLES+1;k++)&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&samples[i][j][k]=0;&&&&&&&&&&&&&&}&&&&&&&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&&&}&&&&&&m_mask&=&Mat::zeros(_image.size(),CV_8UC1);&&}&&&&/****************&Init&model&from&first&frame&********************/&&void&ViBe_BGS::processFirstFrame(const&Mat&_image)&&{&&&&&&RNG&&&&&&&int&row,&&&&&&&&&for(int&i&=&0;&i&&&_image.&i++)&&&&&&{&&&&&&&&&&for(int&j&=&0;&j&&&_image.&j++)&&&&&&&&&&{&&&&&&&&&&&&&&for(int&k&=&0&;&k&&&NUM_SAMPLES;&k++)&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&//&Random&pick&up&NUM_SAMPLES&pixel&in&neighbourhood&to&construct&the&model&&&&&&&&&&&&&&&&&&int&random&=&rng.uniform(0,&9);&&&&&&&&&&&&&&&&&&&&row&=&i&+&c_yoff[random];&&&&&&&&&&&&&&&&&&if&(row&&&0)&&&&&&&&&&&&&&&&&&&&&&&row&=&0;&&&&&&&&&&&&&&&&&&if&(row&&=&_image.rows)&&&&&&&&&&&&&&&&&&&&&&row&=&_image.rows&-&1;&&&&&&&&&&&&&&&&&&&&col&=&j&+&c_xoff[random];&&&&&&&&&&&&&&&&&&if&(col&&&0)&&&&&&&&&&&&&&&&&&&&&&&col&=&0;&&&&&&&&&&&&&&&&&&if&(col&&=&_image.cols)&&&&&&&&&&&&&&&&&&&&&&col&=&_image.cols&-&1;&&&&&&&&&&&&&&&&&&&&samples[i][j][k]=_image.at&uchar&(row,&col);&&&&&&&&&&&&&&}&&&&&&&&&&}&&&&&&}&&}&&&&/****************&Test&a&new&frame&and&update&model&********************/&&void&ViBe_BGS::testAndUpdate(const&Mat&_image)&&{&&&&&&RNG&&&&&&&&&for(int&i&=&0;&i&&&_image.&i++)&&&&&&{&&&&&&&&&&for(int&j&=&0;&j&&&_image.&j++)&&&&&&&&&&{&&&&&&&&&&&&&&int&matches(0),&count(0);&&&&&&&&&&&&&&int&&&&&&&&&&&&&&&&&while(matches&&&MIN_MATCHES&&&&count&&&NUM_SAMPLES)&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&dist&=&abs(samples[i][j][count]&-&_image.at&uchar&(i,&j));&&&&&&&&&&&&&&&&&&if&(dist&&&RADIUS)&&&&&&&&&&&&&&&&&&&&&&matches++;&&&&&&&&&&&&&&&&&&count++;&&&&&&&&&&&&&&}&&&&&&&&&&&&&&&&if&(matches&&=&MIN_MATCHES)&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&//&It&is&a&background&pixel&&&&&&&&&&&&&&&&&&samples[i][j][NUM_SAMPLES]=0;&&&&&&&&&&&&&&&&&&&&//&Set&background&pixel&to&0&&&&&&&&&&&&&&&&&&m_mask.at&uchar&(i,&j)&=&0;&&&&&&&&&&&&&&&&&&&&//&如果一个像素是背景点,那么它有&1&/&defaultSubsamplingFactor&的概率去更新自己的模型样本值&&&&&&&&&&&&&&&&&&int&random&=&rng.uniform(0,&SUBSAMPLE_FACTOR);&&&&&&&&&&&&&&&&&&if&(random&==&0)&&&&&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&&random&=&rng.uniform(0,&NUM_SAMPLES);&&&&&&&&&&&&&&&&&&&&&&samples[i][j][random]=_image.at&uchar&(i,&j);&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&&&&&&&//&同时也有&1&/&defaultSubsamplingFactor&的概率去更新它的邻居点的模型样本值&&&&&&&&&&&&&&&&&&random&=&rng.uniform(0,&SUBSAMPLE_FACTOR);&&&&&&&&&&&&&&&&&&if&(random&==&0)&&&&&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&&int&row,&&&&&&&&&&&&&&&&&&&&&&&random&=&rng.uniform(0,&9);&&&&&&&&&&&&&&&&&&&&&&row&=&i&+&c_yoff[random];&&&&&&&&&&&&&&&&&&&&&&if&(row&&&0)&&&&&&&&&&&&&&&&&&&&&&&&&&&row&=&0;&&&&&&&&&&&&&&&&&&&&&&if&(row&&=&_image.rows)&&&&&&&&&&&&&&&&&&&&&&&&&&row&=&_image.rows&-&1;&&&&&&&&&&&&&&&&&&&&&&&&random&=&rng.uniform(0,&9);&&&&&&&&&&&&&&&&&&&&&&col&=&j&+&c_xoff[random];&&&&&&&&&&&&&&&&&&&&&&if&(col&&&0)&&&&&&&&&&&&&&&&&&&&&&&&&&&col&=&0;&&&&&&&&&&&&&&&&&&&&&&if&(col&&=&_image.cols)&&&&&&&&&&&&&&&&&&&&&&&&&&col&=&_image.cols&-&1;&&&&&&&&&&&&&&&&&&&&&&&&random&=&rng.uniform(0,&NUM_SAMPLES);&&&&&&&&&&&&&&&&&&&&&&samples[i][j][random]=_image.at&uchar&(i,&j);&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&}&&&&&&&&&&&&&&else&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&//&It&is&a&foreground&pixel&&&&&&&&&&&&&&&&&&samples[i][j][NUM_SAMPLES]++;&&&&&&&&&&&&&&&&&&&&//&Set&background&pixel&to&255&&&&&&&&&&&&&&&&&&m_mask.at&uchar&(i,&j)&=&255;&&&&&&&&&&&&&&&&&&&&//如果某个像素点连续N次被检测为前景,则认为一块静止区域被误判为运动,将其更新为背景点&&&&&&&&&&&&&&&&&&if(samples[i][j][NUM_SAMPLES]&50)&&&&&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&&int&random&=&rng.uniform(0,&NUM_SAMPLES);&&&&&&&&&&&&&&&&&&&&&&if&(random&==&0)&&&&&&&&&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&&&&&&random&=&rng.uniform(0,&NUM_SAMPLES);&&&&&&&&&&&&&&&&&&&&&&&&&&samples[i][j][random]=_image.at&uchar&(i,&j);&&&&&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&}&&&&&&&&&&}&&&&&&}&&}&&
[cpp] #include&"ViBe.h"&&#include&&cstdio&&&&&using&namespace&&&using&namespace&&&&&int&main(int&argc,&char*&argv[])&&{&&&&&&Mat&frame,&gray,&&&&&&&VideoCapture&&&&&&&capture.open(0);&&&&&&capture.set(CV_CAP_PROP_FRAME_WIDTH,320);&&&&&&capture.set(CV_CAP_PROP_FRAME_HEIGHT,240);&&&&&&if&(!capture.isOpened())&&&&&&{&&&&&&&&&&cout&&"No&camera&or&video&input!\n"&&&&&&&&&&&&return&-1;&&&&&&}&&&&&&&&ViBe_BGS&Vibe_B&&&&&&bool&count&=&&&&&&&&while&(1)&&&&&&{&&&&&&&&&&capture&&&&&&&&&&&&&&if&(frame.empty())&&&&&&&&&&&&&&&&&&&&&&&&&&cvtColor(frame,&gray,&CV_RGB2GRAY);&&&&&&&&&&if&(count)&&&&&&&&&&{&&&&&&&&&&&&&&Vibe_Bgs.init(gray);&&&&&&&&&&&&&&Vibe_Bgs.processFirstFrame(gray);&&&&&&&&&&&&&&cout&&"&Training&ViBe&complete!"&&&&&&&&&&&&&&&&count=&&&&&&&&&&}&&&&&&&&&&else&&&&&&&&&&{&&&&&&&&&&&&&&Vibe_Bgs.testAndUpdate(gray);&&&&&&&&&&&&&&mask&=&Vibe_Bgs.getMask();&&&&&&&&&&&&&&morphologyEx(mask,&mask,&MORPH_OPEN,&Mat());&&&&&&&&&&&&&&imshow("mask",&mask);&&&&&&&&&&}&&&&&&&&&&&&&&imshow("input",&frame);&&&&&&&&&&&&&if&(&cvWaitKey(10)&==&27&)&&&&&&&&&&&&&&&&&&&&}&&&&&&&&return&0;&&}&&
3、实验结果
& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & 图1、背景图
& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & &图2、前景图
总结,这里就不再贴太多图出来了,大家可以下载代码自己去玩一玩,挺好玩的,这个算法在作者的论文中被说得各种好,各种极品,但是在我的电脑中没有体现那么神乎其神的效果,可能没有加上其他的一些预处理和后处理的缘故吧,也可能是电脑问题,但是总体来说,这个算法确实也不错,算法原理也容易理解,对Ghost区域也做了很好的处理,但是算法已经申请了专利,做做研究还是可以的,还是有很多发展空间,如果商用,那我就不知道会咋样咯。
版权声明:本文为博主原创文章,未经博主允许不得转载。
楼主,能不能把源码包发我一下,最近在做这方面的毕设,谢谢~
您还没有登录,请或
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:52965次
排名:千里之外
原创:38篇
转载:23篇
(3)(6)(12)(1)(4)展开
例子举得不错。。。
额,写的不错,清晰明了。。。
您好!我最近在学习您的《图像显著性论文(三)—Frequency-tuned S...
楼主,能不能把源码包发我一下,最近在做这方面的毕设,谢谢~
@melodyyoung:不好意思,最近很少上博客,所以耽误了你的问题,你问题解决没?是不是下载的时...
博主你好。我运行代码有错误,提示无法打开dirent.h。请问如何解决呢?
写的非常好生动形象,又很全面!太好了!
|||||||||400-600-2320|北京创新乐知信息技术有限公司 版权所有|江苏乐知网络技术有限公司 提供商务支持京&ICP&证&070598&号|Copyright ? , CSDN.NET, All Rights Reserved&
TA的最新馆藏android studio 使用 jni 编译 opencv 完整实例 之 图像边缘检测!从此在andrid中自由使用 图像匹... - 推酷
android studio 使用 jni 编译 opencv 完整实例 之 图像边缘检测!从此在andrid中自由使用 图像匹...
1,过程感慨;
2,运行环境;
3,准备工作;
4,编译 .so
5,遇到的关键问题及其解决方法
6,实现效果截图。
------------------------------------------------------------------------
(原创:转载声明出处:/linguanh/)
1,过程感慨(想直接看教程,请跳过此部分)
在写具体内容之前,我先说下我搞这个东西的过程,由于导师之前说过要搞个图像匹配的androi APP,具体就是匹配前后两张图片的相似度,类似 安卓5.0 引入的刷脸解锁。
当时觉得,要实现这样一个东西,肯定没现成的API 可供使用,第一时间想到的 无疑就是opencv,这个拥有一套强大的图像处理函数的库,它的开发语言主要是C++,但是,也有 jar 包可供android开发使用,如果单单是使用里面已经写好了的效果的话,肯定是不能完成图像匹配的。
也就是说,我必须要调用它里面的函数再结合自己算法重新去实现这样一个功能,再使用 ndk 环境去实现 jni 编程,把我自己写好的 c++ 代码,在生成 .so 动态库的基础上,引入并使用。
刚开始,思路很清晰,然后便着手百度 android studio(下面简称 as) 的 opencv jni编程使用教程,十分遗憾,所能搜到的,关于 as 和 opencv、jni 搭边的例子 几乎为0,很多的例子是 eclipse。没办法,只有自己亲手搞了。
刚动手的时候,很快地把所有装备工作都搞定了,.so 动态库文件(下面会介绍)也编译出来了,但是,就在此时,我遇到了一个 令我第一阶段切底放弃的 bug!!
这个 bug 是:(下面我会说明白,它的真实起因和解决方法)
fatal error: opencv2/opencv.hpp: No such file or directory , 意思是 我所要编译的 cpp文件中的 头文件&opencv2/opencv.hpp 找不到。 当时,无论是自己请教别人、百度、google 还是查书,都无法解决,足足耗时 一星期!!
逐保留项目信息,放弃不搞。
直到 2 天前,开始决定重新尝试,并于今天正式解决后,现发表此文。
2,运行环境
win 7, 系统;
android studio 版本 0.8.0 beta,使用 &build:gradle:0.12.+,tools版本:21.1.2,api 21;
opencv for android 包,我使用的版本是&OpenCV-3.0.0-android-sdk,2.4.9的也可以,可以到 opencv 官网下载,我这里提供个链接
http://downloads.sourceforge.net/project/opencvlibrary/opencv-android/3.0.0/OpenCV-3.0.0-android-sdk-1.zip?r=http%3A%2F%2Fopencv.org%2F&ts=&use_mirror=nchc
编译.so 动态库 使用 cygwin,安装了所有包,这里提示,不一定要用它,可以直接使用 cmd 进行编译;
ndk 为 android-ndk-r10d(强烈建议使用 r9 或 r10 系列,因为这两个能在 cmd 中编译出 .so), r10d 能够支持的 android api 最高到 21,如果你的是 22 的请修改,否则会有会编译不出 jni.h 头文件。
3,准备工作
1 ,---ndk 的下载、安装即配置,此部分不说,网上教程很多,很多可行。
2 ,---cygwin 的下载和安装, 参照&http://blog.csdn.net/asmcvc/article/details/9311573,我上面说了,不一定要用它,win 自带的 cmd 也可以编译。如果使用 cygwin,要做好心理准备,下载和安装它 它,非常非常的久,文件总体积 20 多G!!!!我是用了9个多小时。
3 ,---opencv for android 的sdk 下载完成后。打开 该文件夹,sdk/native/libs,里面有很多平台的文件夹,能在里面出现的,证明你能够在下面的 Application.mk 中设置生成对应的架构的 .so文件,我举个例子,我的是:
在下面介绍的&Application.mk 文件中有一句话&
,它是用来设置生成 对应架构的 .so 文件,我这里是armeabi-7a,如果要生所有的,写出 :=all,注意, 这样很可能会报错,错误信息是,某种架构找不到 ,所以,我要你看清楚,上面文件夹里面有哪些架构,这些 坑是网上找不到,如果你要生成两种,可以轮着来编译,第二次的编译,不同的架构是不会覆盖的。现在打开&sdk/native/jni,如无意外,里面肯定有个 文件叫做 OpenCV.mk,它就是我们在 android.mk 脚本文件中要引入 opencv C++库所要参照的文件。请用记事本 或者Notepad++ 打开。
4 ,---了解 Android.mk 和 Application.mk 文件的基本内容信息:下面我使用默认的 Android.mk 来说明,和我的例子的 Application.mk 来说明。
它们都是脚本文件。
Android.mk&
Application.mk
4,编译 .so
使用你的 as 创建一个新项目,然后在你的 项目的 main 目录下创建一个一个 jni 文件夹,这样创建:
创建好了之后,是这样的:
首先编译 项目的头文件 .h,一般编译出来后,它的名字结构是:包名_类名.h
编译命令如下,请在你的 as 下面的 Terminal 里面输入 :
SourcePath: &&&D:\work\androidstudio\VisualRecognition\app\src\main\java (绝对路径)
TargetPath: &&&D:\work\androidstudio\VisualRecognition\visual\src\main\jni (绝对路径)
TargetClassName: &&&com.yf.visualrecognition.UnityPlayerActivity &(你的包名+类名)
格式: &javah -d ${SourceFile} -classpath ${TargetPath} ${TargetClassName}
控制台指令: &javah -d D:\work\androidstudio\VisualRecognition\visual\src\main\jni&
-classpath D:\work\androidstudio\VisualRecognition\app\src\main\java& io.github.froger.jni.MyActivity
然后在你的jni 文件夹下面 分别创建&Android.mk 、Application.mk 和你要编译的 .cpp 或者.c 文件,前两个的 内容可以模仿我上面介绍的, .cpp 我这里提供一个。
Android.mk 、Application.mk 、ImgFuncpp&分别如下,util.c 是空文件,之所以创建它是为了避免另外一个 bug,这不说:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
OPENCV_LIB_TYPE:=STATIC
ifeq (&$(wildcard $(OPENCV_MK_PATH))&,&&)
include E:\OpenCV-3.0.0-android-sdk-1\OpenCV-android-sdk\sdk\native\jni\OpenCV.mk
include $(OPENCV_MK_PATH)
LOCAL_MODULE := ImgFun
LOCAL_SRC_FILES := ImgFun.cpp
LOCAL_LDLIBS += -lm -llog
include $(BUILD_SHARED_LIBRARY)
---------------------------------------
APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
APP_ABI := armeabi-v7a
APP_PLATFORM := android-8 #这句是设置最低安卓平台,可以不弄
-------------------------------------
1 #include &io_github_froger_jni_MyActivity.h&
2 #include &stdio.h&
3 #include &stdlib.h&
4 #include &opencv2/opencv.hpp&
5 using namespace
6 IplImage * change4channelTo3InIplImage(IplImage * src);
8 extern &C& {
9 JNIEXPORT jintArray JNICALL Java_io_github_froger_jni_MyActivity_ImgFun(
JNIEnv* env, jobject obj, jintArray buf, int w, int h);
11 JNIEXPORT jintArray JNICALL Java_io_github_froger_jni_MyActivity_ImgFun(
JNIEnv* env, jobject obj, jintArray buf, int w, int h) {
cbuf = env-&GetIntArrayElements(buf, false);
if (cbuf == NULL) {
Mat myimg(h, w, CV_8UC4, (unsigned char*) cbuf);
IplImage image=IplImage(myimg);
IplImage* image3channel = change4channelTo3InIplImage(&image);
IplImage* pCannyImage=cvCreateImage(cvGetSize(image3channel),IPL_DEPTH_8U,1);
cvCanny(image3channel,pCannyImage,50,150,3);
int* outImage=new int[w*h];
for(int i=0;i&w*h;i++)
outImage[i]=(int)pCannyImage-&imageData[i];
int size = w *
jintArray result = env-&NewIntArray(size);
env-&SetIntArrayRegion(result, 0, size, outImage);
env-&ReleaseIntArrayElements(buf, cbuf, 0);
42 IplImage * change4channelTo3InIplImage(IplImage * src) {
if (src-&nChannels != 4) {
return NULL;
IplImage * destImg = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 3);
for (int row = 0; row & src-& row++) {
for (int col = 0; col & src-& col++) {
CvScalar s = cvGet2D(src, row, col);
cvSet2D(destImg, row, col, s);
return destI
上面 .cpp 文件的有几句话要说明下,
注意 .c 文件和 .cpp 文件是不一样的:
& & & 请用 & extern &C& { } 包住 你要你的 c++ 函数体的定义和里面的变量,函数声明可以在外面。下面这句:
JNIEXPORT jintArray JNICALL Java_io_github_froger_jni_MyActivity_ImgFun(JNIEnv* env, jobject obj, jintArray buf, int w, int h);
jintArray 是你定义的函数的返回值,我这里的是int数组,它在类型的前面有一个 j ,如果是字符串,那么就是 jstring,数组加上Array;
JNICALL Java 这句不变,所有都一样,注意java的 j 是大写;
io_github_froger_jni 这里是你的包名;
MyActivity 你的类名,要引用这个这里C++函数的类名;
ImgFun &是你要在java中调用的函数名字,哪些不用直接被调用的,不用写;
JNIEnv* env, jobject obj, 这个固定不变,第一个的意思是虚拟机引用,第二个是项目;
jintArray buf, int w, int h 函数的参数。
第一次写是声明,第二次写是定义。
-------------------------------
好了,上面该介绍的已经介绍完了,接下来是编译 .so 的正式操作(我这里使用cmd做例子,因为它更简单操作,cygwin也可以)。
你可以在 as 的 cmd 中或者 系统的 cmd框中实现编译,首先使用命令进入到当前的 jni 文件夹的 目录,例如,我的是&
D:asproject/JniDemo/app/main/jni,然后使用命令 ndk-build,(使用ndk-build命令这一步,需要你已经配置好了 ndk 环境,请参照百度上面的教程)然后回车,如无意外,将会生成如下文件:
其中的 .so 文件就是我们所需要的,现在打开你项目app下的 &build.gradle 文件,在 android{} 里面加入:
sourceSets {
jniLibs.srcDirs = ['src/main/libs']
这样是为了使用 .so文件,上面我们仅仅是生产!
OK,到这里基本大功告成了,不过,笔者我就是在这一步之后,运行程序的时候,出现的简单的致命的 bug,导致我找了近2星期,现在想起来真是蠢..............
5,遇到的关键问题及其解决方法
运行程序,出现,如下错误,这里声明下,不仅仅是 opencv2/opencv.hpp,还可能是其他的 hpp。
出现的原因:
原来是这样的,android studio 在我们编译完 .so 文件后,我们再 Android.mk 文件中设置引入的 opencv 函数库,是被弄进去了 .so 动态库里面的,而我们编译所需要的 cpp 文件,它在 jni 文件夹呢,自然就没有 opencv 库可依赖,所以。
解决方法:
在你编译完.so 文件后,就可以把 cpp 或者 c 文件里面的内容 注释或者删除了,不然 在你运行程序的时候 就会抛出 头文件找不到的 错误,哎,真是辛酸泪,这样一个 bug 搞了我 那么多时间,不过还好,还是解决了。
6,实现效果截图。
已发表评论数()
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
主题不准确
没有分页内容
图片无法显示
视频无法显示
与原文不一致}

我要回帖

更多关于 手机设备号 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信