《OpenCV轻松入门》学习打卡第七天

第十三章 直方图处理

直方图是图像处理过程中的一种非常重要的分析工具,直方图从图像内部灰度级的角度对图像进行表述,包含十分丰富重要的信息,从直方图的角度对图像进行处理,可以达到增强图像显示效果的目的

1.直方图的含义

直方图是图像内灰度值的统计特性与图像灰度值之间的函数,直方图统计图像内各个灰度级出现的次数,从直方图的图形上观察,横坐标是各个像素点的灰度级,纵坐标是具有该灰度值的像素点的个数,有时为了便于表示,也采用归一化直方图,在其中,x轴依旧表示灰度级,y轴表示灰度级出现的频率。
在OpenCV官网上,特别提出了三个概念:
· DIMS:表示在绘制直方图时,收集的参数的数量,一般情况下,直方图中收集的数据只有一种,就是灰度级,因此该值为1
· RANGE:表示要统计的灰度级范围,一般为[0, 255]
· BINS:参数子集的数目,在处理数据的过程中,有时需要将众多的数据划分为若干个组,再进行分析

2.绘制直方图

python的模块matplotlib.pyplot中的hist()函数能够方便的绘制直方图,我们通常采用该函数直接绘制直方图,除此之外,OpenCV中的cv2.calcHist()函数能够计算统计直方图,还可以在此基础上绘制图像的直方图
1)使用Numpy绘制直方图
模块matplotlib.pyplot提供了一个类似于MATLAB绘图方式的框架,可以使用其中的matplotlib.pyplot.hist()函数(以下简称为hist()函数)来绘制直方图,此函数的作用是根据数据源和灰度级分组绘制直方图,语法格式为:
matplotlib.pyplot.hist(X, BINS)
其中X表示数据源,必须是一维的,图像通常是二维的,需要使用函数ravel()将图像处理为一维数据源以后,再做参数使用,BINS的具体值表示灰度级的分组情况
函数ravel()的作用是将二维数组降维成一维数组,语法为:
b = a.ravel()
2)使用OpenCV绘制直方图
OpenCV提供了函数cv2.calcHist()用来计算图像的统计直方图,该函数能够统计各个灰度级的像素点个数,利用matplotlib.pyplot模块中的plot()函数。可以将函数cv2.calcHist()的统计结果绘制成直方图。
1>用cv2.calcHist()函数统计图像直方图信息
函数cv2.calcHist()用于统计图像直方图信息,语法格式为:
hist = cv2.calcHist(images, channels, mask, histSize, ranges, accumulate)
返回值hist是返回的统计直方图,是一个一维数组,数组内的元素是各个灰度级的像素个数;images为原始图像,需要使用”[]”括起来;channels是指定通道编号,需要用”[]”括起来,如果为单通道图像,那么为[0],对于彩色图像,可以为[0], [1], [2]分别对应通道B, G, R;mask是掩模图像;histSize是BINS的值,需要用”[]”括起来;ranges即像素值范围;accumulate是累计标识,默认为False,如果设为True,则直方图在开始计算时不会被清零,计算的是多个直方图的累计结果。
2>Plot()函数的使用
使用matplotlib.pyplot模块内的plot()函数可以将函数cv2.calcHist()的返回值绘
制为图像直方图
3>绘制统计直方图
熟悉函数plot()的使用后,就可以使用它将函数cv2.calcHist()的返回值绘制成直方图了
3)使用掩模绘制直方图
在函数cv2.calcHist()中,参数mask用来标识是否使用掩模图像,当使用掩模图像获取直方图时,仅获取掩模参数mask中指定区域的直方图
1>掩模处理是怎么回事
2>如何构造掩模图像
通常先构造一个像素值全为0的二维数组,再将数组中指定区域的像素值设为255,就得到了掩模图像
3>使用掩模绘制直方图
绘制掩模图像时,首先将函数cv2.calcHist()的mask设置为掩模图像,得到掩模处理的直方图信息,再使用plot()函数完成直方图的绘制

3.直方图均衡化

