2017-09-05 1 views
2

je convertir une image RVB en utilisant HSV représentation par cv2.cvtColor. Mais lors de la conversion de l'image résultante np.float32 DTYPE à np.uint16 et np.uint8 par redimensionnant puis coulée, les images obtenues lors de l'utilisation cv2.imshow look différent pour les versions entières. Ainsi, je me demande maintenant si j'ai fait la conversion correctement ou si ceci est réellement provoqué par certaines informations étant perdues pendant la conversion? J'essaie de comprendre ce qui se passe mais je n'arrive pas à comprendre pourquoi.Numpy 8/16/32 bits de l'image type de données après conversion cvtColor() pour HSV colorspace

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) 

Exemples d'images: enter image description here

Résultat pour chaque conversion: enter image description here

données pour chaque impression:

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

Répondre

1

La différence ne vient pas à cause d'une diminution de la précision quand convertir en entiers. En fait, le problème est que vous attendez que le HSV fonctionne de manière équivalente à la représentation RGB. Mais alors que tous les composants d'un triplet RVB sont compris entre 0 et 1 lorsqu'ils sont représentés sous la forme d'un float32, cela ne vaut plus pour les triplets HSV. Pour HSV, les deuxième et troisième composants (à savoir S et V) sont toujours compris entre 0 et 1, mais le premier composant, H (ue), est un angle compris entre 0 et 360 (voir documentation of cv2.cvtColor).

Cela pose un problème pour les deux, votre conversion ainsi que cv2.imshow() qui attend trois composants entre 0 et 1 ainsi. Bien que votre conversion entraîne un débordement lorsque vous transtypez le dtype en np.uint8 après avoir multiplié toutes les valeurs par 65535. Après avoir lu le documentation of cv2.imshow, on peut s'attendre au même résultat pour la conversion interne lors de l'appel cv2.imshow mais comme imshow interprète le tableau transmis comme une image RVB ne réduit simplement toutes les valeurs qui sont plus grandes que 1 à 1.

Si vous faites manuellement la même avant votre conversion, vous obtiendrez la même image trois fois:

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) 

Cela donnera la même image np.float32, np.uint16 et np.uint8:

enter image description here

(Funnily, cv2.imwrite ne semble pas faire la même conversion, que l'on obtient un autre résultat pour la version np.float32.)

+0

Merci pour l'explication bien détaillée et propre! Apprécierais. Juste pour confirmer, im [:,:, 0] = np.where (im [:,:, 0]> 1.0, 1.0, im [:,:, 0]) >>>>> Cette ligne est d'empêcher le débordement et clip entre 0 à 1 droite? Parlant de cv2.imwrite, selon la documentation, je ne pense pas que cv2.imwrite peut enregistrer des images np.float32? Il semble que l'on doive l'adapter manuellement aux images 16uint ou 8uint avant que cv2.imwrite puisse fonctionner. – SacreD

+0

Oui, c'est pour l'écrêtage. – jotasi

+0

Salut, est-ce que ça fonctionne de la même façon dans LABourspace? J'ai ouvert un nouveau poste ici. Je pensais que vous pourriez faire la lumière sur ce sujet https://stackoverflow.com/questions/46264010/numpy-8-and-32-bits-image-data-type-after-cvtcolor-conversion-to-lab-colorspac – SacreD