其他答案基于整个图像来进行图像归一化。但是,如果您的图像具有主导颜色(例如黑色),它将掩盖您要增强的特征,因为它将不会如此明显。为了避免这种限制,我们可以基于感兴趣的子区域(ROI)对图像进行归一化。实质上,我们将根据要增强的图像部分对图像进行归一化,而不是平等地处理每个像素。以这张地球图片为例:
输入图像 -> 基于整个图像的归一化
![](https://istack.dev59.com/dYu8q.webp)
如果我们想通过基于整个图像的归一化来增强云层,则结果不会非常清晰,并且由于黑色背景而过度饱和。需要增强的特征将会丢失。因此,为了获得更好的结果,我们可以裁剪出一个感兴趣区域(ROI),基于ROI进行归一化,然后将归一化应用回原始图像中。假设我们裁剪出了绿色高亮显示的ROI:
![](https://istack.dev59.com/OMYtX.webp)
这给我们带来了投资回报率{{ROI}}。
![](https://istack.dev59.com/qKu29.webp)
这个想法是计算ROI的平均值和标准差,然后根据下限和上限范围裁剪帧。此外,我们可以使用偏移量来动态调整剪辑强度。从这里开始,我们将原始图像归一化到这个新范围。这是结果:
之前->
之后
![](https://istack.dev59.com/Q61X1.webp)
代码
import cv2
import numpy as np
image = cv2.imread('1.png', 0)
x, y, w, h = 364, 633, 791, 273
ROI = image[y:y+h, x:x+w]
mean, STD = cv2.meanStdDev(ROI)
offset = 0.2
clipped = np.clip(image, mean - offset*STD, mean + offset*STD).astype(np.uint8)
result = cv2.normalize(clipped, clipped, 0, 255, norm_type=cv2.NORM_MINMAX)
cv2.imshow('image', image)
cv2.imshow('ROI', ROI)
cv2.imshow('result', result)
cv2.waitKey()
基于整个图像和ROI特定部分进行归一化的区别可以通过将热力图应用于结果来可视化。请注意云的定义方式的差异。
输入图像->
热力图
![](https://istack.dev59.com/zTRRu.webp)
整张图片归一化 ->
热力图
![](https://istack.dev59.com/yhm7R.webp)
基于ROI进行归一化 ->
热力图
![](https://istack.dev59.com/tiQJ4.webp)
热力图代码
import matplotlib.pyplot as plt
import numpy as np
import cv2
image = cv2.imread('result.png', 0)
colormap = plt.get_cmap('inferno')
heatmap = (colormap(image) * 2**16).astype(np.uint16)[:,:,:3]
heatmap = cv2.cvtColor(heatmap, cv2.COLOR_RGB2BGR)
cv2.imshow('image', image)
cv2.imshow('heatmap', heatmap)
cv2.waitKey()
注意: ROI边界框坐标是使用如何在不猜测和检查的情况下获取ROI边界框坐标获得的,热力图代码来自如何使用Python OpenCV将灰度图像转换为热力图像