Python 3.x 在这种情况下,cv2.addWeighted和numpy平均值之间的差异是什么?

Python 3.x 在这种情况下,cv2.addWeighted和numpy平均值之间的差异是什么?,python-3.x,opencv,Python 3.x,Opencv,假设我有两个OpenCV(python包cv2)加载的灰度图像img1和img2,这两个图像的尺寸都相同。现在,我想取img1和img2的平均值。以下是两种方法: # Method 1 mean = (img1 * 0.5) + (img2 * 0.5) # Method 2 mean = cv2.addWeighted(img1,0.5,img2,0.5,0) 但是,当我使用cv2.imshow显示它们时,这两种方法的mean在视觉上是不同的。为什么会这样?回答我自己的问题,帮助其他对此感

假设我有两个OpenCV(python包
cv2
)加载的灰度图像
img1
img2
,这两个图像的尺寸都相同。现在,我想取
img1
img2
的平均值。以下是两种方法:

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

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

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

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

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

问题在于,用于显示图像的
cv2.imshow
方法要求图像阵列标准化,即在[0,1]范围内。在我的例子中,两个图像数组都是8位无符号整数,因此其像素值在[0255]范围内。由于
mean
是两个阵列的平均值,因此其像素值也在[0255]范围内。因此,当我将
mean
传递给
cv2.imshow
时,值大于1的像素被解释为值为255,从而产生截然不同的视觉效果

解决方案是将
平均值
标准化,然后将其传递给
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和2产生相同的结果。您可以通过使用
cv2.imwrite
mean
图像写入磁盘来验证这一点。问题不在于方法

问题在于,用于显示图像的
cv2.imshow
方法要求图像阵列标准化,即在[0,1]范围内。在我的例子中,两个图像数组都是8位无符号整数,因此其像素值在[0255]范围内。由于
mean
是两个阵列的平均值,因此其像素值也在[0255]范围内。因此,当我将
mean
传递给
cv2.imshow
时,值大于1的像素被解释为值为255,从而产生截然不同的视觉效果

解决方案是将
平均值
标准化,然后将其传递给
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.)

我很高兴你找到了解决问题的有效方法,但这似乎是一个解决办法。这种行为的真正原因在于其他地方。这里的问题是
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]
范围内的矩阵时,问题就会出现,但数据类型是
float32
而不是
uint8
我很高兴您找到了解决问题的有效方法,但这似乎是一个解决办法。这种行为的真正原因在于其他地方。这里的问题是
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]
范围内的矩阵时,会出现问题,但数据类型是
float32
而不是
uint8

您确定img1和img2有可能的范围吗,cv2的完整包装名称是什么?如果我们不知道它是什么,很难找到文档。@topher217:
img1
img2
是8位无符号整数,所以它们在[0255]中
cv2
代表OpenCV的python实现(完整的包名本身就是
cv2
):。对不起,我忘了提那件事。啊,我弄错了!问题在于
cv2.imshow
期望图像在[0,1]范围内。大于1的像素被设置为255。您能在此基础上展开并回答您自己的问题吗?您如何将
平均值
从0->255的平均值转换为cv2.imshow可以接受的0->1的平均值?方法1是否导致值超过255(剪裁),而方法2则不是?是否确定img1和img2的可能范围为0到1?此外,cv2的完整软件包名称是什么?如果我们不知道它是什么,很难找到文档。@topher217:
img1
img2
是8位无符号整数,所以它们在[0255]中
cv2
代表OpenCV的python实现(完整的包名本身就是
cv2
):。对不起,我忘了提那件事。啊,我弄错了!国际空间站