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



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

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,有文档描述这个吗?

从文档来看,OpenCV根据数组的类型改变其行为:

  • 如果图像为8位无符号,则显示如下:
  • 如果图像是16位无符号或32位整数,则像素除以256。即将取值范围[0,255*256]映射到[0,255]。
  • 如果图像是32位浮点数,像素值乘以255。即将取值范围[0,1]映射到[0,255]。

因此,以下操作都将生成相同的灰度图像:

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

float32:

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

uint8是一个无符号8位整数,可以表示0 ~ 255。另一方面,int通常是一个32位带符号整数。当您使用dtype=int创建数组时,该数组中的每个元素占用4个字节。OpenCV显然期望数组由8位元组组成,表示红色,绿色和蓝色。因此,当你传递一个整数数组时,内存将包含这样的内容:

0x00000080 0x00000080 0x00000080.......

openCV将其解释为:

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

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

当你改变类型为uint8,你的数组看起来像这样:

0x80 0x80 0x80 0x80 0x80 0x80 0x80....

然后由OpenCV解释为灰色RGB值:

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

因为OpenCV读取图像的默认dtype是'uint8'所以在该图像上操作的所有内容都必须是'uint8'类型以兼容

如果你想要一个灰色的图像作为输出,那么必须尝试下面的代码来获得预期的结果。想得美

import cv2 as cv 
import numpy as np
img = cv.imread('C:/Users/Admin/Downloads/Opencv/tiger.png')
#cv.imshow('tiger', img)  #this code will shows you a normal image
#cv.waitKey(0)  
#cv.destroyAllWindows()
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY) 
cv.imshow('Gray', gray)
#this above code will shows you a gray colour image
cv.waitKey(0)
cv.destroyAllWindows()

如果您想了解更多信息,请阅读颜色转换文档- https://docs.opencv.org/3.4/d8/d01/group__imgproc__color__conversions.html

相关内容

  • 没有找到相关文章

最新更新