如果一个图像拥有全部可能的灰度级,并且像素值的灰度均匀分布,那么这幅图像就具有高对比度和多变的灰度色调,灰度级丰富且覆盖范围较大,在外观上,这样的图像具有更丰富的色彩,不会过暗或过亮。
直方图均衡化的主要目的是将原始图像的灰度级均匀的映射到整个灰度级范围内,而得到一个灰度级分布均匀的图像。这种均衡化,既实现了灰度值统计上的概率均衡,也实现了人类视觉系统上的视觉均衡
1)直方图均衡化原理
包括两个步骤:
· 计算累计直方图
· 对累计直方图进行区间转换
在此基础上,再利用人眼视觉达到直方图均衡化的目的
1>在原有范围内实现均衡化
用当前灰度值的累计概率乘以当前灰度级的最大值得到新的灰度值,并作为均衡化的结果
2>在更广泛的范围内实现均衡化
用当前灰度值的累计概率乘以更广泛范围灰度级的最大值得到新的灰度值,并作为均衡化的结果
2)直方图均衡化处理
OpenCV使用函数cv2.equalizeHist()实现直方图均衡化,语法格式为:
dst = cv2.equalizeHist(src)
参数src为8位单通道原始图像,dst是直方图均衡化处理的结果

4.pyplot模块介绍

Matplotlib.pyplot模块提供了一个类似于MATLAB绘图方式的框架,可以使用其中的函数方便的绘制图形
1)subplot函数
模块matplotlib.pyplot提供了函数matplotlib.pyplot.subplot()用来向当前窗口内添加一个子窗口对象。语法格式为:
Matplotlib.pyplot.subplot(nrows, ncols, index)
式中nrows为行数,ncols为列数,index为窗口序号
2)imshow函数
模块matplotlib.pyplot提供了函数matplotlib.pyplot.imshow()用来显示图像,语法格式为:
Matplotlib.pyplot.imshow(X, cmap = None)
式中X为图像信息,可以是各种形式的数值;cmap表示色彩空间,是可选项,默认值为NULL,默认使用RGB(A)颜色空间

第十四章 傅里叶变换

图像处理一般分为空间域处理和频率域处理。空间域处理是直接对图像内的像素进行处理,空间域处理是直接对图像内的像素进行处理,空间域处理主要划分为灰度变化和空间滤波两种形式。灰度变化是对图像内的单个像素进行处理,比如调节对比度和处理阈值等,空间滤波涉及图像质量的改变,例如图像平滑处理,空间域处理的计算简单方便,运算速度快
频率域处理是先将图像变换到频率域,然后在频率域对图像进行处理,最后再通过反变换将图像从频率域变换到空间域。傅里叶变换是应用最广泛的一种频域变换

1.理论变换

法国数学家傅里叶指出,任何周期函数都可以表示为不同频率的正弦函数和的形式。傅里叶变换就是从频域的角度完整的表述时域信息,相差也是傅里叶变换中非常重要的条件,在图像处理过程中,傅里叶变换就是将图像分解为正弦分量和余弦分量两部分,即将图像从空间域转换到频率域,数字图像经过傅里叶变换后,得到的频率值是复数。因此,显示傅里叶变换结果需要使用实数图像加虚数图像或者幅度图像加相位图像的形式。
对图像进行傅里叶变换以后,我们会得到图像中的低频和高频信息,低频信息对应图像内变换缓慢的灰度分量。高频信息对应图像内变化越来越快的灰度分量,是由灰度的尖锐过渡造成的。傅里叶变换的目的就是为了将图像从空域转换到频域,并在频域内实现对图像内特定对象的处理,然后再对经过处理的频域图像进行逆傅里叶变换得到空域图像。傅里叶变换在图像处理领域发挥着非常关键的作用,可以实现图像增强,图像去噪,边缘检测,特征提取,图像压缩和加密等

2.Numpy实现傅里叶变换

