android 应用opencv 对图片的处理

android 专栏收录该内容
1 篇文章 0 订阅

       OpenCV是跨平台的强大的计算机视觉识别和图像处理的开源库,可以利用他来实现:模式识别、构建神经网络、深度学习。入门级的同学,就只能先拿来做图片处理。

       但是要做好图片处理也是很难的,发现很多东西需要学习。

        android引用opencv,进行ndk配置开始走了很多弯路,github上的很多代码下载了也根本运行不了,折腾了几天才终于运行起来。

        这里附上github的代码地址,大家有兴趣可以看看 https://github.com/graceyeqing/OpenCV_Image

        不多说废话,直接上图片处理效果图和代码。这里只列了7种效果,代码中会包含更多。(部分算法参照了网上的一些文章,有的特效效果可能不是很好,可以通过调节参数自己去试一下)

一、油画

//油画
extern "C"
JNIEXPORT jobject JNICALL
Java_com_yq_opencv_1image_OpencvImageUtil_oilPaiting(JNIEnv *env, jclass type, jobject bitmap) {

    Mat src;
    BitmapToMat(env, bitmap, src);
    //这里进行图像相关操作
    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;
        }
    }
    MatToBitmap(env, res, bitmap);
    return bitmap;

}

二、马赛克

//马赛克
extern "C"
JNIEXPORT jobject JNICALL
Java_com_yq_opencv_1image_OpencvImageUtil_mosaic(JNIEnv *env, jclass type, jobject bitmap) {
    Mat src;
    BitmapToMat(env, bitmap, src);
    LOGD("nBitmapToMat: BitmapToMat finish");
    int size = 10; //分成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;
                }
            }
        }
    }
    LOGD("nBitmapToMat:mosaic");
    MatToBitmap(env, mosaic, bitmap);
    return bitmap;
}

 三、浮雕

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

    Mat src;
    BitmapToMat(env, bitmap, src);
    //这里进行图像相关操作
    /**
    * [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);
        }
    }
    MatToBitmap(env, relief, bitmap);
    return bitmap;

}

 四、轮廓图

//轮廓图
extern "C"
JNIEXPORT jobject JNICALL
Java_com_yq_opencv_1image_OpencvImageUtil_canary(JNIEnv *env, jclass type, jobject bitmap) {

    Mat src;
    BitmapToMat(env, bitmap, src);
    //这里进行图像相关操作
    cv::cvtColor(src, src, COLOR_BGRA2GRAY);
    cv::GaussianBlur(src, src, Size(3, 3), 0, 0, BORDER_DEFAULT);
    //调用Canny 方法实现边缘检测
    cv::Canny(src, src, 50, 150, 3, false);
    MatToBitmap(env, src, bitmap);
    return bitmap;

}

 五、图像叠加

//图像叠加
extern "C"
JNIEXPORT jobject JNICALL
Java_com_yq_opencv_1image_OpencvImageUtil_add(JNIEnv *env, jclass type, jobject bitmap,
                                              jobject bitmap2) {

    Mat src;
    BitmapToMat(env, bitmap, src);
    Mat src2;
    BitmapToMat(env, bitmap2, src2);
    //这里进行图片的处理
    addWeighted(src,0.7,src2,0.3,0.0,src);
    MatToBitmap(env, src, bitmap);
    return bitmap;

}

 六、图像增强

 

//直方图均衡化
extern "C"
JNIEXPORT jobject JNICALL
Java_com_yq_opencv_1image_OpencvImageUtil_equalizeHist(JNIEnv *env, jclass type, jobject bitmap) {

    Mat src;
    BitmapToMat(env, bitmap, src);
    //这里进行图片的处理
    Mat imgRGB[3];
    split(src, imgRGB);
    //针对每个通道进行直方图均衡化
    for (int i = 0; i < 3; i++) {
        equalizeHist(imgRGB[i], imgRGB[i]);
    }
    //合并图像
    merge(imgRGB, 3, src);

    MatToBitmap(env, src, bitmap);
    return bitmap;
}

 七、图像扭曲

//图像扭曲
extern "C"
JNIEXPORT jobject JNICALL
Java_com_yq_opencv_1image_OpencvImageUtil_warping(JNIEnv *env, jclass type, jobject bitmap) {

    Mat src;
    BitmapToMat(env, bitmap, src);
    //这里进行图片的处理
    Point2f srcTri[3];
    Point2f dstTri[3];

    Mat warp_mat(2, 3, CV_32FC1);
    //设置三个点来计算仿射变换
    srcTri[0] = Point2f(0, 0);
    srcTri[1] = Point2f(src.cols - 1, 0);
    srcTri[2] = Point2f(0, src.rows - 1);

    dstTri[0] = Point2f(src.cols*0.0, src.rows*0.33);
    dstTri[1] = Point2f(src.cols*0.85, src.rows*0.25);
    dstTri[2] = Point2f(src.cols*0.15, src.rows*0.7);

    //计算仿射变换矩阵
    warp_mat = getAffineTransform(srcTri, dstTri);
   //创建仿射变换目标图像与原图像尺寸类型相同
    Mat warp_dstImage = Mat::zeros(src.rows, src.cols, src.type());
    cv::warpAffine(src,src,warp_mat,warp_dstImage.size());

    MatToBitmap(env, src, bitmap);
    return bitmap;

}

 

  • 0
    点赞
  • 0
    评论
  • 2
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值