這裡省去ndk開發環境的配置 直接進入opencv內建到Android studio中
我們在opencv官網下載下傳到的https://opencv.org android開發包 解壓壓縮包結構

U$MD9(`)]]TK6WHT8H`O470.png
在項目的main檔案下建立jniLibs目錄 将opencv的.so檔案拷貝到該目錄下

ss.png
将opencv的include檔案夾拷貝到cpp檔案夾下

includ.png
配置cmake檔案
# 設定include檔案夾的位址
include_directories(${CMAKE_SOURCE_DIR}/src/main/cpp/include)
# 設定opencv的動态庫
add_library(libopencv_java3
SHARED
IMPORTED)
set_target_properties(libopencv_java3
PROPERTIES
IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libopencv_java3.so)
target_link_libraries( # Specifies the target library.
native-lib libopencv_java3 jnigraphics
# Links the target library to the log library
# included in the NDK.
${log-lib})
build.gradle檔案 android 節點下配置
android {
.......
sourceSets {
main {
jniLibs.srcDirs = ['src/main/jniLibs']
}
}
.......
到此我們opencv 已經配置完成 下面我們來寫一個小demo驗證是否配置成功
public class MainActivity extends AppCompatActivity {
// Used to load the 'native-lib' library on application startup.
static {
System.loadLibrary("native-lib");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ImageView iv_show = findViewById(R.id.iv_show);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.zyz);
BitmapUtils.counterWorld(bitmap);
iv_show.setImageBitmap(bitmap);
}
}
下面是利用opencv 實作的一個逆世界效果
#include
#include
#include
#include "bitmap/com_youyangbo_opencv_BitmapUtils.h"
#include "bitmap/opencvHelp.h"
using namespace cv;
extern "C" void JNICALL Java_com_youyangbo_opencv_BitmapUtils_counterWorld
(JNIEnv *env, jclass jclazz, jobject bitmap) {
Mat src;
bitmap2Mat(env, src, bitmap);
int middleRows = src.rows >> 1;
int quarterRows = middleRows >> 1;
Mat conword_imag(src.size(), src.type());
for (int row = 0; row < middleRows; ++row) {
for (int col = 0; col < src.cols; ++col) {
conword_imag.at(middleRows + row, col) = src.at(
quarterRows + row, col);
}
}
for (int row = 0; row < middleRows; ++row) {
for (int col = 0; col < src.cols; ++col) {
conword_imag.at(middleRows - row, col) = src.at(quarterRows + row, col);
}
}
mat2Bitmap(env, conword_imag, bitmap);
}
opencv 是c/c++的庫,處理圖檔資料是Mat(矩陣),Android 圖檔表現形式是Bitmap,是以Android中的圖檔交給opencv處理必須先将Bitmap轉化成Mat,
#include "bitmap/opencvHelp.h"
#include
void bitmap2Mat(JNIEnv *env, cv::Mat &mat, jobject bitmap) {
AndroidBitmapInfo bitmap_info;
void *pPixel = NULL;
AndroidBitmap_getInfo(env, bitmap, &bitmap_info);
AndroidBitmap_lockPixels(env, bitmap, &pPixel);
//判斷傳入的圖檔是什麼類型
if (bitmap_info.format == ANDROID_BITMAP_FORMAT_RGBA_8888) {//32
//對應opncv Mat 類型 CV_8UC4
cv::Mat temp(bitmap_info.height, bitmap_info.width, CV_8UC4, pPixel);
temp.copyTo(mat);
} else if (bitmap_info.format == ANDROID_BITMAP_FORMAT_RGB_565) {//16
//對應opncv Mat 類型 CV_8UC2
cv::Mat temp(bitmap_info.height, bitmap_info.width, CV_8UC2, pPixel);
cv::cvtColor(temp, mat, CV_BGRA2BGR565);
}
AndroidBitmap_unlockPixels(env, bitmap);
}
void mat2Bitmap(JNIEnv *env, cv::Mat &mat, jobject bitmap) {
AndroidBitmapInfo bitmap_info;
void *pPixel = NULL;
AndroidBitmap_lockPixels(env, bitmap, &pPixel);
AndroidBitmap_getInfo(env, bitmap, &bitmap_info);
//判斷傳入的圖檔是什麼類型
if (bitmap_info.format == ANDROID_BITMAP_FORMAT_RGBA_8888) {//32
cv::Mat tmp(bitmap_info.height, bitmap_info.width, CV_8UC4, pPixel);
//對應opncv Mat 類型 CV_8UC4
if (mat.type() == CV_8UC4) {
//對應bitmap RGBA_8888
mat.copyTo(tmp);
} else if (mat.type() == CV_8UC2) {
//對應bitmap RGB_565
cv::cvtColor(mat, tmp, CV_BGR5652BGRA);
} else if (mat.type() == CV_8UC1) {
//單通道 0-255 的灰階圖
cv::cvtColor(mat, tmp, CV_GRAY2BGRA);
}
} else if (bitmap_info.format == ANDROID_BITMAP_FORMAT_RGB_565) {//16
cv::Mat tmp(bitmap_info.height, bitmap_info.width, CV_8UC2, pPixel);
//對應opncv Mat 類型 CV_8UC2
if (mat.type() == CV_8UC4) {
//對應bitmap RGBA_8888
cv::cvtColor(mat, tmp, CV_BGRA2BGR565);
} else if (mat.type() == CV_8UC2) {
//對應bitmap RGB_565
mat.copyTo(tmp);
} else if (mat.type() == CV_8UC1) {
//單通道 0-255 的灰階圖
cv::cvtColor(mat, tmp, CV_GRAY2BGR565);
}
}
AndroidBitmap_unlockPixels(env, bitmap);
}
代碼運作效果:
原圖:

2.jpg
經過opencv處理過的

demo.png