这里省去ndk开发环境的配置 直接进入opencv集成到Android studio中
我们在opencv官网下载到的https://opencv.org android开发包 解压压缩包结构
在项目的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 <jni.h>
#include <string>
#include<opencv2/opencv.hpp>
#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<float>(middleRows + row, col) = src.at<float>(
quarterRows + row, col);
}
}
for (int row = 0; row < middleRows; ++row) {
for (int col = 0; col < src.cols; ++col) {
conword_imag.at<float>(middleRows - row, col) = src.at<float>(quarterRows + row, col);
}
}
mat2Bitmap(env, conword_imag, bitmap);
}
opencv 是c/c++的库,处理图片数据是Mat(矩阵),Android 图片表现形式是Bitmap,所以Android中的图片交给opencv处理必须先将Bitmap转化成Mat,
#include "bitmap/opencvHelp.h"
#include <android/log.h>
/**
* bitmap 转化为矩阵(Mat)
* @param pEnv
* @param mat
* @param bitmap
*/
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);
}
/**
* Mat转化为Bitmap
* @param pEnv
* @param mat
* @param 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);
}
代码运行效果:
经过opencv处理过的 demo.png
网友评论