在 OpenCV 中规范化图像
Normalizing images in OpenCV
我在 OpenCV 中使用 NORM_L1 编写了以下代码来规范化图像。但输出图像只是黑色。如何解决?
import cv2
import numpy as np
import Image
img = cv2.imread('img7.jpg')
gray_image = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
a = np.asarray(gray_image)
dst = np.zeros(shape=(5,2))
b=cv2.normalize(a,dst,0,255,cv2.NORM_L1)
im = Image.fromarray(b)
im.save("img50.jpg")
cv2.waitKey(0)
cv2.destroyAllWindows()
当您使用 NORM_L1 归一化矩阵时,您是将每个像素值除以图像中所有像素的绝对值之和。
结果,所有像素值都变得远小于 1,并且您得到一个黑色图像。尝试 NORM_MINMAX 而不是 NORM_L1.
如果要将范围更改为 [0, 1],请确保输出数据类型为 float
。
image = cv2.imread("lenacolor512.tiff", cv2.IMREAD_COLOR) # uint8 image
norm_image = cv2.normalize(image, None, alpha=0, beta=1, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_32F)
其他答案基于整个图像对图像进行归一化。但是如果你的图像有一个主要的颜色(比如黑色),它会掩盖你试图增强的特征,因为它不会那么明显。为了绕过这个限制,我们可以根据感兴趣的分段区域 (ROI) 对图像进行归一化。本质上,我们将根据我们想要增强的图像部分进行归一化,而不是用相同的权重平等对待每个像素。以这张地球图片为例:
输入图像->
基于整个图像的归一化
如果我们想通过基于整个图像的归一化来增强云层,结果将不会很清晰并且会由于黑色背景而过度饱和。要增强的功能丢失了。因此,为了获得更好的结果,我们可以裁剪 ROI,根据 ROI 进行归一化,然后将归一化应用回原始图像。假设我们裁剪以绿色突出显示的 ROI:
这给了我们这个投资回报率
思路是计算ROI的均值和标准差,然后根据下限和上限范围裁剪帧。此外,我们可以使用偏移量来动态调整剪辑强度。从这里我们将原始图像标准化到这个新范围。结果如下:
之前->
之后
代码
import cv2
import numpy as np
# Load image as grayscale and crop ROI
image = cv2.imread('1.png', 0)
x, y, w, h = 364, 633, 791, 273
ROI = image[y:y+h, x:x+w]
# Calculate mean and STD
mean, STD = cv2.meanStdDev(ROI)
# Clip frame to lower and upper STD
offset = 0.2
clipped = np.clip(image, mean - offset*STD, mean + offset*STD).astype(np.uint8)
# Normalize to range
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 的特定部分的归一化之间的差异可以通过对结果应用热图来可视化。请注意云的定义方式的不同。
输入图像->
热图
对整个图像进行标准化 ->
热图
ROI 归一化 ->
热图
热图代码
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边界框坐标是使用how to get ROI Bounding Box Coordinates without Guess & Check and heatmap code was from
得到的
我在 OpenCV 中使用 NORM_L1 编写了以下代码来规范化图像。但输出图像只是黑色。如何解决?
import cv2
import numpy as np
import Image
img = cv2.imread('img7.jpg')
gray_image = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
a = np.asarray(gray_image)
dst = np.zeros(shape=(5,2))
b=cv2.normalize(a,dst,0,255,cv2.NORM_L1)
im = Image.fromarray(b)
im.save("img50.jpg")
cv2.waitKey(0)
cv2.destroyAllWindows()
当您使用 NORM_L1 归一化矩阵时,您是将每个像素值除以图像中所有像素的绝对值之和。 结果,所有像素值都变得远小于 1,并且您得到一个黑色图像。尝试 NORM_MINMAX 而不是 NORM_L1.
如果要将范围更改为 [0, 1],请确保输出数据类型为 float
。
image = cv2.imread("lenacolor512.tiff", cv2.IMREAD_COLOR) # uint8 image
norm_image = cv2.normalize(image, None, alpha=0, beta=1, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_32F)
其他答案基于整个图像对图像进行归一化。但是如果你的图像有一个主要的颜色(比如黑色),它会掩盖你试图增强的特征,因为它不会那么明显。为了绕过这个限制,我们可以根据感兴趣的分段区域 (ROI) 对图像进行归一化。本质上,我们将根据我们想要增强的图像部分进行归一化,而不是用相同的权重平等对待每个像素。以这张地球图片为例:
输入图像->
基于整个图像的归一化
如果我们想通过基于整个图像的归一化来增强云层,结果将不会很清晰并且会由于黑色背景而过度饱和。要增强的功能丢失了。因此,为了获得更好的结果,我们可以裁剪 ROI,根据 ROI 进行归一化,然后将归一化应用回原始图像。假设我们裁剪以绿色突出显示的 ROI:
这给了我们这个投资回报率
思路是计算ROI的均值和标准差,然后根据下限和上限范围裁剪帧。此外,我们可以使用偏移量来动态调整剪辑强度。从这里我们将原始图像标准化到这个新范围。结果如下:
之前->
之后
代码
import cv2
import numpy as np
# Load image as grayscale and crop ROI
image = cv2.imread('1.png', 0)
x, y, w, h = 364, 633, 791, 273
ROI = image[y:y+h, x:x+w]
# Calculate mean and STD
mean, STD = cv2.meanStdDev(ROI)
# Clip frame to lower and upper STD
offset = 0.2
clipped = np.clip(image, mean - offset*STD, mean + offset*STD).astype(np.uint8)
# Normalize to range
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 的特定部分的归一化之间的差异可以通过对结果应用热图来可视化。请注意云的定义方式的不同。
输入图像->
热图
对整个图像进行标准化 ->
热图
ROI 归一化 ->
热图
热图代码
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边界框坐标是使用how to get ROI Bounding Box Coordinates without Guess & Check and heatmap code was from