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

 更新时间:2021年6月5日 15:00  点击:1790

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()       

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

这里写图片描述

对高斯噪声的滤波

这里写图片描述

用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);
}

运行结果:

这里写图片描述

程序说明:

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

    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 )

以上为个人经验,希望能给大家一个参考,也希望大家多多支持猪先飞。

[!--infotagslink--]

相关文章

  • python opencv 画外接矩形框的完整代码

    这篇文章主要介绍了python-opencv-画外接矩形框的实例代码,代码简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-09-04
  • Python astype(np.float)函数使用方法解析

    这篇文章主要介绍了Python astype(np.float)函数使用方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-06-08
  • 最炫Python烟花代码全解析

    2022虎年新年即将来临,小编为大家带来了一个利用Python编写的虎年烟花特效,堪称全网最绚烂,文中的示例代码简洁易懂,感兴趣的同学可以动手试一试...2022-02-14
  • python中numpy.empty()函数实例讲解

    在本篇文章里小编给大家分享的是一篇关于python中numpy.empty()函数实例讲解内容,对此有兴趣的朋友们可以学习下。...2021-02-06
  • python-for x in range的用法(注意要点、细节)

    这篇文章主要介绍了python-for x in range的用法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-05-10
  • Python 图片转数组,二进制互转操作

    这篇文章主要介绍了Python 图片转数组,二进制互转操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-09
  • Python中的imread()函数用法说明

    这篇文章主要介绍了Python中的imread()函数用法说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-16
  • python实现b站直播自动发送弹幕功能

    这篇文章主要介绍了python如何实现b站直播自动发送弹幕,帮助大家更好的理解和学习使用python,感兴趣的朋友可以了解下...2021-02-20
  • python Matplotlib基础--如何添加文本和标注

    这篇文章主要介绍了python Matplotlib基础--如何添加文本和标注,帮助大家更好的利用Matplotlib绘制图表,感兴趣的朋友可以了解下...2021-01-26
  • 解决python 使用openpyxl读写大文件的坑

    这篇文章主要介绍了解决python 使用openpyxl读写大文件的坑,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-13
  • python 计算方位角实例(根据两点的坐标计算)

    今天小编就为大家分享一篇python 计算方位角实例(根据两点的坐标计算),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-04-27
  • python实现双色球随机选号

    这篇文章主要为大家详细介绍了python实现双色球随机选号,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-05-02
  • python中使用np.delete()的实例方法

    在本篇文章里小编给大家整理的是一篇关于python中使用np.delete()的实例方法,对此有兴趣的朋友们可以学习参考下。...2021-02-01
  • 使用Python的pencolor函数实现渐变色功能

    这篇文章主要介绍了使用Python的pencolor函数实现渐变色功能,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-03-09
  • python自动化办公操作PPT的实现

    这篇文章主要介绍了python自动化办公操作PPT的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-05
  • Python getsizeof()和getsize()区分详解

    这篇文章主要介绍了Python getsizeof()和getsize()区分详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-11-20
  • python实现学生通讯录管理系统

    这篇文章主要为大家详细介绍了python实现学生通讯录管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-02-25
  • PyTorch一小时掌握之迁移学习篇

    这篇文章主要介绍了PyTorch一小时掌握之迁移学习篇,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-09-08
  • 解决python 两个时间戳相减出现结果错误的问题

    这篇文章主要介绍了解决python 两个时间戳相减出现结果错误的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-12
  • Python绘制的爱心树与表白代码(完整代码)

    这篇文章主要介绍了Python绘制的爱心树与表白代码,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-04-06