快速中值滤波——Python实现
原理
中值滤波是空域中常用的一种滤波方式,是一种非线性的滤波。它的原理就是将窗口像素排序,取中值,然后移动窗口,不断重复取中值的过程。
但是,可以发现,每次移动窗口,都需要对像素点进行排序,从而选取中间的那个像素点。每次重新排序的效率特别低,为了优化这个排序,便有了快速中值滤波。
快速中值滤波是中值滤波的优化版,它利用了窗口每次平移时,没有移出窗口的像素点还是排好序的,因此,只需要把新加入的像素点插入到其中即可完成排序。此外,由于我们并不需要一个完整的排序数列, 只需要找到中值就可以了。
基于上面两点,快速中值滤波采用的是直方图的方式来统计像素点,横坐标是像素点的值,纵坐标是窗口中像素点的个数。设置一个“光标”,在横轴上左右移动,当两边像素点相等时,对应的像素点就是要找的中值。然后移动窗口,更新直方图,再次移动“光标”,找到中值,不断反复。
需要注意的是,“光标”的每次移动,都只能移动在数目不为 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实现相关推荐
- (MATLAB/C/Python)快速中值滤波
(MATLAB/C/Python)快速中值滤波 一.中值滤波 二.快速中值滤波 介绍 原理 优化 三.代码 MATLAB C Python 四.测试 其他 by HPC_ZY 最近一个项目中需要用到中 ...
- 直方图实现快速中值滤波opencv
中值滤波能够有效去除图像中的异常点,具有去除图像噪声的作用.传统中值滤波的算法一般都是在图像中建立窗口,然后对窗口内的所有像素值进行排序,选择排序后的中间值作为窗口中心像素滤波后的值.由于这个做法在每 ...
- 快速中值滤波在心电图ECG中的应用
1.算法介绍和实现 首先来搞明白,什么是快速中值滤波? 快速中值滤波非常简单,就是用过去连续N个数据,再对这N个数据进行排序,取排序后的中间那个数据,做为当前的输出,N即为窗口的长度. 算法实现: 1 ...
- OpenCV图像处理专栏九 | 基于直方图的快速中值滤波算法
转载自:https://zhuanlan.zhihu.com/p/98092747 侵删 前言 这是OpenCV图像处理专栏的第9篇文章,主要介绍一个基于直方图的快速中值滤波算法,希望对大家有帮助. ...
- matlab实现 中值滤波去除基线漂移,快速中值滤波在滤除心电信号基线漂移中的应用...
[摘要]文中给出了一种非线性的滤除心电信号基线漂移的滤波方法,把基于排序统计理论的快速中值滤波方法应用于处理心电信号,通过多次对心电信号中选择的窗口数据进行排序,然后取中值的方法来达到滤波的效果.试验 ...
- 高效快速中值滤波算法c语言,快速中值滤波及c语言实现.docx
. .. 快速中值滤波及c语言实现 学生姓名: 刘 勇 学 号: 6100410218 专业班级: 数媒101 [摘要]本文讨论了用c语言在微机上实现中值滤波及快速算法,在程序设计的过程中充分考虑到程 ...
- 图像中值滤波python代码_图像中值滤波FPGA实现
C语言实用数字图像处理.pdf6.34 MB05-11-13|19:30 FPGA实验报告-李炎东.doc633.66 kB16-01-14|10:28 中值滤波在红外成像引信中的应用及硬件实现.ca ...
- 数图:中值滤波python实现
心累,花了一下午写这个 我已经是个大四老咸鱼了,就把代码放出来造福看到的小鲜肉吧(滑稽) import numpy as np #from compiler.ast import flatten 偷懒 ...
- 实时高速实现改进型中值滤波算法_爱学术_免费下载
[摘要]在图像采集和处理过程中会引入噪声,必须先对图像进行预处理.本文介绍一种快速中值滤波算法,该算法在硬件平台上实现实时处理功能.综合考虑,选择现场可编程门阵列(FPGA)作为硬件平台,采用硬件描述 ...
最新文章
- Java基础知识强化之集合框架笔记76:ConcurrentHashMap之 ConcurrentHashMap简介
- C++(STL):34--- multiset容器详解
- 物流×科技,易流如何用IoT技术加速物流业数字化升级?...
- 使用路由和远程访问服务为Hyper-V中虚拟机实现NAT上网
- php产生订单号不重复,php如何生成不重复订单号
- Spring3核心技术之AOP配置【转】
- SSO单点登录Spring-Security+CAS+使用手册.doc
- Flink状态专题:keyed state和Operator state
- RGB颜色值与十六进制颜色码转换工具
- python链家数据分析统计服_Python数据分析实战-链家北京二手房价分析
- java 单位圆_巧用蒙特卡洛算法求单位圆面积
- 构成计算机系统物理实体的是什么,什么构成计算机的物理实体
- OpenCV Mat与uchar*指针相互转换赋值
- Linux比较重要命令使用总结
- 临沂办理高新技术企业需要什么文件及材料
- vue实现斑马线进度条
- 数据结构[1]--学习--绪论(学习记录)
- python连接hive步骤(不出错版)
- 解决 remote Read-only file system 报错原因
- 给图片加文字,加图片