cvtColor()转换为HSV颜色空间

时间:2017-09-05 10:08:38

标签: python opencv numpy image-processing colors

我使用cv2.cvtColor将图像从RGB转换为HSV表示。但是,当通过重新缩放然后转换将np.float32 dtype的结果图像转换为np.uint16np.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)

示例图片: enter image description here

每次转化的结果: enter image description here

每张照片的数据:

>>> 
========== 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

1 个答案:

答案 0 :(得分:2)

出现差异不是因为转换为整数时精度下降。实际上,问题在于您希望HSVRGB表示等效。但是,当表示为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.float32np.uint16np.uint8提供相同的图片:

enter image description here

(有趣的是,cv2.imwrite似乎没有进行相同的转换,因为np.float32版本会得到不同的结果。)