为什么数据类型必须是';uint8';在Opencv python包装器中?

为什么数据类型必须是';uint8';在Opencv python包装器中?,python,opencv,Python,Opencv,我想使用以下代码创建一个灰色颜色的图像: import numpy as np import cv2 cv=cv2 s=np.zeros((240, 320, 3), dtype=int) s[s==0]=128 cv.imshow('3', s) cv.waitKey() cv.destroyAllWindows() 但是我得到了一个完全的黑色图像。当我将图像写入文件时,它实际上是一个灰色图像: fn='example.jpg' cv.imwrite(fn, s) 因此,我必须将int更

我想使用以下代码创建一个灰色颜色的图像:

import numpy as np
import cv2
cv=cv2

s=np.zeros((240, 320, 3), dtype=int)
s[s==0]=128
cv.imshow('3', s)
cv.waitKey()
cv.destroyAllWindows()
但是我得到了一个完全的黑色图像。当我将图像写入文件时,它实际上是一个灰色图像:

fn='example.jpg'
cv.imwrite(fn, s)

因此,我必须将
int
更改为
uint8
,然后一切正常。但我仍然很好奇,为什么我必须使用
uint8
而不是
int
,是否有文档对此进行了描述?

uint8
是一个无符号的8位整数,可以表示值0..255<另一方面,code>int通常是32位有符号整数。当您使用dtype=int创建数组时,该数组中的每个元素都需要4个字节。OpenCV显然希望数组由代表红色、绿色和蓝色的8位元组组成。因此,当您传递整数数组时,内存将包含如下内容:

0x00000080 0x00000080 0x00000080

openCV将其解释为:

{R=0x00,G=0x00,B=0x00}{R=0x80,G=0x00,B=0x00},{R=0x00,G=0x00,B=0x00}

我猜你们得到的是非常暗的图像,仔细观察会显示非常暗的红色、绿色和蓝色像素

当您将类型更改为uint8时,您的数组将如下所示:

0x80 0x80 0x80 0x80 0x80 0x80 0x80 0x80 0x80

然后OpenCV将其解释为灰色RGB值:

{R=0x80,G=0x80,B=0x80}

从中,OpenCV将根据阵列的类型更改其行为:

  • 如果图像是8位无符号的,它将按原样显示
  • 如果图像是16位无符号或32位整数,则像素除以256。也就是说,值范围[0255*256]被映射到[0255]
  • 如果图像是32位浮点,则像素值将乘以255。也就是说,值范围[0,1]被映射到[0255]
因此,以下内容都将生成相同的图像灰度图像:

s = np.zeros((240, 320), dtype=np.uint8)
s[s==0] = 128
int32

s = np.zeros((240, 320), dtype=np.int32)
s[s==0] = 128 * 256
s = np.zeros((240, 320), dtype=np.float32)
s[s==0] = 128 / 256.0
float32

s = np.zeros((240, 320), dtype=np.int32)
s[s==0] = 128 * 256
s = np.zeros((240, 320), dtype=np.float32)
s[s==0] = 128 / 256.0

因为OpenCV读取图像的默认数据类型是“uint8”,所以在该图像上操作的所有数据类型都必须是“uint8”类型,以确保兼容性

太好了!thx人!现在的问题是:为什么
cv.imshow
cv.imwrite
不一致?@zhangxaochen这取决于OpenCV的作者。API为何以某种方式设计的问题没有明确的答案;我们只能猜测。