Android中OpenCV实现图片 浮雕,马赛克,毛玻璃 ,油画效果

这篇我们利用Opencv 实现 浮雕,马赛克,毛玻璃一些简单的效果,因为在Android 实现我们要将Bitmap转Mat给opencv进行操作,opencv操作完图片又要将Mat转化成Bitmap,上篇文章已经讲到Bitmap与Mat的相互转化https://www.jianshu.com/p/c57ee524ad52,在我们实现这些效果的时候其实是对图片的没一个像素点进行操作,接下来我们来看看具体的效果。
浮雕:
浮雕的算法是对图像的每一个点进行卷积处理,采用的矩阵如下
[1 0 0;
0 0 0;
0 0 -1 ];
假设原图src 处理后图像outImg 对于坐标为(row,col)点,其浮雕表达方程式 outImg(row,col) = src (row-1,col-1)-src (row+1,col+1)+128;
还可以用下面这种算子
[1 0
0 -1]
假设原图src 处理后图像outImg 对于坐标为(row,col)点,其浮雕表达方程式 outImg(row,col) = src (row,col)-src (row+1,col+1)+128;
下面代码是用第二种算子实现的浮雕

/**
 * 浮雕
 */
extern "C"
JNIEXPORT void JNICALL
Java_com_youyangbo_opencv_BitmapUtils_relief(JNIEnv *env, jclass type, jobject bitmap) {

    Mat src;
    bitmap2Mat(env, src, bitmap);

    /**
     * [1,0]
     * [0,-1]
     */
    Mat relief(src.size(), src.type());

    for (int row = 1; row < src.rows; ++row) {
        for (int col = 1; col < src.cols; ++col) {
            Vec4b pix_p = src.at<Vec4b>(row - 1, col - 1);
            Vec4b pix_n = src.at<Vec4b>(row, col);
            //b g r a
            relief.at<Vec4b>(row, col)[0] = static_cast<uchar>(pix_p[0] - pix_n[0] + 128);
            relief.at<Vec4b>(row, col)[1] = static_cast<uchar>(pix_p[1] - pix_n[1] + 128);
            relief.at<Vec4b>(row, col)[2] = static_cast<uchar>(pix_p[2] - pix_n[2] + 128);
        }
    }


    mat2Bitmap(env, relief, bitmap);
}
浮雕.jpg

马赛克:
马赛克效果就是把图片分成n*n的小块 n 的取值要适中,下面代码实现是将图片分成很多个8x8的若干个小块,取小块中的第一个点的像素值来填充这个小块来达到马赛克的效果

/**
 * 马赛克
 */
extern "C"
JNIEXPORT void JNICALL
Java_com_youyangbo_opencv_BitmapUtils_mosaic(JNIEnv *env, jclass type, jobject bitmap) {

    Mat src;
    bitmap2Mat(env, src, bitmap);

    int size = 8; //分成8 * 8 的小块 填充相同的颜色

    Mat mosaic= src.clone();

    for (int row = 0; row < src.rows - size; row += size) {
        for (int col = 0; col < src.cols - size; col += size) {

            Vec4b src_pix = src.at<Vec4b>(row, col);

            for (int row_i = 0; row_i < size; ++row_i) {

                for (int col_i = 0; col_i < size; ++col_i) {
                    mosaic.at<Vec4b>(row + row_i, col + col_i) = src_pix;
                }
            }


        }
    }

    mat2Bitmap(env, mosaic, bitmap);
}
马赛克.png

毛玻璃:
毛玻璃效果和马赛克比较相近,下面代码实现是把图片分割成5x5的若干个小块,在小块中取随机点的像素值来填充小块中的点。

/**
 * 毛玻璃效果
 */
extern "C"
JNIEXPORT void JNICALL
Java_com_youyangbo_opencv_BitmapUtils_frostedGlass(JNIEnv *env, jclass type, jobject bitmap) {

    Mat src;
    bitmap2Mat(env, src, bitmap);

    int size = 5; //分成5 * 5的小块 在小块中随机取值填充

    Mat frostedGlass = src.clone();

    RNG rng((unsigned) time(NULL));

    for (int row = 0; row < src.rows - size; ++row) {
        for (int col = 0; col < src.cols - size; ++col) {
            int roandnumber = rng.uniform(0, size);
            frostedGlass.at<Vec4b>(row, col)[0] = src.at<Vec4b>(row + roandnumber, col + roandnumber)[0];
            frostedGlass.at<Vec4b>(row, col)[1] = src.at<Vec4b>(row + roandnumber, col + roandnumber)[1];
            frostedGlass.at<Vec4b>(row, col)[2] = src.at<Vec4b>(row + roandnumber, col + roandnumber)[2];
        }
    }

    mat2Bitmap(env, frostedGlass, bitmap);


}
毛玻璃.png

油画效果:
是通过像素权重实现图像的像素模糊从而达到近似油画效果模糊,(直方统计)
具体的
1.把(0~255)灰度值均分成n个区间
2.遍历图像的每个像素点 将模板范围内的所有像素值进一步离散化,根据像素的灰度落入不同的区间,
3.找到落入像素最多的一个区间 并桶对该区间中的所有像素求出颜色平均值 作为位置 (x, y) 的结果值

extern "C"
JNIEXPORT void JNICALL
Java_com_youyangbo_opencv_BitmapUtils_oilPaintI(JNIEnv *env, jclass type, jobject bitmap) {

    Mat src;
    bitmap2Mat(env, src, bitmap);

    Mat gray;
    cvtColor(src, gray, COLOR_BGRA2GRAY);

    Mat res = src.clone();

    const int g_size = 5;
    const int t_size = 8;

    for (int row = 0; row < src.rows - t_size; ++row) {
        for (int col = 0; col < src.cols - t_size; ++col) {
            //统计灰度等级
            int grade[g_size + 1] = {0};
            int b[g_size + 1] = {0};
            int g[g_size + 1] = {0};
            int r[g_size + 1] = {0};
            for (int t_row = 0; t_row < t_size; ++t_row) {
                for (int t_col = 0; t_col < t_size; ++t_col) {

                    uchar gray_value = gray.at<uchar>(row + t_row, col + t_col);
                    int grade_index = gray_value / (255 / g_size);
                    grade[grade_index] += 1;

                    b[grade_index] += src.at<Vec4b>(row + t_row, col + t_col)[0];
                    g[grade_index] += src.at<Vec4b>(row + t_row, col + t_col)[1];
                    r[grade_index] += src.at<Vec4b>(row + t_row, col + t_col)[2];

                }

            }

            //找出最多落入像素最多的一个等级
            int max_index = 0;
            int max = grade[0];
            for (int index = 1; index <= g_size; ++index) {
                if (grade[index] > max) {
                    max_index = index;
                    max = grade[index];
                }
            }

            //求取这个等级的平均值

            res.at<Vec4b>(row, col)[0] = b[max_index] / max;
            res.at<Vec4b>(row, col)[1] = g[max_index] / max;
            res.at<Vec4b>(row, col)[2] = r[max_index] / max;

        }
    }

    mat2Bitmap(env, res, bitmap);


}
油画效果.jpg
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,607评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,239评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,960评论 0 355
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,750评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,764评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,604评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,347评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,253评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,702评论 1 315
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,893评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,015评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,734评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,352评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,934评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,052评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,216评论 3 371
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,969评论 2 355

推荐阅读更多精彩内容