第三章
背景知识
空间域(将图像视为像素点所组成的整体,通常空间域的处理更有效)
频域 (以傅里叶变换为基础,将图像视作许多不同频率的波拟合的整体)
空间域的处理公式:
![](https://i-blog.csdnimg.cn/blog_migrate/7a697b39dec883207865153d2e493a54.png)
x,y代表了像素坐标,f(x,y), g(x,y)代表了处理前后的图像,T代表了运算方式或者说算子。
从上面的公式我们可以看出,所包含的信息仅有像素本身以及其位置信息,所以显然是空间域处理公式。
空间滤波
空间滤波实在是一个很难理解的概念,因此我打算通过一个例子来讲解,因为我们并不需要十分精确的定义,我们需要的是理解。
假设说,现在二狗要给老妈拍照,拍完照后,老妈的脸上有皱纹。但是老妈想要看起来更年轻一些,然后老妈对你讲,二狗啊,你看能不能把这些皱纹去掉呢?
我们可以很容易想到,如果要去掉皱纹的话,只需要用皱纹附近的颜色把皱纹的颜色给掩盖掉就好了。于是二狗很开心的去做了。但是在做的过程中,二狗发现,这个所谓的”附近“究竟是多大呢?我们假设说皱纹是一个像素那么宽的线条,那么我们以皱纹上某一个像素为中心取3*3的大小,用这个3*3大小的范围中的平均颜色去覆盖掉这个像素,那么对皱纹上的每一个像素重复以上操作,就能去掉皱纹了。二狗想到这里很开心。因为任务完成了。
上述故事中,去皱纹这件事就是在”滤波“,这个3*3的范围就是空间滤波器。当然空间滤波器的大小不止可以是3*3,也可以5*5,3*5,看实际用途而定;同时也不止是取平均值,也可以是加权等等。
基本的灰度变换函数
图像反转(常用于增强嵌入于图像暗色区域的白色或灰色细节):
![](https://i-blog.csdnimg.cn/blog_migrate/8e51c7f7fd71255eb03a188f16114315.gif)
对数变换(常用于扩展图像中的暗像素值,同时压缩更高灰度级的值):
![](https://i-blog.csdnimg.cn/blog_migrate/75ec917f80064cb1319437e3ad4325c6.gif)
其中c是一个常数,并假设r ≥ 0。该变换将输入中范围较窄的低灰度值映射为输出范围中较宽的灰度值,或将输入中范围较宽的高灰度值映射为输出范围中较窄的灰度值。
幂次变换:
![](https://i-blog.csdnimg.cn/blog_migrate/026a14630826ddba8f08f22dbadb71ec.gif)
其中c和γ为正常数。与对数函数情况类似,部分γ值的幂次曲线将较窄范围的暗色输入值映射为较宽范围的输出值,或将较宽范围的高灰度级输入值映射为较窄范围的输出值。
但对于不同的γ,曲线形式不同:
(1)当γ < 1时,其曲线形式和对数曲线相似。
(2)当γ > 1时,作用相反,高灰度区扩展,低灰度区压缩。
部分代码运行效果
import cv2
img = cv2.imread('images/lake.tif')
cv2.imshow('img', img)
# 归一化到范围[100,200]
img_norm = cv2.normalize(img, None, 100, 200, cv2.NORM_MINMAX)
# 显示图片
cv2.imshow('img_norm', img_norm)
# 反转
img_0 = 255 - img
# 显示图片
cv2.imshow('img_0', img_0)
cv2.waitKey(0)
![](https://i-blog.csdnimg.cn/blog_migrate/71541d03d92d35418eccf45432f77775.png)
直方图
直方图是多种空间域处理技术的基础。
灰度级为[0, L - 1]范围的数字图像的直方图是离散函数h(rk) = nk,这里rk是第k级灰度,nk是图像中灰度级为rk的像素个数。经常以图像中像素的总数(用n表示)来除它的每一个值得到归一化的直方图。因此,一个归一化的直方图由P(rk)=nk/n给出,这里k=0, 1, …, L - 1。 简单的说,P(rk)给出了灰度级为rk发生的概率估计值。
归一化直方图所有分量之和应等于1。
图像处理
直方图的处理
基本图像与直方图特点对应关系
暗色图像中,直方图的组成成分集中在灰度级低(暗)的一侧
高亮图像中,直方图的组成成分集中在灰度级高(亮)的一侧
低对比度图像的直方图窄而集中于灰度级的中部
高对比度的图像中,直方图的成分覆盖了灰度级很宽的范围,而且像素的分布相对均匀,只有少量垂线比其他的高许多。
生成直方图代码
import cv2
img = cv2.imread('images/lake.tif')
# 计算灰度直方图
hist = cv2.calcHist([img], [0], None, [256], [0, 256])
# 显示灰度直方图
import matplotlib.pyplot as plt
plt.figure()
plt.title('Grayscale Histogram')
plt.xlabel('Bins')
plt.ylabel('# of Pixels')
plt.plot(hist)
plt.xlim([0, 256])
plt.show()
![](https://i-blog.csdnimg.cn/blog_migrate/f37ce587511f38967abb7b08dadabb2f.png)
直方图均衡化
目标:增强对比度
方法:1. 计算灰度直方图
2. 对每个像素的灰度值重新分配,使得灰度直方图尽可能均匀
其中第二点,是通过一个函数实现重新分配,这个函数必须是单调递增来保证这个过程是可逆的(也即不会丢失信息)。
变换形式:
s = T(r) 0 ≤ r ≤ L - 1
s = T(r) 表示输入灰度级为 r 的像素点在输出灰度级为 s 的像素点上的映射关系,其中 0 ≤ r ≤ L - 1,L 表示图像的灰度级数。
令Pr( r)和Ps(s)分别表示随机变量r和s的概率密度函数。由基本概率论得到的基本结果是,若Pr( r)和T( r)已知,且在感兴趣的值域上T( r)是连续且可微的,则变换(映射)后的变量s的PDF可由下式得到:
![](https://i-blog.csdnimg.cn/blog_migrate/66cc6bbdd2b7bf0a14881dd32783d0ed.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a6d5a4c7a183528c6be4f45218974d12.png)
上面这两个图就是表示了如何把不均匀的分布转化为均匀分布
那么,可以推导得到s:
![](https://i-blog.csdnimg.cn/blog_migrate/657369c17b384ea33b275013ab31029b.png)
其中T(r)代表了上图中的T(r),L-1代表了范围,后面的积分公式代表了r的累积分布
直方图均衡化代码
# 灰度图像变换
import cv2
img = cv2.imread('images/cameraman.tif')
# 将图像转换为灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 直方图均衡化
equ = cv2.equalizeHist(gray)
# 显示结果
cv2.imshow('Original Image', gray)
cv2.imshow('Equalized Image', equ)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 计算直方图
hist_gray = cv2.calcHist([gray], [0], None, [256], [0, 256])
hist_equ = cv2.calcHist([equ], [0], None, [256], [0, 256])
# 显示直方图
import matplotlib.pyplot as plt
plt.figure()
plt.title('Grayscale Histogram')
plt.xlabel('Bins')
plt.ylabel('# of Pixels')
plt.plot(hist_gray)
plt.xlim([0, 256])
plt.show()
plt.figure()
plt.title('Equalized Histogram')
plt.xlabel('Bins')
plt.ylabel('# of Pixels')
plt.plot(hist_equ)
plt.xlim([0, 256])
plt.show()
![](https://i-blog.csdnimg.cn/blog_migrate/60226d1861a477cb494b636cdc70e996.png)
![](https://i-blog.csdnimg.cn/blog_migrate/6c430ee038e20ae3e7f796335dd04688.png)
![](https://i-blog.csdnimg.cn/blog_migrate/0b1098cca4c5319debbd204fbb0fa799.png)
直方图匹配
目标:用于将一幅图像的直方图变换为另一幅给定直方图,可以用来改善图像的对比度和亮度。
实际应用举例:用手机摄影,短时间内拍摄多张不同曝光度的图片,然后将它们按照直方图匹配去合成
实现方法:用a图像的直方图转化去匹配b图像的直方图
空间滤波基础
原理:目前看起来就是卷积,跟卷积没有任何区别,如果不懂,我强烈推荐这个视频: https://www.bilibili.com/video/BV19P4y1q7GD/?spm_id_from=333.337.search-card.all.click&vd_source=1321f02a4fca22087897cdd2ac9faa38
空间相关
相关:使用对称卷积核进行卷积并得到相关度。使用对称卷积核是为了保证空间的对称性与互换性,也即图片翻转或者旋转,最后得到的计算结果依旧是相同的。
空间滤波器
平滑空间滤波器:卷积的时候取平均值,主要目的是消除噪点等,例如
![](https://i-blog.csdnimg.cn/blog_migrate/3d7fccb0c643ad95d1e95149c6586de1.png)
锐化滤波器:主要有一阶微分与二阶微分
一阶微分公式:
![](https://i-blog.csdnimg.cn/blog_migrate/2071963847545dfe00fe6f6ab0d949ef.png)
二阶微分公式:
![](https://i-blog.csdnimg.cn/blog_migrate/f23384834bffc77ef712a686ec2da10d.png)
二阶微分在二维平面下公式推导易由一维推导:
![](https://i-blog.csdnimg.cn/blog_migrate/7dd45a267e22d9880c3869fcd2ae6ef1.png)
拉普拉斯算子有这么几个特性:1.各向同性 2.旋转不变
这意味着,它是对称的,例如:
![](https://i-blog.csdnimg.cn/blog_migrate/e141410f1ecfebf04882fb74372c5285.png)
由于拉普拉斯是一种微分算子,它的应用强调图像中灰度的突变及降低灰度慢变化的区域,这将产生一幅把图像中的浅灰色边线和突变点叠加到暗背景中的图像,将原始图像和拉普拉斯图像叠加到一起的简单方法可以保护拉普拉斯锐化处理的效果,同时又可以复原背景信息。
平滑滤波代码
# 灰度图像变换
import cv2
img = cv2.imread('images/lena_gray_512.tif')
# 平滑处理
blur = cv2.blur(img, (5, 5))
# 显示图像
cv2.imshow('Original', img)
cv2.imshow('Blur', blur)
# 等待显示
cv2.waitKey(0)
![](https://i-blog.csdnimg.cn/blog_migrate/572499cf774f3dabe1f80b62849633a8.png)
锐化滤波代码
import cv2
import numpy as np
# 读取图像
img = cv2.imread('images/lena_gray_512.tif')
# 构建锐化滤波器
kernel = np.array([[-1, -1, -1], [-1, 9, -1], [-1, -1, -1]])
# 使用锐化滤波器
sharp = cv2.filter2D(img, -1, kernel)
# 显示结果
cv2.imshow('Original Image', img)
cv2.imshow('Sharpened Image', sharp)
cv2.waitKey(0)
cv2.destroyAllWindows()
![](https://i-blog.csdnimg.cn/blog_migrate/ccd7955c425e70b7347f7a74c275f5ad.png)
非线性滤波器
非线性主要是指无法用一个线性的函数去表示该点的像素,例如统计排序滤波器。