将OpenCV BGR 8位图像转换为CIE L * a * b *

时间:2012-07-08 20:44:34

标签: c++ opencv colors rgb bgr

我正在尝试使用文档中提供的功能将表示具有8位深度的 RGB 图像的给定Mat转换为 Lab

cvtColor(source, destination, <conversion code>);

我尝试过以下转换代码:

CV_RGB2Lab
CV_BGR2Lab
CV_LBGR2Lab

我每次都收到奇怪的结果,某些样本的“L”值大于100,字面上<107,125,130>。

我也使用Photoshop检查结果 - 但鉴于107超出0≤L≤100的可接受范围,我无法理解我的错误。

更新 我会在这里发布我的整体结果: 给定由8位BGR表示的图像(Mat),可以通过以下方式转换图像:

cvtColor(source, destination, CV_BGR2Lab);

然后可以通过以下方式访问像素值:

int step = destination.step;
int channels = destination.channels();
for (int i = 0; i < destination.rows(); i++) {
    for (int j = 0; j < destination.cols(); j++) {
        Point3_<uchar> pixelData;
        //L*: 0-255 (elsewhere is represented by 0 to 100)
        pixelData.x = destination.data[step*i + channels*j + 0];
        //a*: 0-255 (elsewhere is represented by -127 to 127)
        pixelData.y = destination.data[step*i + channels*j + 1];
        //b*: 0-255 (elsewhere is represented by -127 to 127)
        pixelData.z = destination.data[step*i + channels*j + 2];
    }
}

4 个答案:

答案 0 :(得分:9)

如果有人对其他变量ab的范围感兴趣,我制作了一个小程序来测试它们的范围。 如果将使用RGB表示的所有颜色转换为OpenCV中使用的CieLab,则范围为:

0  <=L<= 255
42 <=a<= 226
20 <=b<= 223

如果您在浮动模式而不是uint8中使用RGB值,则范围将为:

0.0      <=L<= 100.0
-86.1813 <=a<= 98.2352
-107.862 <=b<= 94.4758

P.S。如果你想看到与另一个LAB值有明显区别(关于人类感知)的LAB值,你应该使用浮点数。用于将实验室值保持在uint8范围内的比例与其欧氏距离相混淆。

这是我使用的代码(python):

L=[0]*256**3
a=[0]*256**3
b=[0]*256**3
i=0
for r in xrange(256):
    for g in xrange(256):
        for bb in xrange(256):
            im = np.array((bb,g,r),np.uint8).reshape(1,1,3)
            cv2.cvtColor(im,cv2.COLOR_BGR2LAB,im) #tranform it to LAB 
            L[i] = im[0,0,0]
            a[i] = im[0,0,1]
            b[i] = im[0,0,2]
            i+=1

print min(L), '<=L<=', max(L)
print min(a), '<=a<=', max(a)
print min(b), '<=b<=', max(b)

答案 1 :(得分:8)

这是因为 L 值在OpenCV中的范围 [0..255] 。您可以简单地将此值缩放到所需的间隔(在您的情况下为 [0..100] )。

答案 2 :(得分:1)

我不确定JoãoAbrantes在A和B上的范围。

opencv documentation明确提到了CIE L*a*b*范围。

General Range

  • 8位图片

    Range of 8_bit images

因此导致一系列

0 <= L <= 255
0 <= a <= 255
0 <= b <= 255

答案 3 :(得分:0)

如果有人遇到同样的问题:

请注意,在OpenCV(2.4.13)中,您可以将CV_32FC3 BGR图像转换为Lab颜色空间。也就是说:

//this->xImage is CV_8UC3
this->xImage.convertTo(FloatPrecisionImage, CV_32FC3);
Mat result;
cvtColor(FloatPrecisionImage, result, COLOR_BGR2Lab);
this->xImage = result;

工作 而

Mat result;
cvtColor(this->xImage, result, COLOR_BGR2Lab);
result.convertTo(this->xImage, CV_32FC3);

就像一个魅力。 我没有追查上述行为的原因;然而,这对我来说似乎不合适,因为这实际上限制了图像的质量。