【代码】遥感影像匀色
【代码】遥感影像匀色
ytkz这里实现的是遥感影像匀色的功能——直方图匹配。
直方图匹配是一种用于图像处理的技术,它可以用来调整一幅图像的颜色或灰度分布,使其与另一幅图像的颜色或灰度分布相匹配。这种技术常常用于图像增强,例如改善图像的对比度或者进行颜色校正。
首先,让我们解释一下什么是直方图。在图像处理中,直方图是一个表,它显示了图像中各个颜色或灰度级别的像素数量。例如,一个灰度图像的直方图可能会显示有多少个像素是黑色的,有多少个像素是灰色的,有多少个像素是白色的,等等。
直方图匹配的过程大致如下:
- 计算两幅图像的直方图。这给了我们每幅图像的颜色或灰度分布。
- 计算两个直方图的累积分布函数(CDF)。CDF表示的是图像中小于或等于某个颜色或灰度级别的像素的累积比例。
- 对于原始图像中的每个像素,找到与其灰度级别相匹配的目标图像的灰度级别。这就是通过查找具有最接近CDF值的目标图像的灰度级别来完成的。
- 将原始图像中的每个像素替换为匹配的灰度级别。
通过这种方式,我们可以调整原始图像的颜色或灰度分布,使其看起来更像目标图像。
代码
import numpy as np
import matplotlib.pyplot as plt
import cv2
import time
import matplotlib
def arrayToHist(img, bins):
hist, _ = np.histogram(img.flatten(), bins, [0,256])
return hist / np.prod(img.shape)
def histMatch(img, hist_match):
hist = arrayToHist(img, 256)
cdf_img = hist.cumsum()
cdf_match = hist_match.cumsum()
M = np.interp(cdf_img, cdf_match, np.arange(256))
return M[img.astype(np.uint8)]
def process_channel(img, img_match):
hist_match = arrayToHist(img_match, 256)
img_matched = histMatch(img, hist_match)
return ((img_matched - img_matched.min()) / (img_matched.max() - img_matched.min()) * 255).astype(np.uint8)
def multi_channel_hist_match(img, img_match):
if img.ndim == 3:
result = np.zeros_like(img)
for i in range(img.shape[2]):
result[:,:,i] = process_channel(img[:,:,i], img_match[:,:,i])
elif img.ndim == 2:
result = process_channel(img, img_match)
else:
raise ValueError("Input images must be 2D or 3D arrays")
return result
if __name__ == '__main__':
start_time = time.time()
imdir = "Colorbalance_1.jpg"
imdir_match = "Colorbalance_2.jpg"
img = cv2.imread(imdir)[..., ::-1]
img_match = cv2.imread(imdir_match)[..., ::-1]
img_matched = multi_channel_hist_match(img_match, img)
matplotlib.rcParams['font.sans-serif'] = ['SimHei'] # 用黑体显示中文
plt.figure()
plt.subplot(1, 3, 1)
plt.title("原始图片")
plt.imshow(img)
plt.subplot(1, 3, 2)
plt.title("match图片")
plt.imshow(img_match)
plt.subplot(1, 3, 3)
plt.title("match后的图片")
plt.imshow(img_matched)
plt.savefig('1.png', format='png', bbox_inches='tight', pad_inches=0, dpi=300)
plt.show()
print(f'耗时 {time.time() - start_time}秒')
结果展示
代码解释
这段代码实现了直方图匹配,也就是将一张图像的颜色分布调整为与另一张图像相同。主要步骤包括读取图片、计算直方图、匹配直方图、处理图像的每个通道(对于彩色图像),然后显示和保存结果。
以下是代码中函数的具体解释:
arrayToHist(img, bins)
: 这个函数将图像转换为直方图。它使用numpy的histogram
函数来计算直方图,然后将直方图归一化,使其总和为1。histMatch(img, hist_match)
: 这个函数实现了直方图匹配。它首先计算输入图像的直方图和累积分布函数(CDF),然后使用numpy的interp
函数找到匹配图像的CDF与输入图像的CDF之间的映射关系。最后,它使用这个映射关系将输入图像的每个像素值替换为匹配的像素值。process_channel(img, img_match)
: 这个函数处理图像的每个通道。它首先计算匹配图像的直方图,然后使用histMatch
函数将输入图像的直方图匹配到匹配图像的直方图。最后,它将匹配后的图像归一化到0-255的范围,并将其转换为8位无符号整数。multi_channel_hist_match(img, img_match)
: 这个函数处理多通道图像。如果输入图像是三维的(即,它有多个通道),那么它将对每个通道分别进行处理。如果输入图像是二维的(即,它只有一个通道),那么它将直接处理这个通道。
在主程序中,首先读取两张图像,然后使用multi_channel_hist_match
函数将一张图像的直方图匹配到另一张图像的直方图。然后,它使用matplotlib来显示原始图像、匹配图像和匹配后的图像,并保存匹配后的图像为PNG文件。最后,它打印出程序的运行时间。
小结
这里的遥感影像匀色,本质上是对8bit的图片进行匀色。
即需要在匀色前,要把遥感影像的位深转换为8比特。