我想使用以下代码创建一个灰色颜色的图像:
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