Convert an array of numbers into a color mapped image

조회 수: 33 (최근 30일)
Steve Francis
Steve Francis 2023년 1월 18일
편집: DGM 2023년 1월 20일
I have a 2-d array of integers. It has 1024 rows and 1280 columns. The integers are whole numbers in the range 1-12.
I want to define a rgb colour for each of the twelve values (e.g. "1" is equivalent to [1 1 0], "2" is equivalent to [0 1 1] ... "12" is equivalent to [0.2 0.7 0.6]).
I then want to convert the numerical array into a rgb TIF image with 1024x1280 pixels that shows the appropriate colour corresponding to the array value in the pixel position. For example, if the value of the array element at row 1 column 1 is equal to 2, then I would expect to see a cyan [0 1 1] pixel in the top left hand corner of my rgb image.
How can I do this?
  댓글 수: 3
DGM
DGM 2023년 1월 19일
편집: DGM 2023년 1월 20일
The reason this happens has to do with how the CData gets mapped to the current colormap.
Array1 =[0 0 0 0 0 0; 0 1 0 2 0 6; 4 0 5 5 0 9; 0 10 7 0 8 0];
Array2 =[0 0 0 0 0 0; 0 1 0 2 0 3; 4 0 5 5 0 6; 0 7 0 8 9 0];
mymap = [0 0 0; 0.6 1 0.2;1 1 0;0.6 1 0.2; 1 0.6 0.2;1 0 1;0.2 1 0.6;0 1 0;1 0 0;0.2 0.6 1;0 0 1];
subplot(2,1,1)
hi1 = imagesc(Array1);
colormap(mymap)
caxis
ans = 1×2
0 10
subplot(2,1,2)
hi2 = imagesc(Array2);
colormap(mymap)
caxis
ans = 1×2
0 9
When you use imagesc(), you're scaling everything such that the range of values in the image maps to the extent of the color table. When range of your image varies, so does the mapping.
You can either:
Use imagesc() (scaled mapping) and explicitly specify caxis so that the scale stays consistent. There really isn't a good reason to do this for an indexed image, but I guess you could.
hi1 = imagesc(Array1);
colormap(mymap)
caxis([0 length(mymap)-1])
Use image() (direct mapping) and present the image data as expected for its class
%hi1 = image(Array1+1); % either offset by 1
hi1 = image(uint8(Array1)); % or use an integer class
colormap(mymap)
Or you can use imshow() with the syntax for direct mapping. The same convention described for image() holds here as well. Note that this sets the colormap, so using colormap() isn't necessary.
%hi1 = imshow(Array1+1,mymap); % either offset by 1
hi1 = imshow(uint8(Array1),mymap); % or use an integer class
All of this is really moot if your goal is to write the image instead of just displaying it. Use ind2rgb() as Walter shows, and pay attention to the fact that indexing is class-dependent. Write the images with imwrite().
imwrite(B1,'myimage.tif') % write as RGB
Though note that TIFF does support indexed images.
imwrite(uint8(Array1),mymap,'myimage.tif') % write as indexed
Steve Francis
Steve Francis 2023년 1월 19일
Thanks for this, DGM, and for your comment to Walter's answer. Superb stuff.

댓글을 달려면 로그인하십시오.

채택된 답변

Walter Roberson
Walter Roberson 2023년 1월 19일
Array1 =[0 0 0 0 0 0; 0 1 0 2 0 6; 4 0 5 5 0 9; 0 10 7 0 8 0];
Array2 =[0 0 0 0 0 0; 0 1 0 2 0 3; 4 0 5 5 0 6; 0 7 0 8 9 0];
mymap = [0 0 0; 0.6 1 0.2;1 1 0;0.6 1 0.2; 1 0.6 0.2;1 0 1;0.2 1 0.6;0 1 0;1 0 0;0.2 0.6 1;0 0 1];
B1 = ind2rgb(Array1, mymap);
B2 = ind2rgb(Array2, mymap);
image(B1)
image(B2)
  댓글 수: 3
Steve Francis
Steve Francis 2023년 1월 19일
Awesome comments, DGM. Thank you!
Testing this, it it exactly what I need:
Array1 =[0 0 0 0 0 0; 0 1 0 2 0 6; 4 0 5 5 0 9; 0 10 7 0 8 0];
Array2 =[0 0 0 0 0 0; 0 1 0 2 0 3; 4 0 5 5 0 6; 0 7 0 8 9 0];
mymap = [0 0 0; 0.6 1 0.2;1 1 0;0.6 1 0.2; 1 0.6 0.2;1 0 1;0.2 1 0.6;0 1 0;1 0 0;0.2 0.6 1;0 0 1];
B1 = ind2rgb(Array1+1, mymap);
B2 = ind2rgb(Array2+1, mymap);
image(B1)
image(B2)
Thanks so much for your time! I was struggling with trying to infer how imagesc worked.
Steve Francis
Steve Francis 2023년 1월 19일
Thank you @Walter Roberson for taking the time to answer this question. Much appreciated.

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Orange에 대해 자세히 알아보기

태그

제품


릴리스

R2022a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by