Android NDK开发OpenCV系列:轮廓检测图像裁剪
2022-02-28 本文已影响0人
itfitness
目录
效果展示
函数讲解
这里使用的函数我之前的文章有介绍过:
findContours(轮廓发现)
实现代码
#include <jni.h>
#include <string>
#include "utils.cpp"
#include "android/log.h"
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,__VA_ARGS__ ,__VA_ARGS__) // 定义LOGE类型
using namespace std;
extern "C"
JNIEXPORT jobject JNICALL
Java_com_itfitness_cppdemoone_activity_EdgeCuttingActivity_imageEdgeCutting(JNIEnv *env,
jobject thiz,
jobject bitmap_src) {
//源图像
Mat src,src_copy;
//将Bitmap转换为Mat
BitmapToMat(env,bitmap_src,src, JNI_FALSE);
//复制
src.copyTo(src_copy);
//转换为灰度图
cvtColor(src_copy,src_copy,COLOR_BGR2GRAY);
//图像二值化
threshold(src_copy,src_copy,120,250,THRESH_BINARY);
//轮廓发现
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
//检测外围轮廓
findContours(src_copy,contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE,Point(0,0));//轮廓检测
//找出最大轮廓
Rect rectMax;
int i;
for(i = 0 ; i < contours.size() ; i ++){
Rect rect = boundingRect(contours[i]);
if(rect.width * rect.height > rectMax.width * rectMax.height){
rectMax.width = rect.width;
rectMax.height = rect.height;
rectMax.x = rect.x;
rectMax.y = rect.y;
LOGE("轮廓","宽:%d,高:%d,位置:%d,%d",rectMax.width,rectMax.height,rectMax.x,rectMax.y);
}
}
//调用Activity中的方法进行裁剪
jclass clazz = env->GetObjectClass(thiz);
jmethodID jmethodId = env->GetMethodID(clazz,"createClipBitmap",
"(Landroid/graphics/Bitmap;IIII)Landroid/graphics/Bitmap;");
jobject destBitmap = env->CallObjectMethod(thiz,jmethodId,bitmap_src,rectMax.x,rectMax.y,rectMax.width,rectMax.height);
//释放Mat
src.release();
src_copy.release();
return destBitmap;
}
其中裁剪的方法是Kotlin实现的,代码如下:
/**
* 裁剪图像
*/
fun createClipBitmap(src:Bitmap,x:Int,y:Int,width:Int,height:Int):Bitmap{
return Bitmap.createBitmap(src,x,y,width,height)
}