三、直方圖均衡化
1. 普通直方圖均衡化
直方圖均衡化的原理是將圖像的灰度直方圖展平,使得每個灰度級都有更多的像素分布,從而增強圖像的對比度。具體步驟如下:
- 計算灰度直方圖:統計圖像中每個灰度級的像素數量。
- 計算累積分布函數(CDF):計算每個灰度級的累積概率。
- 映射灰度值:將原始圖像中的每個灰度值映射到新的灰度值,使得新的灰度分布更加均勻。
- 生成均衡化后的圖像:使用映射后的灰度值生成新的圖像。
import cv2
import numpy as np
import matplotlib.pyplot as pltdef histogram_equalization(image):"""直方圖均衡化:param image: 輸入圖像(灰度圖像):return: 處理后的圖像"""if len(image.shape) == 3:image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)equalized_image = cv2.equalizeHist(image)return equalized_imagedef main():# 讀取圖像image = cv2.imread('demo.jpg')if image is None:print("Error: Could not read image.")return# 直方圖均衡化equalized_image = histogram_equalization(image)# 顯示原始圖像和處理后的圖像plt.figure(figsize=(8, 4))plt.subplot(1, 2, 1)plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))plt.title('Original Image')plt.axis('off')plt.subplot(1, 2, 2)plt.imshow(equalized_image, cmap='gray')plt.title('Histogram Equalized Image')plt.axis('off')plt.tight_layout()plt.show()# 顯示直方圖plt.figure(figsize=(12, 6))plt.subplot(1, 2, 1)plt.hist(image.ravel(), 256, [0, 256], color='gray', alpha=0.7)plt.title('Histogram of Original Image')plt.xlabel('Pixel Value')plt.ylabel('Frequency')plt.subplot(1, 2, 2)plt.hist(equalized_image.ravel(), 256, [0, 256], color='gray', alpha=0.7)plt.title('Histogram of Equalized Image')plt.xlabel('Pixel Value')plt.ylabel('Frequency')plt.tight_layout()plt.show()if __name__ == "__main__":
2. 限制對比度自適應直方圖均衡化(Contrast Limited Adaptive Histogram Equalization, CLAHE)
限制對比度自適應直方圖均衡化在直方圖均衡化的基礎上進行了改進,通過限制對比度和局部均衡化來避免過度增強圖像的對比度,從而減少噪聲和不自然的效果。基本原理如下:
- 圖像分割:將圖像分割成若干個小塊(稱為“tiles”),每個小塊的大小由 tileGridSize 參數指定。
- 局部均衡化:對每個小塊分別進行直方圖均衡化。為了限制對比度,使用 clipLimit 參數來限制每個小塊的直方圖中像素值的最大數量。
- 插值平滑:將每個小塊均衡化后的結果通過插值技術合并,以避免明顯的邊界和不連續性。
import cv2
import numpy as np
import matplotlib.pyplot as pltdef clahe_equalization(image, clipLimit=2.0, tileGridSize=(8, 8)):"""CLAHE均衡化:param image: 輸入圖像(灰度圖像):param clipLimit: 對比度限制閾值:param tileGridSize: 小塊大小:return: 處理后的圖像"""if len(image.shape) == 3:image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)clahe = cv2.createCLAHE(clipLimit=clipLimit, tileGridSize=tileGridSize)clahe_image = clahe.apply(image)return clahe_imagedef main():# 讀取圖像image = cv2.imread('demo.jpg')if image is None:print("Error: Could not read image.")return# CLAHE均衡化clahe_image = clahe_equalization(image, clipLimit=2.0, tileGridSize=(8, 8))# 顯示原始圖像和處理后的圖像plt.figure(figsize=(8, 4))plt.subplot(1, 2, 1)plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))plt.title('Original Image')plt.axis('off')plt.subplot(1, 2, 2)plt.imshow(clahe_image, cmap='gray')plt.title('CLAHE Equalized Image')plt.axis('off')plt.tight_layout()plt.show()# 顯示直方圖plt.figure(figsize=(12, 6))plt.subplot(1, 2, 1)plt.hist(image.ravel(), 256, [0, 256], color='gray', alpha=0.7)plt.title('Histogram of Original Image')plt.xlabel('Pixel Value')plt.ylabel('Frequency')plt.subplot(1, 2, 2)plt.hist(clahe_image.ravel(), 256, [0, 256], color='gray', alpha=0.7)plt.title('Histogram of CLAHE Equalized Image')plt.xlabel('Pixel Value')plt.ylabel('Frequency')plt.tight_layout()plt.show()if __name__ == "__main__":main()
四、空間域(增強)
空間域增強方法直接操作圖像的像素值,常用于提高圖像的可視性和特征表現。空間域增強方法可以分為線性濾波和非線性濾波兩大類。此外,邊緣檢測也是一種重要的空間域增強技術,用于突出圖像中的邊緣和細節。
1. 線性濾波
線性濾波通過卷積操作對圖像進行處理,常用的線性濾波器包括方框濾波、均值濾波器、高斯濾波器和銳化濾波器等。
(1) 方框濾波(Box Filtering)
方框濾波是一種簡單的均值濾波,通過計算每個像素鄰域內的平均值來平滑圖像。具體來說,對于每個像素,取其鄰域內的所有像素值的平均值作為該像素的新值。
import cv2
import numpy as np
import matplotlib.pyplot as pltdef box_filter(image, kernel_size=(3, 3)):"""方框濾波:param image: 輸入圖像:param kernel_size: 濾波器大小:return: 處理后的圖像"""filtered_image = cv2.boxFilter(image, -1, kernel_size)return filtered_imagedef main():# 讀取圖像image = cv2.imread('demo.jpg')if image is None:print("Error: Could not read image.")return# 方框濾波box_filtered_image = box_filter(image, kernel_size=(5, 5))# 顯示原始圖像和處理后的圖像plt.figure(figsize=(8, 4))plt.subplot(1, 2, 1)plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))plt.title('Original Image')plt.axis('off')plt.subplot(1, 2, 2)plt.imshow(cv2.cvtColor(box_filtered_image, cv2.COLOR_BGR2RGB))plt.title('Box Filtered Image')plt.axis('off')plt.tight_layout()plt.show()if __name__ == "__main__":main()
(2) 均值濾波器(Mean Filter)
均值濾波器通過計算每個像素鄰域內的平均值來平滑圖像。具體來說,對于每個像素,取其鄰域內的所有像素值的平均值作為該像素的新值。
import cv2
import numpy as np
import matplotlib.pyplot as pltdef mean_filter(image, kernel_size=(3, 3)):"""均值濾波:param image: 輸入圖像:param kernel_size: 濾波器大小:return: 處理后的圖像"""filtered_image = cv2.blur(image, kernel_size)return filtered_imagedef main():# 讀取圖像image = cv2.imread('demo.jpg')if image is None:print("Error: Could not read image.")return# 均值濾波mean_filtered_image = mean_filter(image, kernel_size=(5, 5))# 顯示原始圖像和處理后的圖像plt.figure(figsize=(8, 4))plt.subplot(1, 2, 1)plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))plt.title('Original Image')plt.axis('off')plt.subplot(1, 2, 2)plt.imshow(cv2.cvtColor(mean_filtered_image, cv2.COLOR_BGR2RGB))plt.title('Mean Filtered Image')plt.axis('off')plt.tight_layout()plt.show()if __name__ == "__main__":main()
(3) 高斯濾波器(Gaussian Filter)
高斯濾波器通過高斯核對圖像進行卷積操作,以平滑圖像并減少噪聲。高斯核的權重分布符合高斯分布,中心權重最大,邊緣權重逐漸減小。
import cv2
import numpy as np
import matplotlib.pyplot as pltdef gaussian_filter(image, kernel_size=(5, 5), sigmaX=0):"""高斯濾波:param image: 輸入圖像:param kernel_size: 濾波器大小:param sigmaX: 高斯核的標準差:return: 處理后的圖像"""filtered_image = cv2.GaussianBlur(image, kernel_size, sigmaX)return filtered_imagedef main():# 讀取圖像image = cv2.imread('demo.jpg')if image is None:print("Error: Could not read image.")return# 高斯濾波gaussian_filtered_image = gaussian_filter(image, kernel_size=(5, 5), sigmaX=0)# 顯示原始圖像和處理后的圖像plt.figure(figsize=(8, 4))plt.subplot(1, 2, 1)plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))plt.title('Original Image')plt.axis('off')plt.subplot(1, 2, 2)plt.imshow(cv2.cvtColor(gaussian_filtered_image, cv2.COLOR_BGR2RGB))plt.title('Gaussian Filtered Image')plt.axis('off')plt.tight_layout()plt.show()if __name__ == "__main__":main()
(4) 銳化濾波器(Sharpening Filter)
銳化濾波器通過增強圖像的邊緣和細節來提高圖像的清晰度。常用的銳化濾波器包括拉普拉斯算子和高通濾波器。
import cv2
import numpy as np
import matplotlib.pyplot as pltdef sharpen_filter(image, kernel_size=(3, 3), alpha=1.5):"""銳化濾波:param image: 輸入圖像:param kernel_size: 濾波器大小:param alpha: 銳化因子:return: 處理后的圖像"""# 創建銳化濾波器kernel = np.array([[-1, -1, -1],[-1, 8, -1],[-1, -1,