您的位置:首页 > 移动开发 > Android开发

Qt5 for android + opencv

2014-06-27 10:48 513 查看
~~~~我的生活,我的点点滴滴!!

Qt5中新添加了qcamera接口,但是5.3版本之前android平台上的qcamera都不好用,QML的貌似可以用,有了camera功能确实方便干好多事情,不过今天我们不是来计qt自带的camera,我们使用opencv中的摄像头接口,之所以使用opencv是因为他对图像处理提供了很多方便,并且他也是开源跨平台的,下面开始我们qt5 for android + opencv之旅吧

一、 下载opencv库

去官网 http://opencv.org/ 下载最新的opencv
for android
的库,我使用的时候最新为了2.4.9 版本,opencv自从2.3.1开始就支持anroid平台了,你也不用非得下载最新的opencv,本人测试2.4.x的都可以正常使用(别用太老的版本了)

下载完成后,不需要安装直接解压到非中文文件路径下,文件布局如下:

E:\HZF\qt-android\OpenCV-2.4.9-android-sdk

|------apk

|------doc

|------samples

|------sdk

1. apk --->文件夹下有一些后缀.apk的包和一个readme.txt 我们通过读txt文档,选择合适的OpenCV Manager apk包去安装到我们的真机上,你要觉得好奇可以解压此包看看里面都有什么,你会发现他里面全是java接口的.so 动态链接库,那表明我们的opencv程序在发布到android平台上时不需要自己在带这些库,只要提前安装了OpenCV Manager就行。

2. doc---->开发文档(对于我们没有用)。

3. samples----->有一些例子,也有直接编译好的apk包,那些例子是java的,对于我们不使用原生态android开发来说没多大用处,例子可以安装到真机去测试一下真机环境及验证第一步是否需要提前安装OpenCV Manager, 安装运行example-tutorial-1-camerapreview.apk来检测真机的摄像头是否能用,这对于第一次使用新技术来说很有帮助,能确定出问题只会是自己的软件代码有问题。

4. sdk----->里面有我们需要的native 开发动态链接库
pre-build 是提前编译好的,这点opencv组织做的很好,赞一下!进入到native\libs下面会看到四种不同编译器下面都有已经编译好的库文件,我们需要armeabi-v7a文件夹的下面的。



二、配置opencv到Qt

Qt中添加外部链接库只需要在.pro文件中添加 头文件路径 及 库路径,我们来看看pro里面怎么写的,他的正确性直接决定我们的程序是否能成功编译,我们看一下pro内容

unix {
message("Using unix configuration")
ANDROID_OPENCV = E:/HZF/qt-android/OpenCV-2.4.9-android-sdk/sdk/native

INCLUDEPATH += \
$$ANDROID_OPENCV/jni/include/opencv    \
$$ANDROID_OPENCV/jni/include/opencv2    \
$$ANDROID_OPENCV/jni/include            \

LIBS += \
$$ANDROID_OPENCV/libs/armeabi-v7a/libopencv_contrib.a \
$$ANDROID_OPENCV/libs/armeabi-v7a/libopencv_legacy.a \
$$ANDROID_OPENCV/libs/armeabi-v7a/libopencv_ml.a \
$$ANDROID_OPENCV/libs/armeabi-v7a/libopencv_objdetect.a \
$$ANDROID_OPENCV/libs/armeabi-v7a/libopencv_calib3d.a \
$$ANDROID_OPENCV/libs/armeabi-v7a/libopencv_video.a \
$$ANDROID_OPENCV/libs/armeabi-v7a/libopencv_features2d.a \
$$ANDROID_OPENCV/libs/armeabi-v7a/libopencv_highgui.a \
$$ANDROID_OPENCV/libs/armeabi-v7a/libopencv_androidcamera.a \
$$ANDROID_OPENCV/libs/armeabi-v7a/libopencv_flann.a \
$$ANDROID_OPENCV/libs/armeabi-v7a/libopencv_imgproc.a \
$$ANDROID_OPENCV/libs/armeabi-v7a/libopencv_core.a     \
$$ANDROID_OPENCV/3rdparty/libs/armeabi-v7a/liblibjpeg.a \
$$ANDROID_OPENCV/3rdparty/libs/armeabi-v7a/liblibpng.a \
$$ANDROID_OPENCV/3rdparty/libs/armeabi-v7a/liblibtiff.a \
$$ANDROID_OPENCV/3rdparty/libs/armeabi-v7a/liblibjasper.a \
$$ANDROID_OPENCV/3rdparty/libs/armeabi-v7a/libtbb.a

}


