문제

I am using opencv for a certain image processing code. I need to extract the color layers from a certain picture. So what I do is keep the pixels having a certain value and set the remaining pixels to the background color (which is white in this case). For certain issues I have to carry out this entire operation in CIE-L*a*b* color space. The problem arises when I convert the above image to RGB, using cvCvtColor() the background no longer remains white. I have tried with different permutation and combination of values, but it either becomes red or blue or anything but not pure white.

I even made a picture in paint (just white) and converted it to L*a*b* space and printed the values in a text file. Here is the code

IplImage *image, *lab;
uchar *data;
FILE *fp;
int i, j;
image = cvLoadImage( "white.png", CV_LOAD_IMAGE_UNCHANGED);
lab = cvCreateImage(cvSize(image->width,image->height), IPL_DEPTH_8U, 3);
cvCvtColor(image, lab, CV_BGR2Lab);
data = (uchar*)lab->imageData;
fp= fopen("white.txt", "w");
for(i=0; i<lab->height; i++)
         for(j=0; j<lab->width; j++)
                  fprintf(fp, "L = %d, a = %d, b = %d\n", data[i*lab->widthStep + j*lab->nChannels +0], data[i*lab->widthStep + j*lab->nChannels +0], data[i*lab->widthStep + j*lab->nChannels +0]);

It shows all the three values to be 255. But when I set the pixel values in my required program to it, it becomes reddish.

Here is the code snippet to set the pixel value

image = cvLoadImage( "pic11.png", CV_LOAD_IMAGE_UNCHANGED);
cvCvtColor(image, lab, CV_BGR2Lab);

copy = cvCreateImage(cvSize(lab->width,lab->height), IPL_DEPTH_8U, 3);
cvCopy(lab, copy, NULL);
data2 = (uchar*)copy->imageData;    

copied = cvCreateImage(cvSize(copy->width,copy->height), IPL_DEPTH_8U, 3);
data = (uchar*)copied->imageData;

for(i=x; i<copy->height; i++)
          for(j=y; j<copy->width; j++)
          {        
                   if(data2[i*copy->widthStep + j*copy->nChannels + 0] == r &&
                      data2[i*copy->widthStep + j*copy->nChannels + 1] == g &&
                      data2[i*copy->widthStep + j*copy->nChannels + 2] == b)
                   {
                           data[i*copy->widthStep + j*copy->nChannels + 0] = r;
                           data[i*copy->widthStep + j*copy->nChannels + 1] = g;
                           data[i*copy->widthStep + j*copy->nChannels + 2] = b;
                   }
                   else
                   {
                       data[i*copy->widthStep + j*copy->nChannels + 0] = 255;
                       data[i*copy->widthStep + j*copy->nChannels + 1] = 255;
                       data[i*copy->widthStep + j*copy->nChannels + 2] = 255;
                   }
          }

copy_im = cvCreateImage(cvSize(copied->width,copied->height), IPL_DEPTH_8U, 3);
cvCvtColor(copied, copy_im, CV_Lab2BGR);
cvSaveImage("copy.jpg", copy_im);

Any help would be highly appreciated. Thanks in advance !

도움이 되었습니까?

해결책

To sum up the comments roughly:

In L*a*b* The values are normally [0,100] and "a and "b" are signed, with no well defined boundaries. In opencv for 8 bit images the values are converted as follows:

  • L <- L * 255/100
  • a <- a+128
  • b <- b+128

In CIELab, "white" is represented roughly as (100,0,0) which becomes (255,128,128) by that transformation. If you use 32-bit floating point images, then this last conversion is not needed and you can use (100.0,0.0,0.0) as white.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top