我使用cv2.cvtColor
将图像从RGB转换为HSV表示。但是,当通过重新缩放然后转换将np.float32
dtype的结果图像转换为np.uint16
和np.uint8
时,使用cv2.imshow
时生成的图像对于整数版本看起来会有所不同。因此,我现在想知道我是否已正确完成转换,或者这是否实际上是由于某些信息在转换过程中丢失了?我试图了解发生了什么,但无法弄清楚原因。
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)
每张照片的数据:
>>>
========== 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
答案 0 :(得分:2)
出现差异不是因为转换为整数时精度下降。实际上,问题在于您希望HSV与RGB表示等效。但是,当表示为float32时,RGB三元组中的所有组件都介于0和1之间,这对于HSV三元组不再适用。对于HSV,第二和第三个分量(即S和V)仍在0和1之间,但第一个分量H(ue)是0到360之间的角度(见documentation of cv2.cvtColor
)。
这对您的转换和cv2.imshow()
都有问题,它们期望三个组件在0和1之间。在将所有值与65535相乘后,将dtype转换为np.uint8
时转换会导致溢出。在阅读documentation of cv2.imshow
之后,调用cv2.imshow
时内部转换可能会产生相同的结果但是当imshow
将传递的数组解释为RGB图像时,它只会减少大于1到1的所有值。
如果您在转换前手动执行相同操作,则会三次获得相同的图像:
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
版本会得到不同的结果。)