OpenCV 灰度图处理

效果展示

效果展示.png

opencv android sdk

官网:https://opencv.org/android/
sdk下载:https://github.com/opencv/opencv/releases
PS:本文下载的版本是opencv-4.10.0-android-sdk.zip

灰度图处理的思路

分四部
1、创建与原图宽高一样的bitmap
2、在ndk里将bitmap转成c++的mat对象
3、对mat对象进行灰度操作
4、将mat对象转回bitmap

核心代码

#include <jni.h>
#include <string>
#include <android/log.h>
#include <opencv2/opencv.hpp>
#include <android/bitmap.h>

using namespace cv;

//定义TAG之后,我们可以在LogCat通过TAG过滤出NDK打印的日志
#define TAG "JNI_YGQ_DAY05"

// 定义info信息
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,TAG,__VA_ARGS__)
// 定义debug信息
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)
// 定义error信息
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,TAG,__VA_ARGS__)

//bitmap2Mat和mat2bitmap参考的opencv官网源码
//https://github.com/opencv/opencv/blob/4.x/modules/java/generator/src/cpp/utils.cpp

void bitmap2Mat(JNIEnv *env, Mat &mat, jobject bitmap) {
    AndroidBitmapInfo info;
    AndroidBitmap_getInfo(env, bitmap, &info);
    void *pixels = 0;
    AndroidBitmap_lockPixels(env, bitmap, &pixels);

    // CV_8UC4 8位无符号整数的4通道矩阵,对应BGRA格式
    mat.create(info.height, info.width, CV_8UC4);

    if (info.format == ANDROID_BITMAP_FORMAT_RGBA_8888) {
        LOGD("nBitmapToMat: RGBA_8888 -> CV_8UC4");
        Mat tmp(info.height, info.width, CV_8UC4, pixels);
        tmp.copyTo(mat);
    } else if (info.format == ANDROID_BITMAP_FORMAT_RGB_565) {
        LOGD("nBitmapToMat: RGB_565 -> CV_8UC4");
        //8 位无符号整数的 2 通道矩阵
        Mat tmp(info.height, info.width, CV_8UC2, pixels);
        cvtColor(tmp, mat, COLOR_BGR5652RGBA);
    } else {
        LOGE("nBitmapToMat: unSupport format");
    }
    AndroidBitmap_unlockPixels(env, bitmap);
}

void mat2bitmap(JNIEnv *env, Mat &src, jobject bitmap) {
    // 1. 获取图片的宽高,以及格式信息
    AndroidBitmapInfo info;
    AndroidBitmap_getInfo(env, bitmap, &info);
    void *pixels;
    AndroidBitmap_lockPixels(env, bitmap, &pixels);

    if (info.format == ANDROID_BITMAP_FORMAT_RGBA_8888) {
        Mat tmp(info.height, info.width, CV_8UC4, pixels);
        if (src.type() == CV_8UC1) {
            LOGD("nMatToBitmap: CV_8UC1 -> RGBA_8888");
            cvtColor(src, tmp, COLOR_GRAY2RGBA);
        } else if (src.type() == CV_8UC3) {
            LOGD("nMatToBitmap: CV_8UC3 -> RGBA_8888");
            cvtColor(src, tmp, COLOR_RGB2RGBA);
        } else if (src.type() == CV_8UC4) {
            LOGD("nMatToBitmap: CV_8UC4 -> RGBA_8888");
            src.copyTo(tmp);
        }
    } else if (info.format == ANDROID_BITMAP_FORMAT_RGB_565) {
        Mat tmp(info.height, info.width, CV_8UC2, pixels);
        if (src.type() == CV_8UC1) {
            LOGD("nMatToBitmap: CV_8UC1 -> RGB_565");
            cvtColor(src, tmp, COLOR_GRAY2BGR565);
        } else if (src.type() == CV_8UC3) {
            LOGD("nMatToBitmap: CV_8UC3 -> RGB_565");
            cvtColor(src, tmp, COLOR_RGB2BGR565);
        } else if (src.type() == CV_8UC4) {
            LOGD("nMatToBitmap: CV_8UC4 -> RGB_565");
            cvtColor(src, tmp, COLOR_RGBA2BGR565);
        }
    } else {
        LOGE("nMatToBitmap: unSupport format");
    }

    AndroidBitmap_unlockPixels(env, bitmap);
}

extern "C"
JNIEXPORT jboolean JNICALL
Java_com_ygq_ndk_day05_NativeLib_00024Companion_grayTransform(JNIEnv *env, jobject thiz, jobject src, jobject dest) {
    Mat mat;
    bitmap2Mat(env, mat, src);
    Mat mat_gay;
    cvtColor(mat, mat_gay, COLOR_BGRA2GRAY);
    mat2bitmap(env, mat_gay, dest);
    return JNI_TRUE;
}

源码地址

https://github.com/treech/NDKDemo

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容