一、实验目的与要求
- 加深对图像增强及边缘检测技术的感性认识,应用MATLAB工具箱自带的处理函数或自己编程完成相关的工作,分析处理结果,巩固所学理论知识。
- 熟练掌握空域滤波中常用的平滑和锐化滤波器,针对不同类型和强度的噪声,进行滤波处理,体会并正确评价滤波效果,了解不同滤波方式的使用场合,能够从理论上作出合理的解释。
二、实验内容
- 图像平滑(去噪):编写超限像素平滑法,灰度最相近的K个邻点平均法(函数名称可以自定义),并对上面实验1选择的噪声图片进行处理,显示处理前后的各个图像,分析不同方法对不同噪声的处理效果及其优缺点。
- 图像锐化:编写梯度锐化算法函数my_grad(method,T);参数method可以是梯度算子、Roberts算子、Prewitt和Sobel算子,T是梯度阈值,根据参数method和T选用不同的算子和阈值进行锐化处理,用二值图像表示处理结果,小于T的用黑色表示,大于等于T的用白色表示。显示处理前后的各个图像,分析不同方法对锐化效果及其优缺点。
?
三、实验?????图像
四、实验?????源程序
首先导入以下库: import random import numpy as np import matplotlib.pyplot as plt import cv2 as cv import heapq
- 图像平滑(去噪):编写超限像素平滑法,灰度最相近的K个邻点平均法(函数名称可以自定义),并对上面实验1选择的噪声图片进行处理,显示处理前后的各个图像,分析不同方法对不同噪声的处理效果及其优缺点。
A. 超限像素平滑法 def neighborhood_smooth(img, k=4):
"""
局部平滑法
k:默认为4邻域
"""
h, w = img.shape[:2]
smooth_img = np.zeros((h - 2, w - 2), dtype=np.uint8)
for i in range(1, h - 1):
for j in range(1, w - 1):
smooth_img[i - 1, j - 1] = (int(img[i - 1, j]) + int(img[i + 1, j])
+ int(img[i, j - 1]) + int(img[i, j + 1])) / k
return smooth_img
def Overite_pixel_smoothing_method(img, T=50):
"""
超限像素平滑法
img:椒盐噪声/高斯噪声图片
T:默认50
"""
# 首先调用局部平滑法进行处理
neighborhood_img = neighborhood_smooth(img, k=4)
h, w = neighborhood_img.shape[:2]
for i in range(h):
for j in range(w):
if np.abs(neighborhood_img[i, j] - img[i, j]) <= T:
neighborhood_img[i, j] = img[i, j]
return neighborhood_img
# 读入图像
src = cv.imread("rice.png", 0) # 以灰度图像读入
img = src.copy()
# 生成噪声图片
img_sp = sp_noise(img, prob=0.02) # 添加椒盐噪声,噪声比例为0.02
img_gauss = gasuss_noise(img, mean=0, var=0.01) # 添加高斯噪声,均值为0,方差为0.01
# 超限像素平滑法处理两种噪声图片
result_img_sp = Overite_pixel_smoothing_method(img_sp, T=60)
result_img_gauss = Overite_pixel_smoothing_method(img_gauss, T=60)
# 显示图像
plt.figure(figsize=(10, 8), dpi=100)
plt.subplot(131)
plt.imshow(src, cmap=plt.cm.gray)
plt.title("原图")
plt.subplot(232)
plt.imshow(img_sp, cmap=plt.cm.gray)
plt.title("椒盐噪声图片")
plt.subplot(233)
plt.imshow(result_img_sp, cmap=plt.cm.gray)
plt.title("超限像素平滑法处理椒盐噪声")
plt.subplot(235)
plt.imshow(img_gauss, cmap=plt.cm.gray)
plt.title("高斯噪声图片")
plt.subplot(236)
plt.imshow(result_img_gauss, cmap=plt.cm.gray)
plt.title("超限像素平滑法处理高斯噪声")
plt.show() (注:本题中用到的添加噪声的函数 sp_noise 和 gasuss_noise 为:) def sp_noise(image, prob):
"""
添加椒盐噪声
prob:噪声比例
"""
output = np.zeros(image.shape, np.uint8)
thres = 1 - prob
for i in range(image.shape[0]):
for j in range(image.shape[1]):
rdn = random.random()
if rdn < prob:
output[i][j] = 0
elif rdn > thres:
output[i][j] = 255
else:
output[i][j] = image[i][j]
return output
def gasuss_noise(image, mean=0, var=0.001):
"""
添加高斯噪声
mean : 均值
var : 方差
"""
image = np.array(image / 255, dtype=float)
noise = np.random.normal(mean, var ** 0.5, image.shape)
out = image + noise
if out.min() < 0:
low_clip = -1.
else:
low_clip = 0.
out = np.clip(out, low_clip, 1.0)
out = np.uint8(out * 255)
return out B. 灰度最相近的K个邻点平均法 (仅写出了算法函数) def K_adjacent_point_average_method(img, s=3, k=5):
"""
灰度最相近的k个邻点平均法
:param img: 传入的噪声图片
:param s: 默认为3*3的领域
:param k: 默认为5,包括中心像素
:return: 返回图片
"""
h, w = img.shape[:2]
smooth_img = np.zeros((h - 2, w - 2), dtype=np.uint8)
dis = int((s - 1) / 2)
temp = []
min_index = []
for i in range(1, h - 1):
for j in range(1, w - 1):
temp = img[i - dis:i + dis + 1, j - dis:j + dis + 1].ravel() # 将3*3的切片转换为1维数组
temp2 = [np.abs(k - int(img[i, j])) for k in temp] # 将列表中每个元素减去中心元素并取绝对值
min_num = heapq.nsmallest(k, temp2) # 找出结果列表中最小的k个数
sum = 0
for t in min_num:
index = temp2.index(t) # 根据min_num寻找原列表的索引
sum += temp[index]
temp2[index] = -1
smooth_img[i - 1, j - 1] = np.round(sum / k) # 给新图像赋值
return smooth_img -
图像锐化:编写梯度锐化算法函数my_grad(method,T);参数method可以是梯度算子、Roberts算子、Prewitt和Sobel算子,T是梯度阈值,根据参数method和T选用不同的算子和阈值进行锐化处理,用二值图像表示处理结果,小于T的用黑色表示,大于等于T的用白色表示。显示处理前后的各个图像,分析不同方法对锐化效果及其优缺点。 class Arth():
Grad = 0
Roberts = 1
Prewitt = 2
Sobel = 3
def my_grad(img, method, T=50):
"""
梯度锐化算法
:param img:输入的灰度图像
:param method:不同的算子
:param T:梯度阈值,默认=50
"""
h, w = img.shape[:2]
new_img = np.zeros((h, w), dtype=np.uint8)
for i in range(h - 1):
for j in range(w - 1):
# 梯度算子
if method == Arth.Grad:
grad = abs(int(img[i, j + 1]) - int(img[i, j])) + abs(int(img[i + 1, j]) - int(img[i, j]))
new_img[i, j] = 255 if grad >= T else 0
# Roberts算子
if method == Arth.Roberts:
grad = abs(int(img[i + 1, j + 1]) - int(img[i, j])) + abs(int(img[i + 1, j]) - int(img[i, j + 1]))
new_img[i, j] = 255 if grad >= T else 0
for i in range(h - 2):
for j in range(w - 2):
# Prewitt算子
if method == Arth.Prewitt:
f_y = sum(img[i:i + 3, j:j + 3][2]) - sum(img[i:i + 3, j:j + 3][0])
f_x = sum(img[i:i + 3, j:j + 3][:, 2]) - sum(img[i:i + 3, j:j + 3][:, 0])
grad = abs(f_y) + abs(f_x)
new_img[i, j] = 255 if grad >= T else 0
# Sobel算子
if method == Arth.Sobel:
f_y = sum(img[i:i + 3, j:j + 3][2]) - sum(img[i:i + 3, j:j + 3][0]) \
+ img[i + 2, j + 1] - img[i, j + 1]
f_x = sum(img[i:i + 3, j:j + 3][:, 2]) - sum(img[i:i + 3, j:j + 3][:, 0]) \
+ img[i + 1, j + 2] - img[i + 1, j]
grad = abs(f_y) + abs(f_x)
new_img[i, j] = 255 if grad >= T else 0
return new_img
# 读入图像
src = cv.imread("rice.png", 0) # 以灰度图像读入
img = src.copy()
Grad_img = my_grad(img, Arth.Grad, 50)
Roberts_img = my_grad(img, Arth.Roberts, 50)
Prewitt_img = my_grad(img, Arth.Prewitt, 70)
Sobel_img = my_grad(img, Arth.Sobel, 70)
# 显示图像
plt.figure(figsize=(10, 8), dpi=200)
plt.subplot(131)
plt.imshow(src, cmap=plt.cm.gray)
plt.title("原图")
plt.subplot(232)
plt.imshow(Grad_img, cmap=plt.cm.gray)
plt.title("梯度算子")
plt.subplot(233)
plt.imshow(Roberts_img, cmap=plt.cm.gray)
plt.title("Roberts算子")
plt.subplot(235)
plt.imshow(Prewitt_img, cmap=plt.cm.gray)
plt.title("Prewitt算子")
plt.subplot(236)
plt.imshow(Sobel_img, cmap=plt.cm.gray)
plt.title("Sobel算子")
plt.show() 另一组图像(T=20,20,60,60): ?
|