10
rgbImage = grayImage / max(max(grayImage));

or

rgbImage = grayImage / 255;

Which of the above is right,and reason?

Amro
  • 121,265
  • 25
  • 232
  • 431
user198729
  • 55,886
  • 102
  • 239
  • 342

2 Answers2

23

To convert a grayscale image to an RGB image, there are two issues you have to address:

  • Grayscale images are 2-D, while RGB images are 3-D, so you have to replicate the grayscale image data three times and concatenate the three copies along a third dimension.
  • Image data can be stored in many different data types, so you have to convert them accordingly. When stored as a double data type, the image pixel values should be floating point numbers in the range of 0 to 1. When stored as a uint8 data type, the image pixel values should be integers in the range of 0 to 255. You can check the data type of an image matrix using the function class.

Here are 3 typical conditions you might encounter:

  • To convert a uint8 or double grayscale image to an RGB image of the same data type, you can use the functions repmat or cat:

    rgbImage = repmat(grayImage,[1 1 3]);
    rgbImage = cat(3,grayImage,grayImage,grayImage);
    
  • To convert a uint8 grayscale image to a double RGB image, you should convert to double first, then scale by 255:

    rgbImage = repmat(double(grayImage)./255,[1 1 3]);
    
  • To convert a double grayscale image to a uint8 RGB image, you should scale by 255 first, then convert to uint8:

    rgbImage = repmat(uint8(255.*grayImage),[1 1 3]);
    
gnovice
  • 123,396
  • 14
  • 248
  • 352
  • I just made a test,seems `double(grayImage)` is the same as `grayImage`?And are `./` and `.*` divide and product operators in MATLAB? Seems `./` is the same as `/` ? – user198729 Apr 12 '10 at 13:11
  • @user198729: The operators `./` and `.*` denote *element-wise* division and multiplication, so that each element of the image matrix is divided by or multiplied by 255. You can check the class (i.e. data type) of a matrix by typing `class(grayImage)`. While `double(grayImage)` and `grayImage` might *appear* to be the same, they may each be a different class (such that they store their values in different ways). – gnovice Apr 12 '10 at 13:17
  • I tried various operations,but `/` and `./` never give a different result...And because `double(grayImage)` is the same as `grayImage`,`double(grayImage)./255` is also the same as `grayImage./255`.So,can you give two examples demonstrating why `./` and `double` are necessary? – user198729 Apr 12 '10 at 13:25
  • @user198729: First, the command `A/B` will give the same results as `A./B` if `B` is a single scalar value. Writing `./` just makes it explicitly clear to whoever is reading the code that element-wise division is occurring. Second, I think it was clear in my answer that the use of `double` is only necessary when you want to convert from *another data type* to `double`. If `grayImage` is already of type `double`, no conversion is necessary. – gnovice Apr 12 '10 at 13:33
  • Oh,seems I misunderstood `double` with `float point` alike data type in c/c++,thanks for the answer! – user198729 Apr 12 '10 at 13:38
2

By definition, an RGB image has 3 channels, which implies you need a three-dimensional matrix to represent the image. So, the right answer is:

rgbImage = repmat(255*grayImage/max(grayImage(:)),[1 1 3]);

Be careful when normalizing grayImage. If grayImage is uint8 then you will lose some precision in the 255*grayImage/max(grayImage(:)) operation.

Also, normalizing grayImage depends on the data. In your question, you used two methods:

rgbImage = grayImage / max(max(grayImage));

which normalizes the grayscale image such that the maximum value in the image is 1 and

rgbImage = grayImage / 255;

which only makes sense if the values in grayImage lie in the 0-255 range.

So it really depends on what you want to do. But, if you want an RGB image you need to convert your single-channel matrix to a 3-channel matrix.

Jacob
  • 33,032
  • 14
  • 105
  • 160