我想了解LAB如何在OpenCV中工作。以前在HSV打开帖子我在转换到LAB后正在玩数据类型并进行测试
LAB标准范围内的像素数据在亮度= 0-100,a * = -127到+127,b * = -127到+127。但我对openCV中显示的数据感到困惑。任何人都可以帮我检查我是否正在进行数据类型转换和缩放正确吗?
import cv2
import numpy as np
im = cv2.imread(r'G:\Checkerboardfordummies.png')
cv2.namedWindow('im', cv2.WINDOW_NORMAL)
cv2.imshow('im', im)
print(im)
print(im.dtype)
#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
print(im)
print(im.dtype)
#Colour Space Conversion to LAB
im = cv2.cvtColor(im, cv2.COLOR_BGR2LAB)
cv2.namedWindow('Float32_Checkerboard', cv2.WINDOW_NORMAL)
cv2.imshow('Float32_Checkerboard', im)
cv2.imwrite('Float32_Checkerboard.png',im)
#Conversion from float32 to uint8
im = im*(255.) #Scale value to uint8 range 0-255
im = im.astype(np.uint8) #Cast Image data type
print(im)
print(im.dtype)
cv2.namedWindow('uint8_Checkerboard', cv2.WINDOW_NORMAL)
cv2.imshow('uint8_Checkerboard', im)
cv2.imwrite('uint8_Checkerboard.png',im)
测试图片:
转换测试结果
我不确定哪一种是在LAB中观察到的预期颜色? 8uint还是浮动32?我以为它应该显示相同的颜色?我的缩放可能有问题
这是打印出来的数据供参考:看起来缩小到8uint是错误的看值
>>>
[[[ 0 0 0]
[ 0 0 0]
[ 0 0 0]
...,
[255 255 255]
[255 255 255]
[255 255 255]]
[[ 0 0 0]
[ 0 0 0]
[ 0 0 0]
...,
[255 255 255]
[255 255 255]
[255 255 255]]
[[ 0 0 0]
[ 0 0 0]
[ 0 0 0]
...,
[255 255 255]
[255 255 255]
[255 255 255]]
...,
[[255 255 255]
[255 255 255]
[255 255 255]
...,
[ 0 0 0]
[ 0 0 0]
[ 0 0 0]]
[[255 255 255]
[255 255 255]
[255 255 255]
...,
[ 0 0 0]
[ 0 0 0]
[ 0 0 0]]
[[255 255 255]
[255 255 255]
[255 255 255]
...,
[ 0 0 0]
[ 0 0 0]
[ 0 0 0]]]
uint8
[[[ 0. 0. 0.]
[ 0. 0. 0.]
[ 0. 0. 0.]
...,
[ 1. 1. 1.]
[ 1. 1. 1.]
[ 1. 1. 1.]]
[[ 0. 0. 0.]
[ 0. 0. 0.]
[ 0. 0. 0.]
...,
[ 1. 1. 1.]
[ 1. 1. 1.]
[ 1. 1. 1.]]
[[ 0. 0. 0.]
[ 0. 0. 0.]
[ 0. 0. 0.]
...,
[ 1. 1. 1.]
[ 1. 1. 1.]
[ 1. 1. 1.]]
...,
[[ 1. 1. 1.]
[ 1. 1. 1.]
[ 1. 1. 1.]
...,
[ 0. 0. 0.]
[ 0. 0. 0.]
[ 0. 0. 0.]]
[[ 1. 1. 1.]
[ 1. 1. 1.]
[ 1. 1. 1.]
...,
[ 0. 0. 0.]
[ 0. 0. 0.]
[ 0. 0. 0.]]
[[ 1. 1. 1.]
[ 1. 1. 1.]
[ 1. 1. 1.]
...,
[ 0. 0. 0.]
[ 0. 0. 0.]
[ 0. 0. 0.]]]
float32
[[[ 0 0 0]
[ 0 0 0]
[ 0 0 0]
...,
[156 0 0]
[156 0 0]
[156 0 0]]
[[ 0 0 0]
[ 0 0 0]
[ 0 0 0]
...,
[156 0 0]
[156 0 0]
[156 0 0]]
[[ 0 0 0]
[ 0 0 0]
[ 0 0 0]
...,
[156 0 0]
[156 0 0]
[156 0 0]]
...,
[[156 0 0]
[156 0 0]
[156 0 0]
...,
[ 0 0 0]
[ 0 0 0]
[ 0 0 0]]
[[156 0 0]
[156 0 0]
[156 0 0]
...,
[ 0 0 0]
[ 0 0 0]
[ 0 0 0]]
[[156 0 0]
[156 0 0]
[156 0 0]
...,
[ 0 0 0]
[ 0 0 0]
[ 0 0 0]]]
uint8
>>>
编辑:与Danmasek讨论后......设法在8位和32位正确显示图像
import cv2
import numpy as np
im = cv2.imread(r'G:\Checkerboardfordummies.png')
cv2.namedWindow('im', cv2.WINDOW_NORMAL)
cv2.imshow('im', im)
print(im)
print(im.dtype)
#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
print(im)
print(im.dtype)
#Colour Space Conversion to HSV
im = cv2.cvtColor(im, cv2.COLOR_BGR2LAB)
cv2.namedWindow('Float32_Checkerboard', cv2.WINDOW_NORMAL)
cv2.imshow('Float32_Checkerboard', im)
cv2.imwrite('Float32_Checkerboard.png',im)
#Conversion from float32 to uint8
im[:,:,0] = im[:,:,0]*(255./100)#Scale value to uint8 range 0-255
im[:,:,1] = (im[:,:,1] + 128)/255
im[:,:,2] = (im[:,:,2] + 128)/255
im = im.astype(np.uint8) #Cast Image data type
print(im)
print(im.dtype)
cv2.namedWindow('uint8_Checkerboard', cv2.WINDOW_NORMAL)
cv2.imshow('uint8_Checkerboard', im)
cv2.imwrite('uint8_Checkerboard.png',im)
cv2.imwrite('uint8_Checkerboard.png',im)
得到了这个结果:
打印数据:从32位转换为8位....在缩放后,它仍然在L通道上打印255。非常奇怪
>>>
[[[ 0 0 0]
[ 0 0 0]
[ 0 0 0]
...,
[255 255 255]
[255 255 255]
[255 255 255]]
[[ 0 0 0]
[ 0 0 0]
[ 0 0 0]
...,
[255 255 255]
[255 255 255]
[255 255 255]]
[[ 0 0 0]
[ 0 0 0]
[ 0 0 0]
...,
[255 255 255]
[255 255 255]
[255 255 255]]
...,
[[255 255 255]
[255 255 255]
[255 255 255]
...,
[ 0 0 0]
[ 0 0 0]
[ 0 0 0]]
[[255 255 255]
[255 255 255]
[255 255 255]
...,
[ 0 0 0]
[ 0 0 0]
[ 0 0 0]]
[[255 255 255]
[255 255 255]
[255 255 255]
...,
[ 0 0 0]
[ 0 0 0]
[ 0 0 0]]]
uint8
[[[ 0. 0. 0.]
[ 0. 0. 0.]
[ 0. 0. 0.]
...,
[ 1. 1. 1.]
[ 1. 1. 1.]
[ 1. 1. 1.]]
[[ 0. 0. 0.]
[ 0. 0. 0.]
[ 0. 0. 0.]
...,
[ 1. 1. 1.]
[ 1. 1. 1.]
[ 1. 1. 1.]]
[[ 0. 0. 0.]
[ 0. 0. 0.]
[ 0. 0. 0.]
...,
[ 1. 1. 1.]
[ 1. 1. 1.]
[ 1. 1. 1.]]
...,
[[ 1. 1. 1.]
[ 1. 1. 1.]
[ 1. 1. 1.]
...,
[ 0. 0. 0.]
[ 0. 0. 0.]
[ 0. 0. 0.]]
[[ 1. 1. 1.]
[ 1. 1. 1.]
[ 1. 1. 1.]
...,
[ 0. 0. 0.]
[ 0. 0. 0.]
[ 0. 0. 0.]]
[[ 1. 1. 1.]
[ 1. 1. 1.]
[ 1. 1. 1.]
...,
[ 0. 0. 0.]
[ 0. 0. 0.]
[ 0. 0. 0.]]]
float32
[[[ 0 0 0]
[ 0 0 0]
[ 0 0 0]
...,
[255 0 0]
[255 0 0]
[255 0 0]]
[[ 0 0 0]
[ 0 0 0]
[ 0 0 0]
...,
[255 0 0]
[255 0 0]
[255 0 0]]
[[ 0 0 0]
[ 0 0 0]
[ 0 0 0]
...,
[255 0 0]
[255 0 0]
[255 0 0]]
...,
[[255 0 0]
[255 0 0]
[255 0 0]
...,
[ 0 0 0]
[ 0 0 0]
[ 0 0 0]]
[[255 0 0]
[255 0 0]
[255 0 0]
...,
[ 0 0 0]
[ 0 0 0]
[ 0 0 0]]
[[255 0 0]
[255 0 0]
[255 0 0]
...,
[ 0 0 0]
[ 0 0 0]
[ 0 0 0]]]
uint8
>>>
答案 0 :(得分:2)
你只有2种不同的颜色,所以让我们简化它,只使用2像素的图像,并消除成千上万的冗余像素,只会使行为更难以观察。
因此,我们可以简化这个在线人员的整个过程:
cv2.cvtColor(np.array([[[0,0,0],[1,1,1]]], dtype=np.float32), cv2.COLOR_BGR2LAB)
返回
array([[[ 0., 0., 0.],
[ 100., 0., 0.]]], dtype=float32)
好吧,看看第二个像素。
此时,让我们咨询the documentation进行这种颜色转换。
输出0≤L≤100,-127≤a≤127,-127≤b≤127。然后将值转换为目标数据类型:
- 8位图像:L←L * 255/100,a←a + 128,b←b + 128
- 16位图像:(目前不支持)
- 32位图像:L,a和b按原样保留
我们有一个32位图像,因此值“保持原样”(即在0≤L≤100, −127≤a≤127, −127≤b≤127
范围内)
因此,将结果乘以255并将其转换为8位无符号整数将导致由于溢出而产生无意义。
但是我应该如何缩放并在LAB颜色空间中从float32转换回8bits而不会出现溢出。
应用一些基本数学(引用文献暗示):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 L
float_img[:,:,0] = float_img[:,:,0] * (255.0/100.0)
# Channels a and b
float_img[:,:,1:] = float_img[:,:,1:] + 128
result = np.uint8(float_img)
result
正在
array([[[ 0, 128, 128],
[255, 128, 128]]], dtype=uint8)
进行比较:
>>> 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)