Android OpenCV(二十):高斯滤波

高斯滤波

高斯滤波是一种线性平滑滤波,适用于消除高斯噪声,广泛应用于图像处理的减噪过程。 通俗的讲,高斯滤波就是对整幅图像进行加权平均的过程,每一个像素点的值,都由其本身和邻域内的其他像素值经过加权平均后得到。高斯滤波的具体操作是:用一个模板(或称卷积、掩模)扫描图像中的每一个像素,用模板确定的邻域内像素的加权平均灰度值去替代模板中心像素点的值。

高斯滤波是利用高斯核的一个2维的卷积算子,用于图像模糊化(去除细节和噪声)。

API

public static void GaussianBlur(Mat src, Mat dst, Size ksize, double sigmaX, double sigmaY, int borderType)
  • 参数一:src,待高斯滤波图像,图像可以具有任意的通道数目,但是数据类型必须为CV_8U,CV_16U,CV_16S,CV_32F或CV_64F。
  • 参数二:dst,输出图像,与输入图像src具有相同的尺寸、通道数和数据类型。
  • 参数四:ksize,高斯滤波器的尺寸,滤波器可以不为正方形,但是必须是正奇数。如果尺寸为0,则由标准偏差计算尺寸。
  • 参数五:sigmaX,X方向的高斯滤波器标准偏差。
  • 参数六:sigmaY,Y方向的高斯滤波器标准偏差; 如果输入量为0,则将其设置为等于sigmaX,如果两个轴的标准差均为0,则根据输入的高斯滤波器尺寸计算标准偏差。
  • 参数七:borderType,像素外推法选择标志。默认参数为BORDER_DEFAULT,表示不包含边界值倒序填充。

操作

/**
 * 高斯滤波
 * author: yidong
 * 2020/4/25
 */
class GaussianFilterActivity: AppCompatActivity() {

    private lateinit var mBinding: ActivityGaussianFilterBinding
    private lateinit var mRgb: Mat

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mBinding = DataBindingUtil.setContentView(this, R.layout.activity_gaussian_filter)
        val bgr = Utils.loadResource(this, R.drawable.lena)
        mRgb = Mat()
        Imgproc.cvtColor(bgr, mRgb, Imgproc.COLOR_BGR2RGB)
        bgr.release()
        showMat(mBinding.ivLena, mRgb)
    }

    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        menuInflater.inflate(R.menu.menu_gaussian_filter, menu)
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when (item.itemId) {
            R.id.menu_5_5 -> {
                showMat(mBinding.ivLena, mRgb)

                val result = Mat()
                Imgproc.GaussianBlur(mRgb, result, Size(5.0, 5.0), 10.0, 20.0)
                showMat(mBinding.ivResult, result)
                result.release()
            }
            R.id.menu_9_9 -> {
                showMat(mBinding.ivLena, mRgb)

                val result = Mat()
                Imgproc.GaussianBlur(mRgb, result, Size(9.0, 9.0), 10.0, 20.0)
                showMat(mBinding.ivResult, result)
                result.release()
            }
            R.id.menu_salt_pepper_noise_9_9 -> {
                saltPepperNoiseAndMeanFilter(9.0)
            }
            R.id.menu_salt_pepper_noise_5_5 -> {
                saltPepperNoiseAndMeanFilter(5.0)
            }
            R.id.menu_gaussian_noise_9_9 -> {
                gaussianNoiseAndMeanFilter(9.0)
            }
            R.id.menu_gaussian_noise_5_5 -> {
                gaussianNoiseAndMeanFilter(5.0)
            }
        }
        return true
    }

    private fun saltPepperNoiseAndMeanFilter(size:Double) {
        val source = mRgb.clone()
        val number = 10000
        for (k in 0..number) {
            val i = (0..1000).random() % source.cols()
            val j = (0..1000).random() % source.rows()
            when ((0..100).random() % 2) {
                0 -> {
                    when (source.channels()) {
                        1 -> {
                            source.put(j, i, 255.0)
                        }
                        2 -> {
                            source.put(j, i, 255.0, 255.0)
                        }
                        3 -> {
                            source.put(j, i, 255.0, 255.0, 255.0)
                        }
                        else -> {
                            source.put(j, i, 255.0, 255.0, 255.0, 255.0)
                        }
                    }
                }
                1 -> {
                    when (source.channels()) {
                        1 -> {
                            source.put(j, i, 0.0)
                        }
                        2 -> {
                            source.put(j, i, 0.0, 0.0)
                        }
                        3 -> {
                            source.put(j, i, 0.0, 0.0, 0.0)
                        }
                        else -> {
                            source.put(j, i, 0.0, 0.0, 0.0, 0.0)
                        }
                    }
                }
            }
        }
        showMat(mBinding.ivLena, source)

        val result = Mat()
        Imgproc.GaussianBlur(mRgb, result, Size(size, size), 10.0, 20.0)
        showMat(mBinding.ivResult, result)

        result.release()
        source.release()
    }

    private fun gaussianNoiseAndMeanFilter(size:Double) {
        val source = mRgb.clone()
        val noise = Mat(source.size(), source.type())
        val gaussian = Mat()
        Core.randn(noise, 20.0, 50.0)
        Core.add(source, noise, gaussian)
        showMat(mBinding.ivLena, gaussian)

        val result = Mat()
        Imgproc.GaussianBlur(mRgb, result, Size(size, size), 10.0, 20.0)
        showMat(mBinding.ivResult, result)

        source.release()
        noise.release()
        gaussian.release()
        result.release()
    }

    private fun showMat(view: ImageView, source: Mat) {
        val bitmap = Bitmap.createBitmap(source.width(), source.height(), Bitmap.Config.ARGB_8888)
        Utils.matToBitmap(source, bitmap)
        view.setImageBitmap(bitmap)
    }

    override fun onDestroy() {
        mRgb.release()
        super.onDestroy()
    }
}

效果

高斯滤波

可以很明显的看到,针对椒盐噪声或者高斯噪声,5*5的高斯核就能起到很好的抑制作用,并且图片不会太模糊

源码

https://github.com/onlyloveyd/LearningAndroidOpenCV

扫码关注,持续更新

回复【计算机视觉】获取计算机视觉相关必备学习资料
回复【Android】获取Android,Kotlin必备学习资料

原创文章 179 获赞 272 访问量 34万+

猜你喜欢

转载自blog.csdn.net/poorkick/article/details/105744281
今日推荐