android底层是linux体系,Qt中编译android也是使用的arm体系工具链,这个在上篇blog中也有提到,所以我们使用unix{} 来包裹。

ANDROID_OPENCV 是用来指定opencv native根路径的。

INCLUDEPATH指定了其头文件。

重点来了:

LIBS 中我们用的是.a静态链接库(他只提供了这个),静态链接库的链接顺序是有先后之分的,如果顺序不对是会报错的,大多情况会提示一堆 “未定义”错误,上面基本已经把opencv的所有库都写全了,就是这个顺序,如果懒得研究的可以直接每次在Qt中使用opencv时复制进去就行了。配置好了opencv后我们就可以开始编写代码了。

三、问题及解决

在上面我们配置好编译环境后,我们测试发现失败,报错一堆,我们仔细看其错误,发现类似于 xxxx.so库没有 加载 之类的问题,我们解压我们的apk程序包,对比我们的lib与OpenCV Manager下面的lib 看看是否大体一样(我们lib下面Qt的库忽略,只看与opencv有关的)发现少了 libopencv_java.so我们修改pro链接这个库的全路径,部署运行依然出错,我们在去我们apk包的lib下面找,此时发现就算我们链接了此库但是Qt就没有把他复制到lib下面,怎么办?两种解决方案:

1. 为什么Qt的库能复制进去了?那是因为Qt会自动从他的lib根目录下去找需要的库,既然这样那么我们何不也把libopencv_java.so放到Qt的lib目录下面,然后在pro中写上 -lopencvjava 了?通过验证确实可以行,但是这样有点不太好,更改了Qt lib目录下的文件布局,我们使用第二种方法。

2.此方法在下面给出。

解决了这个问题,我们继续测试opencv的摄像头功能,编译发布都没有问题了(此时有点小高兴) ,当我们在软件中打开camera时,这时报错了,提示“CameraWrapperConnector::connectToLib ERROR: cannot dlopen camera wrapper library” 不使用摄像头功能一切正常(比如:打开图片处理图片之类的操作都正常),并且看错误提示 dlopen camera libray也是没有找到有关此的动态库,google好多资料后发现少了libnative_camera.so库,我去opencv
libs下面看,你会发现有好多版本的此类so文件,我们找一个最匹配我们真机的,真机使用的是android 4.0.4 版本,那么我们就复制libnative_camera_r4.0.3.so到Qt的lib下面,然后照着上面libopencv_java的方法链接,原本以为会成功的,但是一运行,依然提示一堆错误,不过此时已经不是lib的加载的问题了,报java里面的异常,慌乱了,彻底慌乱了,java什么的完全不会啊!!!!!!

.....google搜索中

.....google搜索中

.....google搜索中

良久,想起以前无意间关注的问题,android的各种版本库之间的兼容是怎么解决的?是向上兼容还是向下兼容?问了一下网友,豁然开朗啊!!!用低版本的android包编译与开发的程序在高版本中是可以兼容运行的,但是用高版本开发的不一定能在低版本中使用(注意只是android的sdk包,我们可以下载各个版本的API level当我们需要哪个,我们编译时候就指定哪个),上篇blog文说过,使用sdk manager是可以下载各个版本的android开发包的,但是GFW封死了,百度了好久才找一个4.0.3版本的,解压后改名成android-15(4.0.3对应的API
Level是15)放到C:\adt-bundle-windows-x86-20130729\sdk\platforms下面,目前我还有api level 18的包,看下面文件结构图



问题又来了-----------------Qtcreator中如何指定使用哪个android sdk了? 依然两种方法:

1. 在Qt creator中点击 “项目” --------->>切换到"运行"页进行设置



点击上图中 编号1 ---- 2 -----3 后就能看到上图的内容了,我们下接编译4 会列出所有你电脑上目前有的开发包,选择android-15 然后我们点击编号 5 创建一个AndroidManifest.xml 使用android开发的人都知道这个xml的重要性,他能让我们行使好多特权(作为一个android小白,我是花了好长时间才了解android的一点点基本情况啊,过程很苦比)

创建完成后,我们发现我工程目录下多了此xml文件,我们双击打开,进行设置:



