原理

中值滤波是空域中常用的一种滤波方式,是一种非线性的滤波。它的原理就是将窗口像素排序,取中值,然后移动窗口,不断重复取中值的过程

但是,可以发现,每次移动窗口,都需要对像素点进行排序,从而选取中间的那个像素点。每次重新排序的效率特别低,为了优化这个排序,便有了快速中值滤波。

快速中值滤波是中值滤波的优化版,它利用了窗口每次平移时,没有移出窗口的像素点还是排好序的,因此,只需要把新加入的像素点插入到其中即可完成排序。此外,由于我们并不需要一个完整的排序数列, 只需要找到中值就可以了。

基于上面两点,快速中值滤波采用的是直方图的方式来统计像素点,横坐标是像素点的值,纵坐标是窗口中像素点的个数。设置一个“光标”,在横轴上左右移动,当两边像素点相等时,对应的像素点就是要找的中值。然后移动窗口,更新直方图,再次移动“光标”,找到中值,不断反复。

需要注意的是,“光标”的每次移动,都只能移动在数目不为 0 的像素点上,否则,取到的中值很可能不在这个窗口中。

步骤

  • 第一步:
    设置门限th = N*M/2。门限是用来判断像素点是否是中值的,它是窗口大小的一半,如果不知道有啥用,看第五步的用法。

  • 第二步:
    将窗口移动到一个新行的开始,建立窗口像素的直方图,通过直方图确定中值 med,记下亮度小于或等于 med 的像素数目到变量 n 中。

  • 第三步:
    对于最左列的每个像素,去掉每一个元素,并将直方图中的相应的数值更新,然后更新n的值。

  • 第四步:
    同理,与第三步一样,对于最右列的每个像素,增加每一个元素的值,并将直方图中的相应的数值进行更新。

  • 第五步:
    然后判断n的值与门限 th 的大小。如果 n > th,则将 med 进行递减操作;如果n < th 则将 med 进行递增操作。直到 n 超过 th 为止。得到的 med 就是需要的中值。

代码

R、G、B 三个通道分别计算(可以一起计算,但单通道计算更清晰)

窗口大小为 3*3 的代码:

