问题描述
我正在使用 cv2.cvtColor
将图像从RGB转换为HSV表示。但是当将 np.float32
dtype的结果图像转换为 np.uint16
和 np时。 uint8
通过重新缩放然后转换,使用 cv2.imshow
时生成的图像对于整数版本看起来不同。因此,我现在想知道我是否正确地完成了转换,或者这是否实际上是由于某些信息在转换过程中丢失了?我试图了解发生了什么,但无法弄清楚原因。
I'm converting an image from RGB to HSV representation by using cv2.cvtColor
. But when converting the resulting image of np.float32
dtype to np.uint16
and np.uint8
by rescaling and then casting, the resulting images when using cv2.imshow
look different for the integer versions. Thus, I am now wondering if I have done the conversion correctly or if this is actually caused by some information being lost during the conversion? I am trying to understand what's going on but couldn't figure out why.
import cv2
import numpy as np
im = cv2.imread(r'C:\Users\310293649\Desktop\photo.png')
print(im.dtype)
print(im)
cv2.namedWindow('im', cv2.WINDOW_NORMAL)
cv2.imshow('im',im)
#Conversion from 8uint to float32 before cvtColor()
im = im.astype(np.float32) #Cast Image data type
im *= 1./255 #Scale value to float32 range 0-1
print(im.dtype) #Print to check data type
print(im) #Print pixel value
#Colour Space Conversion to HSV
im = cv2.cvtColor(im, cv2.COLOR_BGR2HSV)
cv2.namedWindow('im1', cv2.WINDOW_NORMAL)
cv2.imshow('im1',im)
#Conversion from float32 to uint16
im *= 65535 #Scale value to uint16 range 0-65535
print(im) #Check Value
im = im.astype(np.uint16) #Cast Image data type
print(im.dtype)
cv2.namedWindow('im2', cv2.WINDOW_NORMAL)
cv2.imshow('im2', im)
#Conversion from uint16 to uint8
im = im*(255./65535) #Scale value to uint8 range 0-255
print(im) #Check Value
im = im.astype(np.uint8) #Cast Image data type
print(im.dtype)
cv2.namedWindow('im3', cv2.WINDOW_NORMAL)
cv2.imshow('im3', im)
示例图像:
Sample Images:
每次转换的结果:
Result for each conversion:
每张印刷品的数据:
>>>
========== RESTART: C:\Users\310293649\Desktop\DatatypeLearning.py ==========
uint8
[[[ 6 4 4]
[15 13 13]
[13 11 11]
...,
[43 45 45]
[43 45 45]
[34 36 36]]
[[ 9 7 7]
[22 20 20]
[19 17 17]
...,
[49 51 51]
[47 49 49]
[36 38 38]]
[[24 22 22]
[28 26 26]
[23 21 21]
...,
[45 47 47]
[41 43 43]
[28 30 30]]
...,
[[11 12 16]
[ 6 7 11]
[ 1 2 6]
...,
[ 7 7 7]
[ 7 7 7]
[ 7 7 7]]
[[10 11 15]
[ 6 7 11]
[ 2 3 7]
...,
[ 7 7 7]
[ 7 7 7]
[ 7 7 7]]
[[ 8 9 13]
[ 6 7 11]
[ 4 5 9]
...,
[ 7 7 7]
[ 7 7 7]
[ 7 7 7]]]
float32
[[[ 0.02352941 0.01568628 0.01568628]
[ 0.05882353 0.0509804 0.0509804 ]
[ 0.0509804 0.04313726 0.04313726]
...,
[ 0.16862746 0.17647059 0.17647059]
[ 0.16862746 0.17647059 0.17647059]
[ 0.13333334 0.14117648 0.14117648]]
[[ 0.03529412 0.02745098 0.02745098]
[ 0.08627451 0.07843138 0.07843138]
[ 0.07450981 0.06666667 0.06666667]
...,
[ 0.19215688 0.20000002 0.20000002]
[ 0.18431373 0.19215688 0.19215688]
[ 0.14117648 0.14901961 0.14901961]]
[[ 0.09411766 0.08627451 0.08627451]
[ 0.10980393 0.10196079 0.10196079]
[ 0.09019608 0.08235294 0.08235294]
...,
[ 0.17647059 0.18431373 0.18431373]
[ 0.16078432 0.16862746 0.16862746]
[ 0.10980393 0.11764707 0.11764707]]
...,
[[ 0.04313726 0.04705883 0.0627451 ]
[ 0.02352941 0.02745098 0.04313726]
[ 0.00392157 0.00784314 0.02352941]
...,
[ 0.02745098 0.02745098 0.02745098]
[ 0.02745098 0.02745098 0.02745098]
[ 0.02745098 0.02745098 0.02745098]]
[[ 0.03921569 0.04313726 0.05882353]
[ 0.02352941 0.02745098 0.04313726]
[ 0.00784314 0.01176471 0.02745098]
...,
[ 0.02745098 0.02745098 0.02745098]
[ 0.02745098 0.02745098 0.02745098]
[ 0.02745098 0.02745098 0.02745098]]
[[ 0.03137255 0.03529412 0.0509804 ]
[ 0.02352941 0.02745098 0.04313726]
[ 0.01568628 0.01960784 0.03529412]
...,
[ 0.02745098 0.02745098 0.02745098]
[ 0.02745098 0.02745098 0.02745098]
[ 0.02745098 0.02745098 0.02745098]]]
[[[ 1.57284000e+07 2.18448906e+04 1.54200012e+03]
[ 1.57284000e+07 8.73798047e+03 3.85500024e+03]
[ 1.57284000e+07 1.00822871e+04 3.34100024e+03]
...,
[ 3.93204025e+06 2.91266455e+03 1.15650000e+04]
[ 3.93204025e+06 2.91266455e+03 1.15650000e+04]
[ 3.93204025e+06 3.64082983e+03 9.25200000e+03]]
[[ 1.57284000e+07 1.45632822e+04 2.31300000e+03]
[ 1.57284000e+07 5.95771875e+03 5.65400000e+03]
[ 1.57284000e+07 6.89840918e+03 4.88300000e+03]
...,
[ 3.93204025e+06 2.56999805e+03 1.31070010e+04]
[ 3.93204025e+06 2.67490112e+03 1.25930010e+04]
[ 3.93204025e+06 3.44920728e+03 9.76600000e+03]]
[[ 1.57284000e+07 5.46124707e+03 6.16800049e+03]
[ 1.57284000e+07 4.68106592e+03 7.19600049e+03]
[ 1.57284000e+07 5.69868750e+03 5.91100000e+03]
...,
[ 3.93204025e+06 2.78872144e+03 1.20790000e+04]
[ 3.93204025e+06 3.04813696e+03 1.10510000e+04]
[ 3.93204025e+06 4.36899463e+03 7.71000049e+03]]
...,
[[ 7.86415812e+05 2.04796504e+04 4.11200000e+03]
[ 7.86415250e+05 2.97885508e+04 2.82700000e+03]
[ 7.86415125e+05 5.46122266e+04 1.54200012e+03]
...,
[ 0.00000000e+00 0.00000000e+00 1.79900012e+03]
[ 0.00000000e+00 0.00000000e+00 1.79900012e+03]
[ 0.00000000e+00 0.00000000e+00 1.79900012e+03]]
[[ 7.86415062e+05 2.18449570e+04 3.85500024e+03]
[ 7.86415250e+05 2.97885508e+04 2.82700000e+03]
[ 7.86415250e+05 4.68105117e+04 1.79900012e+03]
...,
[ 0.00000000e+00 0.00000000e+00 1.79900012e+03]
[ 0.00000000e+00 0.00000000e+00 1.79900012e+03]
[ 0.00000000e+00 0.00000000e+00 1.79900012e+03]]
[[ 7.86415062e+05 2.52057109e+04 3.34100024e+03]
[ 7.86415250e+05 2.97885508e+04 2.82700000e+03]
[ 7.86415125e+05 3.64082109e+04 2.31300000e+03]
...,
[ 0.00000000e+00 0.00000000e+00 1.79900012e+03]
[ 0.00000000e+00 0.00000000e+00 1.79900012e+03]
[ 0.00000000e+00 0.00000000e+00 1.79900012e+03]]]
uint16
[[[ 254.07003891 84.99610895 6. ]
[ 254.07003891 33.99610895 15. ]
[ 254.07003891 39.22957198 13. ]
...,
[ 254.53696498 11.3307393 45. ]
[ 254.53696498 11.3307393 45. ]
[ 254.53696498 14.16342412 36. ]]
[[ 254.07003891 56.66536965 9. ]
[ 254.07003891 23.17898833 22. ]
[ 254.07003891 26.84046693 19. ]
...,
[ 254.53696498 9.99610895 51. ]
[ 254.53696498 10.40466926 49. ]
[ 254.53696498 13.42023346 38. ]]
[[ 254.07003891 21.24902724 24. ]
[ 254.07003891 18.21400778 28. ]
[ 254.07003891 22.17120623 23. ]
...,
[ 254.53696498 10.84824903 47. ]
[ 254.53696498 11.85992218 43. ]
[ 254.53696498 16.99610895 30. ]]
...,
[[ 254.93774319 79.6848249 16. ]
[ 254.93774319 115.90661479 11. ]
[ 254.93774319 212.49805447 6. ]
...,
[ 0. 0. 7. ]
[ 0. 0. 7. ]
[ 0. 0. 7. ]]
[[ 254.93774319 84.99610895 15. ]
[ 254.93774319 115.90661479 11. ]
[ 254.93774319 182.14007782 7. ]
...,
[ 0. 0. 7. ]
[ 0. 0. 7. ]
[ 0. 0. 7. ]]
[[ 254.93774319 98.07392996 13. ]
[ 254.93774319 115.90661479 11. ]
[ 254.93774319 141.66536965 9. ]
...,
[ 0. 0. 7. ]
[ 0. 0. 7. ]
[ 0. 0. 7. ]]]
uint8
推荐答案
不同产生的原因不是因为转换为整数时精度下降。实际上,问题是您希望能够与表示。但是,当表示为float32时,RGB三元组中的所有组件都介于0和1之间,这对于HSV三元组不再适用。对于HSV,第二和第三分量(即S和V)仍然在0和1之间,但第一个分量H(ue)是0到360之间的角度(参见的文档。
The difference arises not because of a decrease of accuracy when converting to integers. Actually, the problem is that you expect the HSV to work equivalently to the RGB representation. But whereas all components in an RGB triple are between 0 and 1 when represented as a float32, this no longer holds true for HSV triples. For HSV the second and third component (namely S and V) are still between 0 and 1 but the first component, H(ue), is an angle between 0 and 360 (see the documentation of cv2.cvtColor
).
这对你的转换以及 cv2.imshow()
都有问题,它要求0和0之间有三个组件。 1也是。在将所有值与65535相乘后,将dtype转换为 np.uint8
时,转换会导致溢出。阅读人们可能会期待调用 cv2.imshow
时内部转换的结果相同,但是 imshow
将传递的数组解释为RGB图像确实只是减少了大于1比1的所有值。
This is problematic for both, your conversion as well as cv2.imshow()
which expects three components between 0 and 1 as well. While your conversion results in an overflow when you cast the dtype to np.uint8
after multiplying all values with 65535. After reading the documentation of cv2.imshow
one might expect the same result for the internal conversion when calling cv2.imshow
but as imshow
interprets the passed array as an RGB image it does simply reduce all values that are bigger than 1 to 1.
如果您在转换前手动执行相同的操作,您将获得三次相同的图像:
If you manually do the same before your conversion, you will get the same image three times:
import cv2
import numpy as np
im = cv2.imread(r'C:\Users\310293649\Desktop\photo.png')
cv2.namedWindow('im', cv2.WINDOW_NORMAL)
cv2.imshow('im', im)
#Conversion from 8uint to float32 before cvtColor()
im = im.astype(np.float32) #Cast Image data type
im /= 255. #Scale value to float32 range 0-1
#Colour Space Conversion to HSV
im = cv2.cvtColor(im, cv2.COLOR_BGR2HSV)
cv2.namedWindow('im1', cv2.WINDOW_NORMAL)
cv2.imshow('im1', im)
im[:, :, 0] = np.where(im[:, :, 0]>1.0, 1.0, im[:, :, 0])
im *= 65535 #Scale value to uint16 range 0-65535
im = im.astype(np.uint16) #Cast Image data type
cv2.namedWindow('im2', cv2.WINDOW_NORMAL)
cv2.imshow('im2', im)
#Conversion from uint16 to uint8
im = im*(255./65535) #Scale value to uint8 range 0-255
im = im.astype(np.uint8) #Cast Image data type
cv2.namedWindow('im3', cv2.WINDOW_NORMAL)
cv2.imshow('im3', im)
这将为 np.float32
, np.uint16
和 np提供相同的图像.uint8
:
(有趣的是, cv2.imwrite
似乎没有做同样的转换,因为得到了不同的结果对于 np.float32
版本。)
(Funnily, cv2.imwrite
does not seem to do the same conversion, as one gets a different result for the np.float32
version.)
这篇关于cvtColor()转换为HSV颜色空间后的Numpy 8/16/32位图像数据类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!