简体   繁体   English

为什么 Opencv python 包装器中的数据类型必须是“uint8”?

[英]why datatype has to be 'uint8' in Opencv python wrapper?

I'd like to create an image of gray color using the following code:我想使用以下代码创建灰色图像:

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()

but I get a totally black image.但我得到一个完全黑色的图像。 When I write the image to a file, it indeed is a gray image:当我将图像写入文件时,它确实是一个灰色图像:

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

So I have to change int to uint8 , then everything works well.所以我必须将int更改为uint8 ,然后一切正常。 But I'm still curious that why I have to use uint8 instead of int , is there any docs describing this?但我仍然很好奇为什么我必须使用uint8而不是int ,有没有描述这个的文档?

From the documentation , OpenCV changes its behavior according to the type of the array: 文档中 ,OpenCV根据数组的类型更改其行为:

  • If the image is 8-bit unsigned, it is displayed as is. 如果图像是8位无符号的,则按原样显示。
  • If the image is 16-bit unsigned or 32-bit integer, the pixels are divided by 256. That is, the value range [0,255*256] is mapped to [0,255]. 如果图像是16位无符号或32位整数,则将像素除以256。即,值范围[0,255 * 256]映射到[0,255]。
  • If the image is 32-bit floating-point, the pixel values are multiplied by 255. That is, the value range [0,1] is mapped to [0,255]. 如果图像是32位浮点,则将像素值乘以255。即,值范围[0,1]映射到[0,255]。

Hence, the following will all produce the same image grayscale image: 因此,以下各项将产生相同的图像灰度图像:

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

int32 : int32

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

float32 : float32

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

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

uint8 is an unsigned 8-bit integer that can represent values 0..255. uint8是一个无符号的8位整数,可以表示值0..255。 int on the other hand is usually a 32-bit signed integer. 另一方面, int通常是32位有符号整数。 When you create array using dtype=int, each element in that aray takes 4 bytes. 使用dtype = int创建数组时,该数组中的每个元素占用4个字节。 OpenCV apparently expect array to be made of 8-bit tuples representing red, green and blue. OpenCV显然希望数组由代表红色,绿色和蓝色的8位元组组成。 So when you pass array of integers, the memory will contain something like this: 因此,当您传递整数数组时,内存将包含以下内容:

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

Which openCV interprets as: openCV解释为:

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

My guess is what you've got very dark image which, on closer inspection would show very dim red, green and blue pixels. 我的猜测是您得到的图像非常暗,如果仔细检查,它会显示非常暗的红色,绿色和蓝色像素。

When you changed type to uint8, your array would look like this: 当您将类型更改为uint8时,您的数组将如下所示:

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

Which is then interpreted by OpenCV as gray RGB values: 然后,OpenCV会将其解释为灰色RGB值:

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

If you want a gray image as output then must try this below code to to get an expecting result.如果您想要一个灰色图像作为输出,那么必须尝试下面的代码以获得预期的结果。 Well nice try.很好的尝试。

 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()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM