说明
本文记录数字图像处理相关问题。导入的依赖如下:
import cv2
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image
matplotlib.rcParams['font.sans-serif'] = ['SimHei'] # 显示中文
# 为了坐标轴负号正常显示。matplotlib默认不支持中文,设置中文字体后,负号会显示异常。需要手动将坐标轴负号设为False才能正常显示负号。
matplotlib.rcParams['axes.unicode_minus'] = False
1. 图像点处理
1.1 图像翻转
img = Image.open("data//Lenna.jpg")
plt.subplot(2, 2, 1)
plt.imshow(img)
plt.title("原图")
img_lR = img.transpose(Image.FLIP_LEFT_RIGHT) #上下翻转则调成TOP_BUTTOM
plt.subplot(2, 2, 2)
plt.imshow(img_lR)
plt.title("左右翻转")
plt.show()
结果如下:
1.2 幂运算和对数运算
img = cv2.imread("data//cameraman.tif")
plt.subplot(2, 2, 1)
plt.imshow(img)
plt.title("原图")
img_pow = cv2.pow(src=img, power=2)
plt.subplot(2, 2, 2)
plt.imshow(img_pow)
plt.title("2次幂")
img = np.float32(img)
img_log = cv2.log(img)
plt.subplot(2, 2, 3)
plt.imshow(img_log)
plt.title("对数")
plt.show()
结果如下:
2. 直方图处理
分析:直方图简单来说就是图像中每个像素值的个数统计。直方图均衡化就是用来改善图像的全局亮度和对比度。 均衡化作用:将原来比较少像素的灰度分配到别的灰度中,像素相对集中,均衡后灰度范围变大,对比度变大,清晰度变大,故能有效地增强图像。
# 均衡化
def hist_equal(img, z_max=255):
H, W = img.shape
S = H * W * 1.
out = img.copy()
sum_h = 0.
for i in range(1, 255):
ind = np.where(img == i)
sum_h += len(img[ind])
z_prime = z_max / S * sum_h
out[ind] = z_prime
out = out.astype(np.uint8)
return out
# 3.直方图处理
img = cv2.imread("data//Lenna.jpg", 0).astype(np.float32)
plt.subplot(2, 2, 1)
plt.imshow(img)
plt.title("原图")
plt.subplot(2, 2, 2)
plt.hist(img.ravel(), bins=255, rwidth=0.8, range=(0, 255))
plt.title("原图的直方图")
img_hist = hist_equal(img)
plt.subplot(2, 2, 3)
plt.imshow(img_hist)
plt.title("均衡化后的图")
plt.subplot(2, 2, 4)
plt.hist(img_hist.ravel(), bins=255, rwidth=0.8, range=(0, 255))
plt.title("均衡化直方图")
plt.show()
结果:
3. 图像平滑
图像平滑是一种区域增强算法,平滑算法有:均值滤波、中值滤波、高斯滤波等。 均值滤波:指任意一点的像素值,都是周围N*M个像素值的均值。 中值滤波:中值滤波是非线性的图像处理方法,在去噪的同时可以兼顾到边界信息的保留。具体做法:选一个含有奇数点的窗口W,将这个窗口在图像上扫描,把窗口中所含的像素点按灰度级的升或降序排列,取位于中间的灰度值来代替该点的灰度值。 高斯滤波:图像高斯平滑也是邻域平均的思想对图像进行平滑的一种方法,在图像高斯平滑中,对图像进行平均时,不同位置的像素被赋予了不同的权重。 方框滤波:和均值滤波差不多,区别在于需不需要均一化处理。
# 4. 图像平滑: 用不同大小的核进行均值滤波、中值滤波、高斯滤波等。
# 4.0 读取原图
img = cv2.imread("data//Lenna.jpg")
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # 调整通道顺序,解决imread图片读取发蓝的问题
plt.subplot(3, 2, 1)
plt.imshow(img)
plt.title("原图")
# 4.1 均值滤波
img_avg = cv2.blur(src=img, ksize=(5, 5))
plt.subplot(3, 2, 2)
plt.imshow(img_avg)
plt.title("均值滤波")
# 4.2 中值滤波
img_median = cv2.medianBlur(src=img, ksize=5)
plt.subplot(3, 2, 3)
plt.imshow(img_median)
plt.title("中值滤波")
# 4.3 高斯滤波
img_gauss = cv2.GaussianBlur(img, ksize=(5, 5),sigmaX=0)
plt.subplot(3, 2, 4)
plt.imshow(img_median)
plt.title("高斯滤波")
# 4.4 方框滤波
img_fang = cv2.boxFilter(src=img, ddepth=-1, ksize=(5, 5), normalize=1) # normalize=1表示做归一化处理
plt.subplot(3, 2, 5)
plt.imshow(img_median)
plt.title("方框滤波")
plt.show()
结果:
4. 图像锐化
Laplacian算子是图像的二阶导,可以检测图像灰度的快速变化,经常用于图像的边缘检测。正常图像中边界清晰,经拉普拉斯计算后方差较大;模糊图像边界信息少,方差小。所以,可以利用拉普拉斯算子做图像的模糊检测。
# 5.图像锐化: 计算laplacian图像、梯度图像。
img = cv2.imread("data//Lenna.jpg")
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # 调整通道顺序,解决imread图片读取发蓝的问题
plt.subplot(3, 2, 1)
plt.imshow(img)
plt.title("原图")
# 5.1 Laplacian
img_Laplacian = cv2.Laplacian(src=img, ddepth=-1, ksize=3) # ddept=-1表示和原图像一样的深度,可调节
plt.subplot(3, 2, 2)
plt.imshow(img_Laplacian)
plt.title("Laplacian")
# 5.2 Sobel
img_sobel = cv2.Sobel(src=img, ddepth=cv2.CV_64F, dx=1, dy=0, ksize=3)
plt.subplot(3, 2, 3)
plt.imshow(img_sobel)
plt.title("sobel")
plt.show()
结果:
5. 图像增强
图像增强有很多方式,本文采用了直方图均衡、拉普拉斯算子、对数变换、伽马变换、限制对比度自适应直方图均衡化来进行图像增强。
# 直方图均衡增强
def hist(image):
r, g, b = cv2.split(image)
r1 = cv2.equalizeHist(r)
g1 = cv2.equalizeHist(g)
b1 = cv2.equalizeHist(b)
image_equal_clo = cv2.merge([r1, g1, b1])
return image_equal_clo
# 拉普拉斯算子
def laplacian(image):
kernel = np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]])
image_lap = cv2.filter2D(image, cv2.CV_8UC3, kernel)
return image_lap
# 对数变换
def log(image):
image_log = np.uint8(np.log(np.array(image) + 1))
cv2.normalize(image_log, image_log, 0, 255, cv2.NORM_MINMAX)
# 转换成8bit图像显示
cv2.convertScaleAbs(image_log, image_log)
return image_log
# 伽马变换
def gamma(image):
fgamma = 2
image_gamma = np.uint8(np.power((np.array(image) / 255.0), fgamma) * 255.0)
cv2.normalize(image_gamma, image_gamma, 0, 255, cv2.NORM_MINMAX)
cv2.convertScaleAbs(image_gamma, image_gamma)
return image_gamma
# 限制对比度自适应直方图均衡化CLAHE
def clahe(image):
b, g, r = cv2.split(image)
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
b = clahe.apply(b)
g = clahe.apply(g)
r = clahe.apply(r)
image_clahe = cv2.merge([b, g, r])
return image_clahe
img = cv2.imread("data//fig3_43.tif")
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # 调整通道顺序,解决imread图片读取发蓝的问题
plt.subplot(3, 2, 1)
plt.imshow(img)
plt.title("原图")
# 6.1 使用直方图增强
img_hist = hist(img)
plt.subplot(3, 2, 2)
plt.imshow(img_hist)
plt.title("hist")
# 6.2 使用拉普拉斯算子增强
img_laplacian = laplacian(img)
plt.subplot(3, 2, 3)
plt.imshow(img_laplacian)
plt.title("img_laplacian")
# 6.3使用对数变换增强
img_log = log(img)
plt.subplot(3, 2, 4)
plt.imshow(img_log)
plt.title("img_log")
# 6.4 使用伽马变换增强
img_gamma = gamma(img)
plt.subplot(3, 2, 5)
plt.imshow(img_gamma)
plt.title("img_gamma")
# 6.5 限制对比度自适应直方图均衡化CLAHE
img_clahe = clahe(img)
plt.subplot(3, 2, 6)
plt.imshow(img_clahe)
plt.title("img_clahe")
plt.show()
结果如下:
|