Python OpenCV中的图像规格化

Python OpenCV中的图像规格化,python,opencv,Python,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(

我编写了以下代码来使用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的平均值和标准偏差,然后根据上下范围剪裁帧。此外,我们可以使用偏移来动态调整剪辑强度。从这里开始,我们将原始图像标准化到这个新范围。结果如下:

->

代码


通过对结果应用热图,可以可视化基于整个图像的规格化与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边界框坐标是使用获得的,热图代码来自

使用L1规范化图像的动机是什么?Python要求我指定dst输入参数。在这种情况下,您可能希望将norm_image初始化为image的副本,并将其作为dst传递。@ckirksey3您只需将
None
作为
dst
传递即可。添加一行额外的代码没有意义。那么NORM_MINMAX中到底发生了什么呢?最小像素值将映射到最小输出值(alpha),最大像素值将映射到最大输出值(beta)。我相信,对于介于两者之间的所有事物,都使用线性缩放。NORM_MINMAX沿着((像素值-alpha)/(β-alpha))*β线计算。这与@rsaxvc的回答是一致的。只是一个次要的兴趣点。我注意到,应该能够使用skimage rescale_intensity在一个命令中结合np.clip和cv2.normalize。看见
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()