Numpy 8 And 32 Bits Image Data Type After Cvtcolor() Conversion To Lab Colorspace
Solution 1:
You only have 2 distinct colours, so let's simplify it and only use an image with 2 pixels, and eliminate the tens of thousands of redundant pixels that only make the behaviour more difficult to observe.
As such, we can simplify the whole thing to this onliner:
cv2.cvtColor(np.array([[[0,0,0],[1,1,1]]], dtype=np.float32), cv2.COLOR_BGR2LAB)
which returns
array([[[ 0., 0., 0.],
[ 100., 0., 0.]]], dtype=float32)
Well, look at the second pixel.
At this point, let's consult the documentation for this kind of colour conversion.
This outputs 0≤L≤100, −127≤a≤127, −127≤b≤127 . The values are then converted to the destination data type:
- 8-bit images: L←L∗255/100,a←a+128,b←b+128
- 16-bit images: (currently not supported)
- 32-bit images: L, a, and b are left as is
We've got a 32 bit image, so the values are "left as is" (i.e in the ranges 0≤L≤100, −127≤a≤127, −127≤b≤127
)
Hence, multiplying the result by 255 and casting it to an 8 bit unsigned integer will leave you with nonsense due to overflow.
But how should i scale and convert back from float32 to 8bits in the LAB colorspace without experiencing overflow.
Apply some elementary math (hinted at by the quoted documentation): L←L∗255/100,a←a+128,b←b+128
float_img = cv2.cvtColor(np.array([[[0,0,0],[1,1,1]]], dtype=np.float32), cv2.COLOR_BGR2LAB)
# Channel Lfloat_img[:,:,0] = float_img[:,:,0] * (255.0/100.0)# Channels a and bfloat_img[:,:,1:] = float_img[:,:,1:] + 128
result = np.uint8(float_img)
The result
being
array([[[ 0, 128, 128],
[255, 128, 128]]], dtype=uint8)
For comparison:
>>> cv2.cvtColor(np.array([[[0,0,0],[255,255,255]]], dtype=np.uint8), cv2.COLOR_BGR2LAB)
array([[[ 0, 128, 128],
[255, 128, 128]]], dtype=uint8)
Post a Comment for "Numpy 8 And 32 Bits Image Data Type After Cvtcolor() Conversion To Lab Colorspace"