一、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;
}
}
- 效果