一、OpenCV介绍
OpenCV是一个基于开源的跨平台计算机视觉库,实现了许多图像处理和计算机视觉方面的通用算法,是计算机视觉领域最有力的研究工具之一。
OpenCV应用领域:人机互动 物体识别 图像分割 人脸识别 动作识别 运动跟踪 机器人 运动分析 机器视觉 结构分析 汽车安全驾驶 自动驾驶。。。
二、OpenCV模块介绍
1.core,核心功能模块,主要包含如下的内容:
OpenCV基本数据结构(Basic Structures);
基本的C语言数据结构和操作(Basic C Structures and Operations);
动态数据结构(DynamicStructures);
数组操作相关函数(Operations on Arrays);
绘图功能(Drawing Functions);
XML和YAML语法的支持(XML/YAML Persistence);
XML和YAML语法的支持的C语言接口(XML/YAML Persistence (C API));
聚类(Clustering);
辅助功能与系统函数和宏(Utility and System Functions and Macros);
与OpenGL的互操作(OpenGL interoperability);
2.imgproc,是Image Processing的简写。图像处理模块,主要包含以下内容:
线性和非线性的图像滤波(Image Filtering);
图像的几何变换(Geometric ImageTransformations);
图像的其他变换(Miscellaneous Image Transformations);
直方图(Histograms);
结构分析和形状描述(Structural Analysis and Shape Descriptors);
运动分析和目标跟踪(Motion Analysis and Object Tracking);
特征检测(Feature Detection);
目标检测(Object Detection);
3. highgui,是High-level GUI and Media I/O的简写。高层用户界面模块和媒体输入/输出模块,主要包含以下内容:
用户界面(User Interface);
图片和视频的读写(Reading and Writing Images and Video);
QT新功能(Qt New Functions);
4. features2d,是2D Features Framework的简写。二维特征框架模块,主要包含以下内容:
人脸识别
VR和AR
特征的检测和描述(Feature Detection and Description);
特征检测器的通用接口(Common Interfaces of Feature Detectors);
描述符提取器的通用接口(Common Interfaces of Descriptor Extractors);
描述符匹配器的通用接口(Common Interfaces of Descriptor Matchers);
通用描述符匹配器通用接口(Common Interfaces of Generic Descriptor Matchers);
关键点和匹配结果的绘制功能(Drawing Function of Keypoints and Matches);
目标分类(Object Categorization);
5.flann,Clustering and Search in Multi-Dimensional Spaces,多维空间聚类和搜索模块,主要包含以下内容:快速近视最近邻搜索(Fast Approximate Nearest Neighbor Search);
聚类(Clustering);
6. video,是Video Analysis的简写。视频分析模块,主要包含以下内容:
运动分析和目标跟踪(Motion Analysis and Object Tracking),视频相关的,上面提到的是图片相关的;
7. calib3d ,是Camera Calibration and 3D
Reconstruction的简写。这个模块主要是相机校准和三维重建相关的内容,包括基本的多视角几何算法、单个立体摄像头标定、物体姿态估计、立体相似性算法,3D信息的重建等。
三、OpenCV-android-SDK目录结构
apk = ==》OpenCV manager针对各个架构的cup的manager安装包
samples ===》 android平台下的案例源码和安装包(java调用方式的)
sdk = ==》 sdk文件夹
四、环境搭建(正文)
1.搭建AndroidStudio的NDK环境,创建NDK项目;
2.下载OpenCV(点击下载)
3.找到app的build.gradle添加下面两句话:
为了方便大家copy,就特意写出来了
cmake {
//-std=c++14 加入C++14支持
cppFlags "-std=c++14 -frtti -fexceptions"
//指定要ndk需要兼容的架构
//注意:如果全部都适配的话,包很大,
// 这样兼容那些用户数极少的cpu就很不划算,
// 所以可以选择适配了armeabi-v7a这一个
// (我这里全部配置了apk真的很大 大概有80.7 MB)
abiFilters 'arm64-v8a','armeabi','armeabi-v7a','mips','mips64','x86','x86_64'
}
================================================================
sourceSets{
main {
//jni库的调用会到这个目录里面找so文件
jniLibs.srcDirs =
['E:/OpenCV/opencv-3.4.3-android-sdk/OpenCV-android-sdk/sdk/native/libs']
}
}
4.配置CMakeLists.txt文件(直接复制,把路径修改成自己的就成)
#声明CMake的版本要求
cmake_minimum_required(VERSION 3.4.1)
#该变量为真时会创建完整版本的Makefile
set(CMAKE_VERBOSE_MAKEFILE on)
#定义变量ocvlibs使后面的命令可以使用定位具体的库文件
set(ocvlibs
"E:/OpenCV/opencv-3.4.3-android-sdk/OpenCV-android-sdk/sdk/native/libs")
#调用头文件的具体路径
include_directories
(E:/OpenCV/opencv-3.4.3-android-sdk/OpenCV-android-sdk/sdk/native/jni/include)
#生成动态库openvc-lib
add_library(openvc-lib SHARED IMPORTED )
#设置输出的名称,设置动态库的版本和API版本
set_target_properties(openvc-lib
PROPERTIES
IMPORTED_LOCATION
"${ocvlibs}/${ANDROID_ABI}/openvc-lib.so")
add_library(native-lib SHARED src/main/cpp/native-lib.cpp )
find_library(log-lib log )
target_link_libraries(native-lib openvc-lib android log ${log-lib})
5.检验是否成功(如果头文件导入成功 就表示环境搭建没啥问题!)
五、案例
既然环境搭建成功,相信很多人会迫不及待的想要去尝试一下,这里给大家做了一个简单的 “ 图片灰度处理 ” 案例:
- 布局(请自行脑补,谢谢!)
- MainActivity.java
static {
System.loadLibrary("native-lib");
}
public native int[] getGrayImage(int pixels[], int width, int height);
private ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.button).setOnClickListener(this);
imageView = findViewById(R.id.imageView);
//获取位图
bitmap =
BitmapFactory.decodeResource(this.getResources() , R.mipmap.mei);
imageView.setImageBitmap(bitmap);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button:
int w = bitmap.getWidth();
int h = bitmap.getHeight();
int pixels[] = new int[w*h];
int count = 0;
for(int i = 0 ; i < h ; i++)
for (int j = 0 ; j < w ; j++)
pixels[count++] = bitmap.getPixel(j , i);
int p[] = getGrayImage(pixels , w , h);
imageView.setImageBitmap(
Bitmap.createBitmap(p , w , h , Bitmap.Config.ARGB_8888));
break;
}
}
- native-lib.cpp
#include <jni.h>
#include <opencv2/opencv.hpp>
extern "C" {
JNIEXPORT jintArray JNICALL
Java_com_qingyan_opecv_101_MainActivity_getGrayImage
(JNIEnv *env, jobject instance, jintArray _pixels, jint width, jint height)
{
jint *pixels = env->GetIntArrayElements(_pixels , NULL);
if(pixels==NULL){
return NULL;
}
cv::Mat imgData(height , width , CV_8UC4 , pixels);
uchar *ptr = imgData.ptr(0);
for (int i = 0; i < width * height; i++) {
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] = (uchar) grayScale;
ptr[4 * i + 2] = (uchar) grayScale;
ptr[4 * i + 0] = (uchar) grayScale;
}
int size = width * height;
jintArray result = env->NewIntArray(size);
env->SetIntArrayRegion(result, 0, size, pixels);
env->ReleaseIntArrayElements(_pixels, pixels, 0);
return result;
}
}
- 效果
如果遇到【dlopen failed: library “libc++_shared.so” not found】报错 可以查看我的这篇文章