编号1 看看就行

编号2 其实我们可以在这里指定android版本

编号3 用来更改我们程序图标(建议使用一下他,可以用来验证我们设置了xml是否在程序中起了使用)

编号4 用来给程序添加一些特性,由于我们要使用camera,我们需要添加camera权限,找到编号 5 这一项,点击 添加 就OK了!

准备工作做完了,编译运行

..................

终于看到opencv成功打开摄像头了,眼泪哗哗往下流啊!!!



----------------------------------------------------------------------------------------------------------------------------------------------

上面说过添加外部动态链接库有两种方法,我们只说了第一种,下面补充第二种,建议使用这种方法,直接看图片,找到此处添加我们需要的库就行,Qt在发布android平台的程序时就会复制到apk包的lib下面了,但是我们的pro的LIBS中还是要写上链接库的名字(编译要用),使用这方法是运行是需要的,他们不同的,切记!!



上面废话了一堆,我们其实只关心结果,总结一下,大家可以直接看总结

1. 正确写好pro文件里的内容

unix {
message("Using unix configuration")
ANDROID_OPENCV = E:/HZF/qt-android/OpenCV-2.4.9-android-sdk/sdk/native
ANDROID_ZBAR = E:/HZF/qt-android/ZBarAndroidSDK

INCLUDEPATH += \
$$ANDROID_OPENCV/jni/include/opencv    \
$$ANDROID_OPENCV/jni/include/opencv2    \
$$ANDROID_OPENCV/jni/include            \
$$ANDROID_ZBAR/include  \

LIBS += -lopencv_java   \
$$ANDROID_ZBAR/libs\armeabi-v7a/libiconv.so  \
$$ANDROID_ZBAR/libs\armeabi-v7a/libzbarjni.so    \
$$ANDROID_OPENCV/libs/armeabi-v7a/libopencv_contrib.a \
$$ANDROID_OPENCV/libs/armeabi-v7a/libopencv_legacy.a \
$$ANDROID_OPENCV/libs/armeabi-v7a/libopencv_ml.a \
$$ANDROID_OPENCV/libs/armeabi-v7a/libopencv_objdetect.a \
$$ANDROID_OPENCV/libs/armeabi-v7a/libopencv_calib3d.a \
$$ANDROID_OPENCV/libs/armeabi-v7a/libopencv_video.a \
$$ANDROID_OPENCV/libs/armeabi-v7a/libopencv_features2d.a \
$$ANDROID_OPENCV/libs/armeabi-v7a/libopencv_highgui.a \
$$ANDROID_OPENCV/libs/armeabi-v7a/libopencv_androidcamera.a \
$$ANDROID_OPENCV/libs/armeabi-v7a/libopencv_flann.a \
$$ANDROID_OPENCV/libs/armeabi-v7a/libopencv_imgproc.a \
$$ANDROID_OPENCV/libs/armeabi-v7a/libopencv_core.a     \
$$ANDROID_OPENCV/3rdparty/libs/armeabi-v7a/liblibjpeg.a \
$$ANDROID_OPENCV/3rdparty/libs/armeabi-v7a/liblibpng.a \
$$ANDROID_OPENCV/3rdparty/libs/armeabi-v7a/liblibtiff.a \
$$ANDROID_OPENCV/3rdparty/libs/armeabi-v7a/liblibjasper.a \
$$ANDROID_OPENCV/3rdparty/libs/armeabi-v7a/libtbb.a
}

ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android

OTHER_FILES += \
    android/AndroidManifest.xml

contains(ANDROID_TARGET_ARCH,armeabi-v7a) {
    ANDROID_EXTRA_LIBS = \
        E:/HZF/HZFProject/QtTest2/libnative_camera_r4.0.3.so \
        E:/HZF/HZFProject/QtTest2/libiconv.so \
        $$PWD/libzbarjni.so
}


2. 点击 “项目” ------> “运行” 修改 build sdk 选择 比真机android库版本低的开发包,创建AndroidManifest.xml 文件,点击 “add” 添加我们需要的libnative_camera_r4.0.3.so文件

3.打开AndroidManifest.xml文件,修改权限,添加使用camera权限,修改Target sdk 改成比真机android库版本低的开发包(如果显示是低版本的包就不需要这一步了)

4.Qt5 for android 开发的apk 运行时是不需要预先安装OpenCV Manager的

