python-opencv 中值滤波{cv2.medianBlur(src, ksize)}的用法


Posted in Python onJune 05, 2021

python-opencv 中值滤波{cv2.medianBlur(src, ksize)}

中值滤波将图像的每个像素用邻域 (以当前像素为中心的正方形区域)像素的 中值 代替 。与邻域平均法类似,但计算的是中值

#用中值法
for y in xrange(1,myh-1):
    for x in xrange(1,myw-1):
        lbimg[y,x]=np.median(tmpimg[y-1:y+2,x-1:x+2]

下面调用opencv的函数

# -*- coding: utf-8 -*-   
#code:myhaspl@myhaspl.com
#中值滤波
import cv2
import numpy as np
fn="test3.jpg"
myimg=cv2.imread(fn)
img=cv2.cvtColor(myimg,cv2.COLOR_BGR2GRAY)
#加上椒盐噪声
#灰阶范围
w=img.shape[1]
h=img.shape[0]
newimg=np.array(img)
#噪声点数量
noisecount=50000
for k in xrange(0,noisecount):
    xi=int(np.random.uniform(0,newimg.shape[1]))
    xj=int(np.random.uniform(0,newimg.shape[0]))
    newimg[xj,xi]=255
#滤波去噪
lbimg=cv2.medianBlur(newimg,3)
cv2.imshow('src',newimg)
cv2.imshow('dst',lbimg)
cv2.waitKey()
cv2.destroyAllWindows()

中值滤波忽略了较高阶灰度和较低阶灰度,直接取中值,因此有效得过滤椒盐噪声。

python-opencv 中值滤波{cv2.medianBlur(src, ksize)}的用法

对高斯噪声的滤波

python-opencv 中值滤波{cv2.medianBlur(src, ksize)}的用法

用scipy.signal中值滤波

中值滤波技术能有效抑制噪声,通过把数字图像中一点的值用该点周围的各点值的中位数来代替,让这些值接近,以消除原图像中的噪声。

*模拟中值滤波

>>> import random
>>> import numpy as np
>>> import scipy.signal as signal
>>> x=np.arange(0,100,10)
>>> random.shuffle(x)
>>> x
array([70, 80, 30, 20, 10, 90,  0, 60, 40, 50])
>>> signal.medfilt(x,3) #一维中值滤波
array([ 70.,  70.,  30.,  20.,  20.,  10.,  60.,  40.,  50.,  40.])

signal的medfilt()方法传入两个参数,第一个参数是要作中值滤波的信号,第二个参数是邻域的大小(奇数)。如邻域为3即是每个点自己和左右各一个点成为一个邻域。在每个位置的邻域中选取中位数替换这个位置的数,也就是该函数的返回值数组。如果邻域中出现没有元素的位置,那么以0补齐。

>>> x=np.random.randint(1,1000,(4,4))
>>> x
array([[ 31,  33, 745, 483],
       [331, 469, 804, 479],
       [235, 487, 244, 982],
       [857, 114, 167, 174]])
>>> signal.medfilt(x,(3,3)) #二维中值滤波
array([[   0.,   33.,  469.,    0.],
       [  33.,  331.,  483.,  479.],
       [ 235.,  331.,  469.,  174.],
       [   0.,  167.,  167.,    0.]])

二维中值滤波还可以用signal.medfilt2d(),速度较快,但只支持int8,float32和float64。

*对图像中值滤波 (这个代码我还没试,如果出现问题可以怀疑是代码的问题)

import numpy as np
from PIL import Image
import scipy.signal as signal
im=Image.open('test.jpg') #读入图片并建立Image对象im
data=[] #存储图像中所有像素值的list(二维)
width,height=im.size #将图片尺寸记录下来
#读取图像像素的值
for h in range(height): #对每个行号h
    row=[] #记录每一行像素
    for w in range(width): #对每行的每个像素列位置w
        value=im.getpixel((h,w)) #用getpixel读取这一点像素值
        row.append(value)#把它加到这一行的list中去
    data.append(row) #把记录好的每一行加到data的子list中去,就建立了模拟的二维list
data=signal.medfilt(data,kernel_size=3) #二维中值滤波
data=np.int32(data) #转换为int类型,以使用快速二维滤波
#创建并保存结果
for h in range(height): #对每一行
    for w in range(width): #对该行的每一个列号
        im.putpixel((h,w),tuple(data[h][w])) #将data中该位置的值存进图像,要求参数为tuple
im.save('result.jpg')#存储

opencv中值滤波medianBlur

中值滤波是一种典型的非线性滤波,是基于排序统计理论的一种能够有效抑制噪声的非线性信号处理技术,基本思想是用像素点邻域灰度值的中值来代替该像素点的灰度值,让周围的像素值接近真实的值从而消除孤立的噪声点。该方法在取出脉冲噪声、椒盐噪声的同时能保留图像的边缘细节。这些优良特性是线性滤波所不具备的。

中值滤波首先也得生成一个滤波模板,将该模板内的各像素值进行排序,生成单调上升或单调下降的二维数据序列,二维中值滤波输出为g(x, y)=medf{f(x-k, y-1),(k, l∈w)},其中f(x,y)和g(x,y)分别是原图像和处理后图像, w为输入的二维模板,能够在整幅图像上滑动,通常尺寸为3*3或5*5区域,也可以是不同的形状如线状、圆形、十字形、圆环形等。通过从图像中的二维模板取出奇数个数据进行排序,用排序后的中值取代要处理的数据即可。

中值滤波对消除椒盐噪声非常有效,能够克服线性滤波器带来的图像细节模糊等弊端,能够有效保护图像边缘信息,是非常经典的平滑噪声处理方法。在光学测量条纹图像的香味分析处理方法中有特殊作用,但在条纹中心分析方法中作用不大。

中值滤波相较于线性滤波中的均值滤波优点在前面已经提到,取得良好滤波效果的代价就是耗时的提升,可能达到均值滤波的数倍,而且对于细节较多的图像也不太适用。

opencv中提供了medianBlur()函数实现了中值滤波操作,其原型如下:

C++: void medianBlur(InputArray src, OutputArray dst, int ksize)

参数解释:

. InputArray src: 输入图像,图像为1、3、4通道的图像,当模板尺寸为3或5时,图像深度只能为CV_8U、CV_16U、CV_32F中的一个,如而对于较大孔径尺寸的图片,图像深度只能是CV_8U。

. OutputArray dst: 输出图像,尺寸和类型与输入图像一致,可以使用Mat::Clone以原图像为模板来初始化输出图像dst

. int ksize: 滤波模板的尺寸大小,必须是大于1的奇数,如3、5、7……

示例程序:

#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
using namespace std;
using namespace cv;
//定义全局变量
Mat g_mSrcImage;
Mat g_mDstImage;
const int g_nMedianBlurMaxValue = 5;
int g_nMedianBlurValue;
int g_nkernelSize;
//定义回调函数
void on_medianBlurTrackBar(int, void*);
int main()
{
    g_mSrcImage = imread("lena.jpg");
    //判断文件是否加载成功
    if(g_mSrcImage.empty())
    {
        cout << "图像加载失败!" << endl;
        return -1;
    }
    else
        cout << "图像加载成功!" << endl;
    //判断图像是否是CV_8U图像
    if(0 <= g_mSrcImage.depth() <= 255)
        cout << "加载图像符合处理要求!" << endl;
    else
    {
        cout << "图像深度不是CV_8U,程序即将退出..." << endl;
        return -1;
    }
    namedWindow("原图像", WINDOW_AUTOSIZE);
    imshow("原图像", g_mSrcImage);
    //输出图像窗口属性及轨迹条名称
    namedWindow("中值滤波图像", WINDOW_AUTOSIZE);
    char medianBlurName[20];
    sprintf(medianBlurName, "核函数尺寸 %d", g_nMedianBlurMaxValue);
    g_nMedianBlurValue = 1;
    //创建轨迹条
    createTrackbar(medianBlurName, "中值滤波图像", &g_nMedianBlurValue,
                    g_nMedianBlurMaxValue, on_medianBlurTrackBar);
    on_medianBlurTrackBar(g_nMedianBlurValue, 0);
    waitKey(0);
    return 0;
}
void on_medianBlurTrackBar(int, void*)
{
    //重新计算尺寸值,尺寸值应为大于1的奇数
    g_nkernelSize = g_nMedianBlurValue * 2 + 1;
    medianBlur(g_mSrcImage, g_mDstImage, g_nkernelSize);
    imshow("中值滤波图像", g_mDstImage);
}

运行结果:

python-opencv 中值滤波{cv2.medianBlur(src, ksize)}的用法

程序说明:

对于程序中对图像深度的判断根据如下标准:

CV_8U - 8-bit unsigned integers ( 0..255 )
    CV_8S - 8-bit signed integers ( -128..127 )
    CV_16U - 16-bit unsigned integers ( 0..65535 )
    CV_16S - 16-bit signed integers ( -32768..32767 )
    CV_32S - 32-bit signed integers ( -2147483648..2147483647 )
    CV_32F - 32-bit floating-point numbers ( -FLT_MAX..FLT_MAX, INF, NAN )
    CV_64F - 64-bit floating-point numbers ( -DBL_MAX..DBL_MAX, INF, NAN )

以上为个人经验,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python3.x和Python2.x的区别介绍
Feb 12 Python
Python使用PyGreSQL操作PostgreSQL数据库教程
Jul 30 Python
Python itertools模块详解
May 09 Python
Python探索之修改Python搜索路径
Oct 25 Python
python网络爬虫之如何伪装逃过反爬虫程序的方法
Nov 23 Python
python 时间信息“2018-02-04 18:23:35“ 解析成字典形式的结果代码详解
Apr 19 Python
让你Python到很爽的加速递归函数的装饰器
May 26 Python
Django配置文件代码说明
Dec 04 Python
pytorch 改变tensor尺寸的实现
Jan 03 Python
python字符串,元组,列表,字典互转代码实例详解
Feb 14 Python
python3将变量写入SQL语句的实现方式
Mar 02 Python
使用Python文件读写,自定义分隔符(custom delimiter)
Jul 05 Python
解决Pytorch修改预训练模型时遇到key不匹配的情况
Jun 05 #Python
pytorch 预训练模型读取修改相关参数的填坑问题
Jun 05 #Python
解决pytorch 损失函数中输入输出不匹配的问题
Jun 05 #Python
Pytorch distributed 多卡并行载入模型操作
Jun 05 #Python
Pytorch中的学习率衰减及其用法详解
Jun 05 #Python
pytorch finetuning 自己的图片进行训练操作
Jun 05 #Python
Python 如何将integer转化为罗马数(3999以内)
Jun 05 #Python
You might like
收藏的PHP常用函数 推荐收藏保存
2010/02/21 PHP
PHP自定义序列化接口Serializable用法分析
2017/12/29 PHP
php常用字符串长度函数strlen()与mb_strlen()用法实例分析
2019/06/25 PHP
Laravel 5.5 异常处理 &amp; 错误日志的解决
2019/10/17 PHP
jQuery选择器的工作原理和优化分析
2011/07/25 Javascript
js关闭父窗口时关闭子窗口
2013/04/01 Javascript
JS 加入收藏夹的代码(主流浏览器通用)
2013/05/13 Javascript
JS鼠标滑过图片时切换图片实现思路
2013/09/12 Javascript
javascript模拟枚举的简单实例
2014/03/06 Javascript
iframe调用父页面函数示例详解
2014/07/17 Javascript
用JavaScript实现用一个DIV来包装文本元素节点
2014/09/09 Javascript
jQuery实现的在线答题功能
2015/04/12 Javascript
jQuery实现文件上传进度条特效
2015/08/12 Javascript
12个超实用的JQuery代码片段
2015/11/02 Javascript
node.js中module.exports与exports用法上的区别
2016/09/02 Javascript
用jquery获取自定义的标签属性的值简单实例
2016/09/17 Javascript
js链表操作(实例讲解)
2017/08/29 Javascript
详解使用Typescript开发node.js项目(简单的环境配置)
2017/10/09 Javascript
Vue 2.0 中依赖注入 provide/inject组合实战
2019/06/20 Javascript
[47:03]完美世界DOTA2联赛PWL S3 Galaxy Racer vs Phoenix 第二场 12.10
2020/12/13 DOTA
Python完全新手教程
2007/02/08 Python
Python 开发Activex组件方法
2009/11/08 Python
python基于itchat实现微信群消息同步机器人
2017/02/27 Python
python 计算一个字符串中所有数字的和实例
2019/06/11 Python
python 实现查找文件并输出满足某一条件的数据项方法
2019/06/12 Python
Python交互式图形编程的实现
2019/07/25 Python
Python Request类源码实现方法及原理解析
2020/08/17 Python
美国现代家具购物网站:LexMod
2019/01/09 全球购物
c++工程师面试问题
2013/08/04 面试题
金额转换,阿拉伯数字的金额转换成中国传统的形式如:(¥1011)-> (一千零一拾一元整)输出
2015/05/29 面试题
机械化及自动化毕业生的自我评价分享
2013/11/06 职场文书
精细化工应届生求职信
2013/11/17 职场文书
幼儿园亲子活动方案
2014/01/29 职场文书
产品质量承诺书
2014/03/27 职场文书
初三班主任寄语大全
2014/04/04 职场文书
就业意向协议书
2015/01/29 职场文书