在这种情况下,cv2.addWeighted和numpy mean有什么区别?

时间:2019-11-27 04:06:07

标签: python-3.x opencv

假设我有两个OpenCV(Python软件包cv2)已加载灰度图像img1img2,它们的尺寸均相同。现在,我希望同时使用img1img2的均值。这是两种方法:

# Method 1
mean = (img1 * 0.5) + (img2 * 0.5)

# Method 2
mean = cv2.addWeighted(img1,0.5,img2,0.5,0)

但是,当我使用mean显示它们时,cv2.imshow在两种方法上在视觉上都是不同的。为什么会这样?

2 个答案:

答案 0 :(得分:2)

回答我自己的问题,以帮助对此感到困惑的其他人:

方法1和2都产生相同的结果。您可以通过使用meancv2.imwrite映像写入磁盘来验证这一点。问题不在于方法。

问题是用于显示图像的cv2.imshow方法期望图像阵列被规范化,即在[0,1]范围内。在我的情况下,两个图像数组都是8位无符号整数,因此,其像素值在[0,255]范围内。由于mean是两个数组的平均值,因此其像素值也在[0,255]范围内。因此,当我将mean传递给cv2.imshow时,值大于1的像素将被解释为值为255,从而导致视觉效果大不相同。

解决方案是在将mean传递给cv2.imshow之前对其进行规范化:

# Method 1
mean = (img1 * 0.5) + (img2 * 0.5)

# Method 2
mean = cv2.addWeighted(img1,0.5,img2,0.5,0)

# Note that the division by 255 results in the image array values being squeezed to [0,1].

cv2.imshow("Averaged", mean/255.)

答案 1 :(得分:1)

很高兴您找到了解决问题的可行方法,但这似乎是一种解决方法。此行为的真正原因在于其他地方。这里的问题是mean = (img1 * 0.5) + (img2 * 0.5)返回的数据类型为float32的矩阵包含范围为0.0 - 255.0的值。您可以使用print mean.dtype进行验证。由于新的矩阵值已被无意转换为浮点型,因此我们可以使用(img_1 * 0.5 + img_2 * 0.5).astype("uint8")还原此操作。如果使用cv2.addWeighted(),它将自动为您返回数据类型为uint8的矩阵,并且一切正常。

我关心的是您得出的结论:

  

问题是cv2.imshow()方法用于显示图像,   希望您的图像阵列被标准化,即在[0,1]范围内。

cv2.imshow()可以在[0-255][0.0-1.0]的范围内正常工作,但是当您传递值在[0-255]范围内的矩阵时会出现问题,但是dtype为float32而不是uint8