5.附上Demo,建议在编译Qt for android 程序时不要使用 Shadow build

附言

感谢下面留言指出问题的所有人,也特别感谢下面留言的 wy9420
不辞辛苦的总结和指出了一些他在按照我的文章配置和调用过程中遇到的问题,这篇文章只是作为一个引子和方向指出怎么在 Qt for android 中使用opencv ,也许你完全照着上面做并不一定能一次就成功,但是至少会比你在一无所知的情况下盲目摸索要好很多,当时我在弄这个的时候,基本上算是没有资料也借用,也许有,但至少我是没有搜索到,所以大家在按照上面弄完后,碰到问题,不要慌张,也不要着急,慢慢的来,Qt for android + opencv肯定是可行的,
下面列出 wy9420
碰到的问题,大家就当作一种借鉴,也许你按我上面的能成功,也许你按下面也能成功。

问题1:

配置opencv时出现类似红色字体

D:\andriodziliao\OpenCV-2.4.9-android-sdk\sdk\native/libs/armeabi-v7a/libopencv_highgui.a(grfmt_exr.cpp.o):grfmt_exr.cpp:function cv::ExrDecoder::ExrDecoder(): error: undefined reference to 'Imf::Chromaticities::Chromaticities(Imath::Vec2<float> const&, Imath::Vec2<float> const&, Imath::Vec2<float> const&, Imath::Vec2<float> const&)'的情况

问题就是出在LIBS里面的opencv链接库没有包含对,或者完全 。



但是在虫子你的博客里面的libs我按照加了一样有问题 ,后面去

\OpenCV-2.4.9-android-sdk\sdk\native\3rdparty\libs\armeabi-v7a\

下面找到libIlmImf.a加了进去就好了,等于在下面多出了红色的那行

unix {

message("Using unix configuration")

ANDROID_OPENCV = E:/Qt/Qt5.3.2_Android/OpenCV-2.4.9-android-sdk/sdk/native





INCLUDEPATH += \

$$ANDROID_OPENCV/jni/include/opencv \

$$ANDROID_OPENCV/jni/include/opencv2 \

$$ANDROID_OPENCV/jni/include \





LIBS += \

$$ANDROID_OPENCV/libs/armeabi-v7a/libopencv_contrib.a \

$$ANDROID_OPENCV/libs/armeabi-v7a/libopencv_legacy.a \

$$ANDROID_OPENCV/libs/armeabi-v7a/libopencv_ml.a \

$$ANDROID_OPENCV/libs/armeabi-v7a/libopencv_objdetect.a \

$$ANDROID_OPENCV/libs/armeabi-v7a/libopencv_calib3d.a \

$$ANDROID_OPENCV/libs/armeabi-v7a/libopencv_video.a \

$$ANDROID_OPENCV/libs/armeabi-v7a/libopencv_features2d.a \

$$ANDROID_OPENCV/libs/armeabi-v7a/libopencv_highgui.a \

$$ANDROID_OPENCV/libs/armeabi-v7a/libopencv_androidcamera.a \

$$ANDROID_OPENCV/libs/armeabi-v7a/libopencv_flann.a \

$$ANDROID_OPENCV/libs/armeabi-v7a/libopencv_imgproc.a \

$$ANDROID_OPENCV/libs/armeabi-v7a/libopencv_core.a \

$$ANDROID_OPENCV/3rdparty/libs/armeabi-v7a/libIlmImf.a \

$$ANDROID_OPENCV/3rdparty/libs/armeabi-v7a/liblibjpeg.a \

$$ANDROID_OPENCV/3rdparty/libs/armeabi-v7a/liblibpng.a \

$$ANDROID_OPENCV/3rdparty/libs/armeabi-v7a/liblibtiff.a \

$$ANDROID_OPENCV/3rdparty/libs/armeabi-v7a/liblibjasper.a \

$$ANDROID_OPENCV/3rdparty/libs/armeabi-v7a/libtbb.a

}



问题2:

碰到这个情况CameraWrapperConnector::connectToLib ERROR: cannot dlopen camera wrapper library



虫子,我按你的那个加解决不了, 我是都将



复制到了工程目录下面,仅在这里



添加了

libopencv_java.so

libopencv_info.so

而没有添加libnative_camera_r4.0.3.so,如果要添加libnative_camera_r4.0.3.so,则会直接报错…. ,然后就ok了 。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: