Android OpenCV(十八):均值滤波

Stella981
• 阅读 545

均值滤波

均值滤波也称为线性滤波,其采用的主要方法为邻域平均法。线性滤波的基本原理是用均值代替原图像中的各个像素值,即对待处理的当前像素点(x,y),选择一个模板,该模板由其近邻的若干像素组成,求模板中所有像素的均值,再把该均值赋予当前像素点(x,y),作为处理后图像在该点上的灰度g(x,y),即g(x,y)=∑f(x,y)/m m为该模板中包含当前像素在内的像素总个数。从频率域观点来看均值滤波是一种低通滤波器,高频信号将会去掉,因此可以帮助消除图像尖锐噪声,实现图像平滑,模糊等功能。

从均值滤波的定义上看,滤波操作也是进行图像卷积运算。均值滤波使用到的卷积核如下
Android OpenCV(十八):均值滤波

API

public static void blur(Mat src, Mat dst, Size ksize, Point anchor, int borderType)
  • 参数一:src,待均值滤波的图像,图像的数据类型必须是CV_8U、CV_16U、CV_16S、CV_32F和CV_64F这五种数据类型之一。

  • 参数二:dst,均值滤波后的图像,与输入图像具有相同的尺寸和数据类型。

  • 参数三:ksize,卷积核尺寸。

  • 参数四:anchor,内核的基准点(锚点),其默认值为(-1,-1)代表内核基准点位于kernel的中心位置。基准点即卷积核中与进行处理的像素点重合的点,其位置必须在卷积核的内部。

  • 参数五:borderType,像素外推法选择标志。默认参数为BORDER_DEFAULT,表示不包含边界值倒序填充。

边界填充

作用

BORDER_CONSTANT

0

用特定值填充,如iiiiii|abcdefgh|iiiiiii

BORDER_REPLICATE

1

两端复制填充,如aaaaaa|abcdefgh|hhhhhhh

BORDER_REFLECT

2

倒叙填充,如fedcba|abcdefgh|hgfedcb

BORDER_WRAP

3

正序填充,如cdefgh|abcdefgh|abcdefg

BORDER_REFLECT_101

4

不包含边界值倒叙填充,gfedcb|abcdefgh|gfedcba

BORDER_TRANSPARENT

5

随机填充,uvwxyz|abcdefgh|ijklmno

BORDER_REFLECT101

4

与BORDER_REFLECT_101相同

BORDER_DEFAULT

4

与BORDER_REFLECT_101相同

BORDER_ISOLATED

16

不关心感兴趣区域之外的部分

操作

/** * 均值滤波 * author: yidong * 2020/4/11 */class MeanFilterActivity : AppCompatActivity() {    private lateinit var mBinding: ActivityMeanFilterBinding    private lateinit var mRgb: Mat    override fun onCreate(savedInstanceState: Bundle?) {        super.onCreate(savedInstanceState)        mBinding = DataBindingUtil.setContentView(this, R.layout.activity_mean_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_mean_filter, menu)        return true    }    override fun onOptionsItemSelected(item: MenuItem): Boolean {        when (item.itemId) {            R.id.menu_3_3 -> {                showMat(mBinding.ivLena, mRgb)                val result = Mat()                Imgproc.blur(mRgb, result, Size(3.0, 3.0))                showMat(mBinding.ivResult, result)                result.release()            }            R.id.menu_9_9 -> {                showMat(mBinding.ivLena, mRgb)                val result = Mat()                Imgproc.blur(mRgb, result, Size(9.0, 9.0))                showMat(mBinding.ivResult, result)                result.release()            }            R.id.menu_12_12 -> {                showMat(mBinding.ivLena, mRgb)                val result = Mat()                Imgproc.blur(mRgb, result, Size(12.0, 12.0))                showMat(mBinding.ivResult, result)                result.release()            }            R.id.menu_salt_pepper_noise -> {                saltPepperNoiseAndMeanFilter()            }            R.id.menu_gaussian_noise -> {                gaussianNoiseAndMeanFilter()            }        }        return true    }    private fun saltPepperNoiseAndMeanFilter() {        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.blur(source, result, Size(9.0, 9.0))        showMat(mBinding.ivResult, result)        result.release()        source.release()    }    private fun gaussianNoiseAndMeanFilter() {        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.blur(gaussian, result, Size(9.0, 9.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()    }}

效果

建议直接运行代码查看效果,更清晰更直观。

图片效果

Android OpenCV(十八):均值滤波

均值滤波3X3

Android OpenCV(十八):均值滤波

均值滤波9X9

Android OpenCV(十八):均值滤波

均值滤波12X12

Android OpenCV(十八):均值滤波

椒盐噪声和均值滤波9X9

Android OpenCV(十八):均值滤波

高斯噪声和均值滤波9X9

GIF

Android OpenCV(十八):均值滤波

均值滤波

源码

https://github.com/onlyloveyd/LearningAndroidOpenCV

本文分享自微信公众号 - 微卡智享(VaccaeShare)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Stella981 Stella981
2年前
OpenCV 之 空间滤波
1 空间滤波 1.1 基本概念空间域,在图像处理中,指的是像平面本身;空间滤波,则是在像平面内,对像素值所进行的滤波处理。!(https://oscimg.oschina.net/oscnet/0daafa04976ff550daa79ae366f301bdfac.png)如上图所示,假
Wesley13 Wesley13
2年前
FLV文件格式
1.        FLV文件对齐方式FLV文件以大端对齐方式存放多字节整型。如存放数字无符号16位的数字300(0x012C),那么在FLV文件中存放的顺序是:|0x01|0x2C|。如果是无符号32位数字300(0x0000012C),那么在FLV文件中的存放顺序是:|0x00|0x00|0x00|0x01|0x2C。2.  
Stella981 Stella981
2年前
Python之time模块的时间戳、时间字符串格式化与转换
Python处理时间和时间戳的内置模块就有time,和datetime两个,本文先说time模块。关于时间戳的几个概念时间戳,根据1970年1月1日00:00:00开始按秒计算的偏移量。时间元组(struct_time),包含9个元素。 time.struct_time(tm_y
Stella981 Stella981
2年前
Android OpenCV(二十):高斯滤波
高斯滤波高斯滤波是一种线性平滑滤波,适用于消除高斯噪声,广泛应用于图像处理的减噪过程。通俗的讲,高斯滤波就是对整幅图像进行加权平均的过程,每一个像素点的值,都由其本身和邻域内的其他像素值经过加权平均后得到。高斯滤波的具体操作是:用一个模板(或称卷积、掩模)扫描图像中的每一个像素,用模板确定的邻域内像素的加权平均灰度值去替代模板中心像素点的值
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Stella981 Stella981
2年前
Python OpenCV学习笔记之:图像滤波处理
\\coding:utf8\图像滤波'''图像处理也支持低通滤波(LPF)和高通滤波(HPF)处理OpenCV提供filter2D函数对图像进行滤波处理'''importcv2ascvimportnumpyasnpimportmatplotlib.pyplotasplt读取图像img
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这