题目1:有20幅噪声图像中均加入了均值为0,方差为0.03的高斯噪声,请对图像进行去噪增强,并写出原理。
1、算法原理:
高斯滤波是一种线性平滑滤波,适用于消除高斯噪声,广泛应用于图像处理的减噪过程。
通俗的讲,高斯滤波就是对整幅图像进行加权平均的过程,每一个像素点的值,都由其本身和邻域内的其他像素值经过加权平均后得到。
高斯滤波的具体操作是:用一个模板(或称卷积、掩模)扫描图像中的每一个像素,用模板确定的邻域内像素的加权平均灰度值去替代模板中心像素点的值。
对应均值滤波和方框滤波来说,其邻域内每个像素的权重是相等的。而在高斯滤波中,会将中心点的权重值加大,远离中心点的权重值减小,在此基础上计算邻域内各个像素值不同权重的和。
20张噪声图像:
我们将20张噪声图像使用高斯滤波之后进行平均处理。
import numpy as np
import cv2
def GaussianFilter(img):
h, w, c = img.shape
print(img.shape)
# 高斯滤波
K_size = 3
sigma = 1.3
# 零填充
pad = K_size // 2
out = np.zeros((h + 2 * pad, w + 2 * pad, c), dtype=np.float)
out[pad:pad + h, pad:pad + w] = img.astype(np.float)
# 定义滤波核
K = np.zeros((K_size, K_size), dtype=np.float)
for x in range(-pad, -pad + K_size):
for y in range(-pad, -pad + K_size):
K[y + pad, x + pad] = np.exp(-(x ** 2 + y ** 2) / (2 * (sigma ** 2)))
K /= (sigma * np.sqrt(2 * np.pi))
K /= K.sum() # 归一化
# 卷积的过程
tmp = out.copy()
for y in range(h):
for x in range(w):
for ci in range(c):
out[pad + y, pad + x, ci] = np.sum(K * tmp[y:y + K_size, x:x + K_size, ci])
out = out[pad:pad + h, pad:pad + w].astype(np.uint8)
return out
if __name__ == "__main__":
img_final = np.zeros((960, 720, 3), dtype=np.float)
for i in range(20):
img_name = "image_noise{i}.jpg".format(i=i + 1)
img1 = cv2.imread(img_name)
img2 = GaussianFilter(img1)
img2 = img2.astype(np.float)
img_final += img2
img_final /= 20
img_final = img_final.astype(np.uint8)
cv2.imwrite("image_final.jpg", img_final)
输出结果image_final.jpg:
可以看到通过对20张噪声图像经过高斯滤波然后平均化之后,得到的图像已经基本不含噪点,更加清晰,质量提高了许多。
题目2:请对下图做简单的空域均值滤波,模板为15*15的矩阵,用三种不同的方法考虑边界滤波后的效果。
1、算法原理:
均值滤波:
平滑线性空间滤波器的输出是包含在滤波器模板邻域内的像素的简单平均值,也就是均值滤波器。均值滤波器也是低通滤波器,均值滤波器很容易理解,即把邻域内的平均值赋给中心元素。
均值滤波器用来降低噪声,均值滤波器的主要应用是去除图像中的不相关细节,不相关是指与滤波器的模板相比较小的像素区域。模糊图片以便得到感兴趣物体的粗略描述,因此那些较小的物体的灰度就会与背景混合在一起,较大的物体则变的像斑点而易于检测。模板的大小由那些即将融入背景中的物体尺寸决定。
均值滤波器的缺点是存在着边缘模糊的问题。
边界滤波是数字图像处理领域中的一种基本图像处理方法,主要用于去除图像边缘处的伪像或噪声,常常被用于图像增强和特征提取的前期处理。以下是三种不同的边界滤波处理办法:
1.反射边界滤波(Reflective Boundary Filtering):反射边界滤波是指在滤波时使用边界像素的镜像值作为卷积核的一部分。这种方法的好处是可以保留边界的平滑性,并且不会引入额外的噪声。
2.扩展边界滤波(Extended Boundary Filtering):扩展边界滤波是指在滤波时把边界以外的区域扩展一定的像素值。这种方法的好处是可以有效地避免滤波结果中的边界伪影,但会在图像边缘引入额外的噪声。
3.零边界滤波(Zero Boundary Filtering):零边界滤波是指在滤波时使用边界像素值的零值作为卷积核的一部分。这种方法可以消除边界伪影,但相对于反射边界滤波可能会导致平滑边界之外的图像区域。
import cv2
import numpy as np
def process(name, key):
# 读取图像
img = cv2.imread(name)
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
height, width = img.shape[:2]
# 定义滤波模板大小
kernel_size = 15
if key == 'ZeroPadding':
# 定义零边界滤波
border_type = cv2.BORDER_CONSTANT
border_value = 0
# 扩展边界
img_expanded = cv2.copyMakeBorder(img, kernel_size // 2, kernel_size // 2, kernel_size // 2, kernel_size // 2,
border_type, value=border_value)
if key == 'Reflect':
# 定义反射边界滤波
border_type = cv2.BORDER_REFLECT
# 反射边界滤波
img_expanded = cv2.copyMakeBorder(img, kernel_size // 2, kernel_size // 2, kernel_size // 2, kernel_size // 2,
border_type)
if key == 'Replicate':
# 定义扩展边界滤波
border_type = cv2.BORDER_REPLICATE
# 扩展边界
img_expanded = cv2.copyMakeBorder(img, kernel_size // 2, kernel_size // 2, kernel_size // 2, kernel_size // 2,
border_type)
# 均值滤波
kernel = np.ones((kernel_size, kernel_size), np.float32) / (kernel_size ** 2)
img_filtered = cv2.filter2D(img_expanded, -1, kernel)
# 截取有效部分
img_filtered = img_filtered[kernel_size // 2: height + kernel_size // 2, kernel_size // 2: width + kernel_size // 2]
# 显示结果
cv2.imshow('Original', img)
cv2.imshow(key, img_filtered)
if __name__ == "__main__":
process("2.bmp", 'ZeroPadding')
process("2.bmp", 'Reflect')
process("2.bmp", 'Replicate')
cv2.waitKey(0)
cv2.destroyAllWindows()
结果图:
三种方法处理边界滤波的效果是不同的。
零边界滤波
在这种方法中,边界区域使用 0 填充。这种方法可以在处理边缘部分时产生一些明显的黑色边缘。
反射边界滤波
在这种方法中,图像边缘将被反转并复制,以创建一个边缘像之外的新像素。因此,边缘周围小区域的像素是反射的,而反转图像的效果是在边缘周围创建一个像素“角”(即,没有颜色信息的象素单元)。
扩展边界滤波
这种方法中,像素值在边界上重复。这意味着在达到边缘时,边缘周围的小区域将使用边缘像素的值进行模板计算。这会导致边缘周围的图像出现重复的行或列。
题目3:请用直方图均衡对下图进行增强。
直方图均衡(Histogram equalization)是一种常见的图像增强方法,它可以将图像的直方图进行变换,使得图像的灰度级数分布更加均匀,从而增强图像的对比度和显示效果。
直方图均衡化分为以下步骤:
首先计算原始图像的直方图,即图像中每个灰度级别的像素数量。
计算原始图像的累积分布函数(Cumulative Distribution Function, CDF),以得到每个灰度级别在整幅图像中的出现概率。
将CDF比例化至最大灰度级别(即图像深度),计算出一个新的映射表,该映射表将原始图像中灰度级的值映射到直方图均衡化后的灰度级。
使用该新映射表将原始图像中的每个像素的灰度级转换为新的灰度级,并创建一张经过直方图均衡化的图像。
通过这个过程,直方图均衡能够扩展图像的动态范围,减少图像中像素强度值的方差,并增强图像的对比度,从而提高图像的视觉质量。
import cv2
import numpy as np
def Origin_histogram(img):
# 建立原始图像各灰度级的灰度值与像素个数对应表
histogram = {}
for i in range(img.shape[0]):
for j in range(img.shape[1]):
k = img[i][j]
if k in histogram:
histogram[k] += 1
else:
histogram[k] = 1
sorted_histogram = {} # 建立排好序的映射表
sorted_list = sorted(histogram) # 根据灰度值进行从低至高的排序
for j in range(len(sorted_list)):
sorted_histogram[sorted_list[j]] = histogram[sorted_list[j]]
return sorted_histogram
def equalization_histogram(histogram, img):
pr = {} # 建立概率分布映射表
for i in histogram.keys():
pr[i] = histogram[i] / (img.shape[0] * img.shape[1])
tmp = 0
for m in pr.keys():
tmp += pr[m]
pr[m] = max(histogram) * tmp
new_img = np.zeros(shape=(img.shape[0], img.shape[1]), dtype=np.uint8)
for k in range(img.shape[0]):
for l in range(img.shape[1]):
new_img[k][l] = pr[img[k][l]]
return new_img
if __name__ == '__main__':
# 读取原始图像
img = cv2.imread('body_x_ray.jpg', cv2.IMREAD_GRAYSCALE)
# 计算原图灰度直方图
origin_histogram = Origin_histogram(img)
# 直方图均衡化
new_img1 = equalization_histogram(origin_histogram, img)# 进行直方图均衡化
# 显示原始图像和直方图均衡化后的图像
cv2.imshow('original', img)
cv2.imshow('processed', new_img1)
cv2.waitKey(0) # 等待用户按下任何键
结果:
得到灰度直方图均衡化之后的图像,可以看出树叶”锃亮“了许多,图像变得很清晰,叶子的纹理也显现了出来,图像质量不再是灰蒙蒙的了。
题目4:请对下图做伽马变换,以增强其对比度。
伽马变换是一种非线性的图像增强方法,主要用于调整图像的亮度、对比度和颜色平衡。伽马变换是通过调整伽马值来调整图像的对比度和亮度。
伽马变换的主要作用包括:
提升对比度:对于一些灰度值过低的图像,它们的对比度非常低,难以展示图像内部的细节。通过将伽马值设定在低于1的值,可以提升图像中灰度值较低的像素的亮度值,这可以提高图像的整体对比度,从而增强图像的可视性。
调整亮度和颜色平衡:在图像处理中,经常需要对图像中的亮度和色彩进行调整。对于过于暗淡的图像,可以通过将伽马值设定在大于1的值来调整亮度。如果图像的颜色分布歪曲或过为淡板,可以采用比给定伽马值更大的值来进行颜色平衡。
在图像编码中的应用:伽马变换在图像编码中被广泛使用,它可以有效的消除图像数据中的大量冗余信息,并在保持图像质量的情况下缩小图像的数据规模。
伽马变换是一种实用的图像处理方法,它可以用于提高图像质量、调整图像的亮度和色彩平衡等方面,增强图像的可视性和实用性,在图像处理和计算机视觉等领域具有广泛的应用价值。
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 读取需要处理的图像
img = cv2.imread('1.jpg', cv2.IMREAD_GRAYSCALE)
# 设定伽马值
gamma = 0.5
# 对图像进行伽马变换
gamma_correction = np.power(img / 255.0, gamma)
gamma_correction = (gamma_correction * 255).astype(np.uint8)
# 显示原始图像和伽马变换后的图像
fig = plt.figure(figsize=(10, 10))
ax1 = fig.add_subplot(2, 1, 1)
ax1.imshow(img, cmap='gray')
ax1.title.set_text("original")
ax2 = fig.add_subplot(2, 1, 2)
ax2.imshow(gamma_correction, cmap='gray')
ax2.title.set_text("processed")
plt.show()
结果:
可以看到,图像经过伽马变换后,提升了图像中灰度值较低的像素的亮度值,提高了图像的整体对比度,从而使图像可视性大大增强。
题目5:请对图像分别采用均值滤波器和中值滤波器进行滤波处理,并对处理后的结果进行分析。
中值滤波:
中值滤波是一种非线性的信号处理方法,所以它是一种非线性滤波器,也是一种统计排序滤波器。它将每一像素点的灰度值设置为该点某邻域窗口内的所有像素点灰度值的中值。
中值滤波对孤立的噪声像素即椒盐噪声、脉冲噪声具有良好的滤波效果,可以保持图像的边缘特性,不会使图像产生显著的模糊。
中值滤波是把数字图像或数字序列中一点的值用该点的一个邻域中各点值的中值代替,让周围的像素值接近真实值,从而消除孤立的噪声点。
均值滤波:
平滑线性空间滤波器的输出是包含在滤波器模板邻域内的像素的简单平均值,也就是均值滤波器。均值滤波器也是低通滤波器,均值滤波器很容易理解,即把邻域内的平均值赋给中心元素。
均值滤波器用来降低噪声,均值滤波器的主要应用是去除图像中的不相关细节,不相关是指与滤波器的模板相比较小的像素区域。模糊图片以便得到感兴趣物体的粗略描述,因此那些较小的物体的灰度就会与背景混合在一起,较大的物体则变的像斑点而易于检测。模板的大小由那些即将融入背景中的物体尺寸决定。
均值滤波器的缺点是存在着边缘模糊的问题。
import cv2
import numpy as np
def MedianFilter(img, k=3):
h, w = img.shape
pad = k // 2
out = np.zeros((h + 2 * pad, w + 2 * pad), dtype="uint8")
out[pad:pad + h, pad:pad + w] = img.astype(np.float)
for y in range(h):
for x in range(w):
out[pad + y, pad + x] = np.median(img[y:y + k, x:x + k]) # 调用np.median求取中值
return out
def MeanFilter(img, k=3):
h, w = img.shape
pad = k // 2
out = np.zeros((h + 2 * pad, w + 2 * pad), dtype="uint8")
out[pad:pad + h, pad:pad + w] = img.astype(np.float)
for y in range(h):
for x in range(w):
out[pad + y, pad + x] = np.mean(img[y:y + k, x:x + k]) # 调用np.mean求均值
return out
if __name__ == "__main__":
# process("image_salt_pepper2.jpg")
img = cv2.imread("image_salt_pepper2.jpg", 0)
result1 = MedianFilter(img)
result2 = MeanFilter(img)
cv2.imshow("Original", img )
cv2.imshow("MedianFilter", result1)
cv2.imshow("MeanFilter", result2)
cv2.waitKey(0)
cv2.destroyAllWindows()
结果图:
中值滤波:
均值滤波:
可以看到中值滤波基本去掉了图像的噪点,均值滤波则还含有少量噪点,但是平均地消弱了噪点的影响。
两者都具有起到平滑图像,滤去噪声的功能。