# -*- coding: UTF-8 -*-
import numpy as np
import cv2def quickMedianFiltering(img) :B, G, R = cv2.split(img)# 对 蓝色通道 进行中值滤波H = np.zeros(256, dtype=int)    # 直方图for row in range(1, len(B) - 1) :# 到达一个新的行 初始化H = np.zeros(256, dtype=int)    # 直方图# 求中值med = np.uint8(np.median(B[row - 1 : row + 2, 0:3]))n = 0for i in range(-1, 2) :for j in range(0, 3) :H[B[row+i][j]] = H[B[row+i][j]] + 1if B[row+i][j] <= med :n = n + 1for col in range(1, len(B[row]) - 1) :if col == 1 :None# 移到下一列else :# 更新直方图 并计算 n 的值for i in range(-1, 2) :# 对左列元素 值减一 H[B[row+i][col-2]] = H[B[row+i][col-2]] - 1if B[row+i][col-2] <= med :n = n - 1# 对右列元素 值加一H[B[row+i][col+1]] = H[B[row+i][col+1]] + 1if B[row+i][col+1] <= med :n = n + 1# 重新计算中值if n > 5 :while n > 5 :if med == 0 :breakn = n - H[med]med = med - 1elif n < 5 :while n < 5 :med = med + 1n = n + H[med]sum = 0for k in range(med + 1) :sum = sum + H[k]# 更新中值后的直方图H[B[row][col]] = H[B[row][col]] - 1if med < B[row][col] :n = n + 1B[row][col] = medH[med] = H[med] + 1# 对 绿色通道 进行中值滤波H = np.zeros(256, dtype=int)    # 直方图for row in range(1, len(G) - 1) :# 到达一个新的行 初始化H = np.zeros(256, dtype=int)    # 直方图# 求中值med = np.uint8(np.median(G[row - 1 : row + 2, 0:3]))if med == -128 :print(G[row - 1 : row + 2, 0:3])n = 0for i in range(-1, 2) :for j in range(0, 3) :H[G[row+i][j]] = H[G[row+i][j]] + 1if G[row+i][j] <= med :n = n + 1for col in range(1, len(G[row]) - 1) :if col == 1 :None# 移到下一列else :# 更新直方图 并计算 n 的值for i in range(-1, 2) :# 对左列元素 值减一 H[G[row+i][col-2]] = H[G[row+i][col-2]] - 1if G[row+i][col-2] <= med :n = n - 1# 对右列元素 值加一H[G[row+i][col+1]] = H[G[row+i][col+1]] + 1if G[row+i][col+1] <= med :n = n + 1# 重新计算中值if n > 5 :while n > 5 :if med == 0 :breakn = n - H[med]med = med - 1elif n < 5 :while n < 5 :med = med + 1n = n + H[med]# 更新中值后的直方图H[G[row][col]] = H[G[row][col]] - 1if med < G[row][col] :n = n + 1G[row][col] = medH[med] = H[med] + 1# 对 红色通道 进行中值滤波H = np.zeros(256, dtype=int)    # 直方图for row in range(1, len(R) - 1) :# 到达一个新的行 初始化H = np.zeros(256, dtype=int)    # 直方图# 求中值med = np.uint8(np.median(R[row - 1 : row + 2, 0:3]))if med == -128 :print(R[row - 1 : row + 2, 0:3])n = 0for i in range(-1, 2) :for j in range(0, 3) :H[R[row+i][j]] = H[R[row+i][j]] + 1if R[row+i][j] <= med :n = n + 1for col in range(1, len(R[row]) - 1) :if col == 1 :None# 移到下一列else :# 更新直方图 并计算 n 的值for i in range(-1, 2) :# 对左列元素 值减一 H[R[row+i][col-2]] = H[R[row+i][col-2]] - 1if R[row+i][col-2] <= med :n = n - 1# 对右列元素 值加一H[R[row+i][col+1]] = H[R[row+i][col+1]] + 1if R[row+i][col+1] <= med :n = n + 1# 重新计算中值if n > 5 :while n > 5 :if med == 0 :breakn = n - H[med]med = med - 1elif n < 5 :while n < 5 :med = med + 1n = n + H[med]sum = 0# 更新中值后的直方图H[R[row][col]] = H[R[row][col]] - 1if med < R[row][col] :n = n + 1R[row][col] = medH[med] = H[med] + 1return cv2.merge([B,G,R])

最后

快速中值滤波主要是利用了直方图的思想,虽然思路很简单,但写代码的时候,也遇到不少bug,所幸最后写完了。

如果有任何错误的地方,请联系我改正,非常感谢。

