首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android利用SurfaceView显示Camera图像爬坑记(六) -- 用OpenCV进行Canny边缘检测

Android利用SurfaceView显示Camera图像爬坑记(六) -- 用OpenCV进行Canny边缘检测

作者头像
Vaccae
发布2019-07-25 14:28:00
1.1K0
发布2019-07-25 14:28:00
举报
文章被收录于专栏:微卡智享微卡智享

前言

上一篇《Android利用SurfaceView显示Camera图像爬坑记(五) -- 在现有项目中加入NDK配置》中我们已经把NDK加入到SurfaceView实时图像显示了,这一篇我们就针对这个实时进行图像处理,并显示到预览实时帧中。

本篇写完基本这个摄像头获取实时Camera进行图像处理的基本可以告一段落,所以最后我会把我的这套DEMO程序放到网盘上。

视频演示效果

今天这篇先上视频效果

代码实现

新建一个JNI的调用类VaccaeOpenCVJNI,在里面加入一个native的方法getCameraframebitbmp,用于实时处理传递进去的Bitmap的图像。

平时我们惯例直接ALT+ENTER,在native-lib中生成对应的方法了,不过这次因为我们原来的native-lib.cpp里面是空的,系统默认在JNI的目录下生成了一个native-lib.c的文件,没办法,这个只能手写了,不过写完这一个如果要再增加方法按ALT+ENTER就会指定对了。

native-lib.cpp里的方法

其中上面有个mat2bitmap就是我在《OpenCV4Android中NDK开发(二)---图片转为灰度图》处理灰度图的方法

extern "C"
JNIEXPORT jobject JNICALL
Java_dem_vac_surfaceviewdemo_VaccaeOpenCVJNI_getCameraframebitbmp(JNIEnv *env, jclass type,
                                                                  jobject bmp) {

    AndroidBitmapInfo bitmapInfo;
    void *pixelscolor;
    int ret;

    //获取图像信息,如果返回值小于0就是执行失败
    if ((ret = AndroidBitmap_getInfo(env, bmp, &bitmapInfo)) < 0) {
        LOGI("AndroidBitmap_getInfo failed! error-%d", ret);
        return NULL;
    }

    //判断图像类型是不是RGBA_8888类型
    if (bitmapInfo.format != ANDROID_BITMAP_FORMAT_RGBA_8888) {
        LOGI("BitmapInfoFormat error");
        return NULL;
    }

    //获取图像像素值
    if ((ret = AndroidBitmap_lockPixels(env, bmp, &pixelscolor)) < 0) {
        LOGI("AndroidBitmap_lockPixels() failed ! error=%d", ret);
        return NULL;
    }

    //生成源图像
    cv::Mat src(bitmapInfo.height, bitmapInfo.width, CV_8UC4, pixelscolor);

    //生成Canny图像
    dealcanny(src);

    //获取原图片的参数
    jclass java_bitmap_class = (jclass) env->FindClass("android/graphics/Bitmap");
    jmethodID mid = env->GetMethodID(java_bitmap_class, "getConfig",
                                     "()Landroid/graphics/Bitmap$Config;");
    jobject bitmap_config = env->CallObjectMethod(bmp, mid);
    //将SRC转换为图片
    jobject _bitmap = mat2bitmap(env, src, false, bitmap_config);

    AndroidBitmap_unlockPixels(env, bmp);


    return _bitmap;
}

上图中看到这里有个dealcanny(src)的方法,这里正好学习一下新知识,新建别的C++的文件调用,这样我们的native-lib.cpp里的方法只有入口方法,具体的图像处理可以新建别的CPP来实现。

新建cvcanny的C++ class

鼠标右键CPP那选择新建,如下图,名称改为cvcanny

cvcanny.h头文件

在头文件中加入一个dealcanny的方法

cvcanny.cpp文件

cvcanny.cpp中写dealcanny的实现方法

然后在native-lib.cpp中引入cvcanny.h的头文件

CMakeLists.txt修改

CMakeLists.txt要做修改的原因有两点,一是我们在相同目录下加入了别的cpp的文件,所以要一起打包进去,另一个原因是我把Opencv4.1的版本改为OpenCV3.4.6了(改版本的原因是我有个老的测试机是android4.1的,用OpenCV4.1不支持这个机型,所以改为OpenCV3.4.6)

最后在VaccaeSurfaceView中的nv21Tobitmap的方法旋转图像下面加入调用JNI的方法,如下图红框

这样整个项目就完成了,总结一下几个注意的点:

  1. 增加新的CPP方法时一开始我直接加了cpp文件,结果运行时报错,后面才加入的cvcanny的class写法,但是一开始用重新编译时一直不通过,提示我原来增加的cpp文找不到,反复试了几次后发现需要重新修改一下CMakeLists.txt的任何地方,编译一次再改回来就好了。
  2. 返回图像时一开始我用的是传像素的方法,传递进来int[],返回的数据也是int[],再转为图片显示,参考《学习《实时Opencv处理后的Camera图像Android NDK方法》笔记》里的那个DEMO方式,结果试了一天多,还是预览的画面不变,到现在没解决,所以改为直接调用的图片方法返回也是图片。

DEMO下载地址

链接:https://pan.baidu.com/s/1EeK8MhqfXjvg8OjSGTnJBw 提取码:h2g7

-END-

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-07-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 微卡智享 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
图像处理
图像处理基于腾讯云深度学习等人工智能技术,提供综合性的图像优化处理服务,包括图像质量评估、图像清晰度增强、图像智能裁剪等。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档