在OpenCV中规范化图像

时间:2016-06-25 06:49:01

标签: 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(a,dst,0,255,cv2.NORM_L1)


im = Image.fromarray(b)

im.save("img50.jpg")

cv2.waitKey(0)
cv2.destroyAllWindows()

3 个答案:

答案 0 :(得分:35)

如果要将范围更改为[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)

答案 1 :(得分:14)

使用NORM_L1对矩阵进行标准化时,将每个像素值除以图像中所有像素的绝对值之和。 结果,所有像素值变得远小于1并且您获得黑色图像。尝试使用NORM_MINMAX而不是NORM_L1。

答案 2 :(得分:10)

其他答案根据整个图像对图像进行归一化。但是,如果您的图像具有主要颜色(例如黑色),则它将掩盖您尝试增强的功能,因为它不会那么明显。为了解决这个限制,我们可以基于感兴趣的子区域(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()

注意:使用how to get ROI Bounding Box Coordinates without Guess & Check获得了ROI边界框坐标,并且热图代码来自how to convert a grayscale image to heatmap image with Python OpenCV