美文网首页
opencv-自定义线性滤波

opencv-自定义线性滤波

作者: Peakmain | 来源:发表于2019-07-09 11:39 被阅读0次

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

处理边缘类型

  • BORDER_CONSTANT:常量,用一个指定颜色填充,默认是黑色
  • BORDER_REPLICATE :周边像素来填充
  • BORDER_WRAP :对边填充
  • BORDER_DEFAULT:用周边边缘填充

自定义线性滤波

  • Robert算子


    image.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);
  • soble算子
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);
  • 拉普拉斯算子
    图片要求比较高


    image.png
    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

图像二值化

图像像素点只有两个值

  • THRESH_BINARY:
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);
  • THRESH_BINARY_INV:
CV_EXPORTS_W double threshold( InputArray src, OutputArray dst,
                               double thresh, double maxval, int type )

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

  • THRESH_TRUNC
    如果当前值大于thresh,则当前像素取thresh,否则取原来的值

  • THRESH_TOZERO
    如果当前值大于thresh,则当前像素取原来的值,否则取最小值

  • THRESH_TOZERO_INV
    如果当前值大于thresh,则当前像素取最小值,否则取原来的值

  • THRESH_OTSU
    自动阈值:取每个像素点(整个图像)计算一个thresh值

  • THRESH_TRIANGLE
    自动阈值:取每个像素点(整个图像)计算一个thresh值

举例使用

    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);

相关文章

网友评论

      本文标题:opencv-自定义线性滤波

      本文链接:https://www.haomeiwen.com/subject/wpmshctx.html