Numpy模块提供了傅里叶变换,Numpy模块中的fft2()函数可以实现图像的傅里叶变换。
1)实现傅里叶变换
Numpy提供的实现傅里叶变换的函数是numpy.fft.fft2(),语法格式为:
返回值 = numpy.fft.fft2(原始图像)
这里需要注意,原始图像的类型是灰度图像,返回值为一个复数数组,经过该函数的处理以后,就能得到图像的频谱信息,此时,图像频谱中的零频率分量位于频谱图像的左上角,为了便于观察,通常会使用函数numpy.fft.fftshift()将零频率成分移动到频域图像的中心位置,函数numpy.fft.fftshift()的语法格式为:
返回值 = numpy.fft.fftshift(原始图谱)
使用该函数处理以后,图像频谱中的零频率分量会被移到频域图像的中心位置,对于观察傅里叶变换后频谱中的零频率部分非常有效,对图像傅里叶变换后,得到的是一个复数数组。为了显示图像,需要将它们的值调整到[0, 255]的灰度空间内,使用的公式为:
像素新值 = 20 * np.log(np.abs(频谱值))
2)实现逆傅里叶变换
如果在傅里叶变换过程中使用了numpy.fft.fftshift()函数移动零频率分量,那么在逆傅里叶变换过程中,需要先使用numpy.fft.ifftshift()函数将零频率分量移到原来的位置,再进行逆傅里叶变换
函数numpy.fft.ifftshift()是numpy.fft.fftshift()的逆函数,语法格式为:
调整后的频谱 = numpy.fft.ifftshift(原始频谱)
函数numpy.fft.ifft2()可以用来实现逆傅里叶变换,返回值为空域复数数组,它是函数numpy.fft.fft2()的逆函数,语法格式为:
返回值 = numpy.fft.ifft2(频域数据)
函数numpy.fft.ifft2()的返回值仍旧是一个复数数组,需要将信息调整至[0, 255]灰度空间内,使用的公式为:
Iimag = np.abs(逆傅里叶变换结果)
3)高通滤波
在一幅图像中,同时存在着高频信号和低频信号,滤波器能够允许一定频率的分量通过或者拒绝其通过,按照其作用方式可以划分为低通滤波器和高通滤波器
· 允许低频信号通过的滤波器叫做低通滤波器,低通滤波器使高频信号衰减而对低频信号放行,会使图像变模糊
· 允许高频信号通过的滤波器叫做高通滤波器,高通滤波器使低频信号衰减而对高频信号放行,将增强图像中尖锐的细节,但是会导致图像的对比度降低

傅里叶变换可以将图像的高频信号和低频信号分离,在对图像的高频或低频信号进行处理后,再进行逆傅里叶变换返回空域,就完成了对图像的频域处理,通过对图像的频域处理,可以实现图像增强,图像去噪,边缘检测,特征提取,压缩和加密等操作

3.OpenCV实现傅里叶变换

OpenCV提供了函数cv2.dft()和cv2.idft()来实现傅里叶变换和逆傅里叶变换
1)实现傅里叶变换
函数cv2.dft()的语法格式为:
返回结果 = cv2.dft(原始图像, 转换标识)
对于参数“原始图像”,要首先使用np.float32()函数将图像转换为np.float32格式,“转换标识”的值通常为“cv2.DFT_COMPLEX_OUTPUT”,用来输出一个复数阵列,函数cv2.dft()返回的结果与使用Numpy进行傅里叶变换得到的结果是一致的,经过函数cv2.dft()的变换后,我们得到了原始图像的频谱信息,此时零频率分量并不在中心位置,为了处理方便需要将其移至中心位置,可以用函数numpy.fft.fftshift()实现,经过上述处理后,频谱图像还只是一个由实部和虚部构成的值,要将其显示出来,还要做进一步的处理,函数cv2.magnitude()可以计算频谱信息的幅度,该函数的语法格式为:
返回值 = cv2.magnitude(参数1, 参数2)
得到了频谱信息的幅度以后,通常还需要对幅度值做进一步的转换,以便将频谱信息以图像的形式展示出来,这里使用的公式为:
result = 20 * np.log(cv2.magnitude(实部,虚部))
2)实现逆傅里叶变换
在OpenCV中,使用函数cv2.idft()实现逆傅里叶变换,该函数是傅里叶变换函数cv2.dft()的逆函数,语法格式为:
返回结果 = cv2.idft(原始数据)
如果使用了函数numpy.fft.fftshift()移动了零频率分量,那么进行逆傅里叶变换以前,要使用函数numpy.fft.ifftshift()将零频率分量恢复到原来的位置,注意的是,在进行逆傅里叶变换以后,得到的仍是复数,需要使用函数cv2.magnitude()计算其幅度。
3)低通滤波
前面讲过,在一幅图像内,低频信号对应图像内变化缓慢的灰度分量,低通滤波器让高频信号衰减让低频信号通过,图像进行低通滤波后会变模糊,因为边缘信息被削弱了

若有侵权,请联系删除

本读书笔记来源于教材。1


  1. 李立宗. OpenCV轻松入门: 面向python[M].北京. 电子工业出版社: 李立宗. 2019.5 ↩︎

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值