快速中值滤波——Python实现相关推荐

  1. (MATLAB/C/Python)快速中值滤波

    (MATLAB/C/Python)快速中值滤波 一.中值滤波 二.快速中值滤波 介绍 原理 优化 三.代码 MATLAB C Python 四.测试 其他 by HPC_ZY 最近一个项目中需要用到中 ...

  2. 直方图实现快速中值滤波opencv

    中值滤波能够有效去除图像中的异常点,具有去除图像噪声的作用.传统中值滤波的算法一般都是在图像中建立窗口,然后对窗口内的所有像素值进行排序,选择排序后的中间值作为窗口中心像素滤波后的值.由于这个做法在每 ...

  3. 快速中值滤波在心电图ECG中的应用

    1.算法介绍和实现 首先来搞明白,什么是快速中值滤波? 快速中值滤波非常简单,就是用过去连续N个数据,再对这N个数据进行排序,取排序后的中间那个数据,做为当前的输出,N即为窗口的长度. 算法实现: 1 ...

  4. OpenCV图像处理专栏九 | 基于直方图的快速中值滤波算法

    转载自:https://zhuanlan.zhihu.com/p/98092747  侵删 前言 这是OpenCV图像处理专栏的第9篇文章,主要介绍一个基于直方图的快速中值滤波算法,希望对大家有帮助. ...

  5. matlab实现 中值滤波去除基线漂移,快速中值滤波在滤除心电信号基线漂移中的应用...

    [摘要]文中给出了一种非线性的滤除心电信号基线漂移的滤波方法,把基于排序统计理论的快速中值滤波方法应用于处理心电信号,通过多次对心电信号中选择的窗口数据进行排序,然后取中值的方法来达到滤波的效果.试验 ...

  6. 高效快速中值滤波算法c语言,快速中值滤波及c语言实现.docx

    . .. 快速中值滤波及c语言实现 学生姓名: 刘 勇 学 号: 6100410218 专业班级: 数媒101 [摘要]本文讨论了用c语言在微机上实现中值滤波及快速算法,在程序设计的过程中充分考虑到程 ...

  7. 图像中值滤波python代码_图像中值滤波FPGA实现

    C语言实用数字图像处理.pdf6.34 MB05-11-13|19:30 FPGA实验报告-李炎东.doc633.66 kB16-01-14|10:28 中值滤波在红外成像引信中的应用及硬件实现.ca ...

  8. 数图:中值滤波python实现

    心累,花了一下午写这个 我已经是个大四老咸鱼了,就把代码放出来造福看到的小鲜肉吧(滑稽) import numpy as np #from compiler.ast import flatten 偷懒 ...

  9. 实时高速实现改进型中值滤波算法_爱学术_免费下载

    [摘要]在图像采集和处理过程中会引入噪声,必须先对图像进行预处理.本文介绍一种快速中值滤波算法,该算法在硬件平台上实现实时处理功能.综合考虑,选择现场可编程门阵列(FPGA)作为硬件平台,采用硬件描述 ...

最新文章

  1. Java基础知识强化之集合框架笔记76:ConcurrentHashMap之 ConcurrentHashMap简介
  2. C++(STL):34--- multiset容器详解
  3. 物流×科技,易流如何用IoT技术加速物流业数字化升级?...
  4. 使用路由和远程访问服务为Hyper-V中虚拟机实现NAT上网
  5. php产生订单号不重复,php如何生成不重复订单号
  6. Spring3核心技术之AOP配置【转】
  7. SSO单点登录Spring-Security+CAS+使用手册.doc
  8. Flink状态专题:keyed state和Operator state
  9. RGB颜色值与十六进制颜色码转换工具
  10. python链家数据分析统计服_Python数据分析实战-链家北京二手房价分析
  11. java 单位圆_巧用蒙特卡洛算法求单位圆面积
  12. 构成计算机系统物理实体的是什么,什么构成计算机的物理实体
  13. OpenCV Mat与uchar*指针相互转换赋值
  14. Linux比较重要命令使用总结
  15. 临沂办理高新技术企业需要什么文件及材料
  16. vue实现斑马线进度条
  17. 数据结构[1]--学习--绪论(学习记录)
  18. python连接hive步骤(不出错版)
  19. 解决 remote Read-only file system 报错原因
  20. 给图片加文字,加图片

热门文章

  1. CASIA-Webface数据集
  2. java毕业生设计一中体育馆管理系统计算机源码+系统+mysql+调试部署+lw
  3. jdk 8u192 官网下载
  4. 用程序的思想浅谈优化福州一中发书
  5. Hi3559AV100-网口调试
  6. Sublime Text3 安装sublime_merge 以及sublimerge插件
  7. 12306订票流程解析
  8. VIL VIH VOH VOL解释
  9. javascript - js 创建网页 url 桌面快捷方式(兼容chrome)-书签工具
  10. 安卓开发之安卓设置锁屏密码