opencv-自定义线性滤波

2019-07-09  本文已影响0人  Peakmain

bitmap和mat之间互转工具类


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

    Mat mat;

    if (info.format == ANDROID_BITMAP_FORMAT_RGBA_8888) {
        LOGE("nMatToBitmap: CV_8UC4 -> RGBA_8888");
        mat = Mat(info.height, info.width, CV_8UC4, pixels);
    } else {
        LOGE("nMatToBitmap: CV_8UC2 -> RGBA_565");
        mat = Mat(info.height, info.width, CV_8UC2, pixels);
    }

    AndroidBitmap_unlockPixels(env, bitmap);
    return mat;
}

/**
 * mat转成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) {
            LOGE("nMatToBitmap: CV_8UC1 -> RGBA_8888");
            cvtColor(src, tmp, COLOR_GRAY2RGBA);
        } else if (src.type() == CV_8UC3) {
            LOGE("nMatToBitmap: CV_8UC3 -> RGBA_8888");
            cvtColor(src, tmp, COLOR_RGB2RGBA);
        } else if (src.type() == CV_8UC4) {
            LOGE("nMatToBitmap: CV_8UC4 -> RGBA_8888");
            src.copyTo(tmp);
        }
    } else {
        // info.format == ANDROID_BITMAP_FORMAT_RGB_565
        Mat tmp(info.height, info.width, CV_8UC2, pixels);
        if (src.type() == CV_8UC1) {
            LOGE("nMatToBitmap: CV_8UC1 -> RGB_565");
            cvtColor(src, tmp, COLOR_GRAY2BGR565);
        } else if (src.type() == CV_8UC3) {
            LOGE("nMatToBitmap: CV_8UC3 -> RGB_565");
            cvtColor(src, tmp, COLOR_RGB2BGR565);
        } else if (src.type() == CV_8UC4) {
            LOGE("nMatToBitmap: CV_8UC4 -> RGB_565");
            cvtColor(src, tmp, COLOR_RGBA2BGR565);
        }
    }

    AndroidBitmap_unlockPixels(env, bitmap);
}

卷积filter2D

把kernel(卷积核)放到我们图像矩阵之上,求锚点周围覆盖像素乘积之和(包括锚点),用来计算锚点的像素值覆盖图片下面的像素值,称为卷积


卷积操作.png

处理边缘类型

自定义线性滤波

    Mat src = bitmap2Mat(env, bitmap);

    Mat dest;
    Mat kernel;
    kernel=(Mat_<int>(2,2)<<1,0,0,-1);
    //depth:值是0-6,type进度的程度
    // 矩阵中元素的一个通道的数据类型,
    // 这个值和type是相关的。例如 type为 CV_16SC2,
    // 一个2通道的16位的有符号整数。那么,depth则是CV_16S。depth也是一系列的预定义值,
    //将type的预定义值去掉通道信息就是depth值:
    //CV_8U用0表示 CV_8S用1表示 CV_16U用2表示 CV_16S用3表示 CV_32S用4表示 CV_32F用5表示 CV_64F用6表示
    filter2D(src,dest,src.depth(),kernel);
    mat2bitmap(env, dest, bitmap);
image.png

左边算子

    Mat src = bitmap2Mat(env, bitmap);
    //转成灰度图
    Mat gray;
    cvtColor(src,gray,COLOR_BGR2GRAY);
    Mat dest;
    Mat kernel;
    kernel=(Mat_<int>(3,3)<<-1,0,1,-2,0,2,-1,0,1);

    filter2D(gray,dest,src.depth(),kernel);
    mat2bitmap(env, gray, bitmap);

右边算子

   Mat src = bitmap2Mat(env, bitmap);

    Mat dest;
    Mat kernel;
    kernel=(Mat_<int>(3,3)<<-1,-2,-1,0,0,0,1,2,1);

    filter2D(src,dest,src.depth(),kernel);
    mat2bitmap(env, dest, bitmap);
    Mat src = bitmap2Mat(env, bitmap);

    Mat dest;
    Mat kernel;
    kernel=(Mat_<int>(3,3)<<0,-1,0,-1,4,-1,0,-1,0);

    filter2D(src,dest,src.depth(),kernel);
    mat2bitmap(env, dest, bitmap);

自定义卷积实现模糊

   //系统的模糊
    Mat dest;
    Mat blur_m;
    blur(src,blur_m,Size(5,5));
    //自定义卷积实现模糊
    int size=5;
    Mat kernel;
    //ones全是1
    kernel=Mat::ones(size,size,CV_32F)/(size*size);
    filter2D(src,dest,src.depth(),kernel);
    mat2bitmap(env, dest, bitmap);

效果图


image.png

图像二值化

图像像素点只有两个值

CV_EXPORTS_W double threshold( InputArray src, OutputArray dst,
                               double thresh, double maxval, int type )

如果当前值大于thresh,则当前像素取maxval,否则取最小值默认是0

    Mat src = bitmap2Mat(env, bitmap);
    Mat gray;
    cvtColor(src,gray,COLOR_BGR2GRAY);
    Mat dest;
    threshold(gray,dest,100,255,THRESH_BINARY);
    mat2bitmap(env, dest, bitmap);
CV_EXPORTS_W double threshold( InputArray src, OutputArray dst,
                               double thresh, double maxval, int type )

如果当前值大于thresh,则当前像素取最小值,否则取maxval

举例使用

    Mat src = bitmap2Mat(env, bitmap);
    Mat gray;
    cvtColor(src,gray,COLOR_BGR2GRAY);
    Mat dest;
    threshold(gray,dest,100,255,THRESH_TRIANGLE);
    mat2bitmap(env, dest, bitmap);
上一篇 下一篇

猜你喜欢

热点阅读