Python 3.x 在这种情况下,cv2.addWeighted和numpy平均值之间的差异是什么?
假设我有两个OpenCV(python包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在视觉上是不同的。为什么会这样?回答我自己的问题,帮助其他对此感
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
):。对不起,我忘了提那件事。啊,我弄错了!国际空间站