为了账号安全,请及时绑定邮箱和手机立即绑定

opencv在android平台下的开发【3】-图像平滑处理

标签:
Android

基本概念
图像的平滑也就是图像的模糊处理,简单但是使用频率很高,在执行许多高级处理之前都需要先进性图像的平滑处理,以提高图像处理算法效果。

平滑处理中需要使用滤波器,常用的是线性滤波器,作用是将输入像素值的加权和作为结果输出给锚点像素。

g(i,j) 为输出的锚点像素值;f(i+k,j+l) 为输入的像素值;h(k,l) 为核

https://img1.sycdn.imooc.com//5d3281580001561302800063.jpg

image

滤波过程示例:

https://img1.sycdn.imooc.com//5d32816100017bdd05080347.jpg

image

图像读入到mat

介绍平滑算法之前,先调用android自带图库,选择一张图片后返回到app中,保存在一个mat对象里。

        //点击按钮,启动图库
        btnLoadImg.setOnClickListener(new View.OnClickListener() {            @Override
            public void onClick(View v) {
                Intent imgPickerIntent = new Intent(Intent.ACTION_PICK);
                imgPickerIntent.setType("image/*");
                startActivityForResult(imgPickerIntent, REQ_CODE_PICK_IMG);
            }
        });        
        
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {        super.onActivityResult(requestCode, resultCode, data);        if (requestCode == REQ_CODE_PICK_IMG) {            if (resultCode == RESULT_OK) {                try {                    //获取图库选择的图像
                    final Uri imgUri = data.getData();                    final InputStream inputStream = getContentResolver().openInputStream(imgUri);                    //图像输入流解析为bitmap对象
                    final Bitmap originImg = BitmapFactory.decodeStream(inputStream);                    //根据bitmap信息初始化mat对象
                    src = new Mat(originImg.getHeight(), originImg.getWidth(), CvType.CV_8UC4);                    //将bitmap转换为mat对象
                    Utils.bitmapToMat(originImg, src);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
            }
        }
    }

另外,图像保存在mat对象中,所以还需要一个显示mat对象图像的方法。

    private void showMat() {        //根据mat对象信息初始化bitmap
        Bitmap processedImg = Bitmap.createBitmap(src.cols(), src.rows(), Bitmap.Config.ARGB_8888);        //将mat对象转换到bitmap
        Utils.matToBitmap(src, processedImg);        //显示
        imgProcess.setImageBitmap(processedImg);
    }

均值模糊

使用归一化块滤波器,也是最简单的滤波器,输出像素值是核窗口内像素的均值,即所有像素加权系数相等。

核如下:

https://img1.sycdn.imooc.com//5d32816d0001dcfd03490139.jpg

image

opencv-android sdk 提供的方法如下

    /**
     * 均值模糊
     * @param src 源图像mat
     * @param dst 目标图像mat
     * @param ksize 核大小
     */
    public static void blur(Mat src, Mat dst, Size ksize)
    {        //sdk封装的一个jni方法,具体的实现在.so库中用c/c++实现
        blur_2(src.nativeObj, dst.nativeObj, ksize.width, ksize.height);        
        return;
    }

方法使用如下:

Imgproc.blur(src, src, new Size(3, 3));
showMat();

高斯模糊

高斯滤波器是最有用的滤波器(不是最快),将输入的每一个像素点与高斯内核的卷积核作为输出像素值。

高斯模糊中,距离锚点像素越近的输入像素权重越高,即临近锚点像素对像素结果的影响比那些较远的像素要高。

https://img1.sycdn.imooc.com//5d32817d00016f3d03690169.jpg

image

高斯核是通过高斯函数获得的

https://img1.sycdn.imooc.com//5d3281860001734b03610085.jpg

image

opencv-android sdk 提供的方法如下

    //javadoc: GaussianBlur(src, dst, ksize, sigmaX)
    public static void GaussianBlur(Mat src, Mat dst, Size ksize, double sigmaX)
    {        //sdk封装的一个jni方法,具体的实现在.so库中用c/c++实现
        GaussianBlur_2(src.nativeObj, dst.nativeObj, ksize.width, ksize.height, sigmaX);        
        return;
    }

方法使用

Imgproc.GaussianBlur(src, src, new Size(3, 3), 0);
showMat();

中值滤波

中值滤波是将图像的每个像素用邻域像素的中值代替。

opencv-android sdk 提供的方法如下

    //javadoc: medianBlur(src, dst, ksize)
    public static void medianBlur(Mat src, Mat dst, int ksize)
    {
        
        medianBlur_0(src.nativeObj, dst.nativeObj, ksize);        
        return;
    }

方法使用

Imgproc.medianBlur(src, src, 3);
showMat();



作者:昵称真难选
链接:https://www.jianshu.com/p/b3c2d50f9d73


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消