Extracting the XY + RGB value from an image.

6 views (last 30 days)
Hello,
I am working on a program to pull the RGB values of a 22x22 gif. I am using this to turn it into a template to use on a LED matrix. I have been searching high and low and think I might be using the wrong wording or where to look.
What I want to accomplish is read a 22x22 gif(Frame by frame if possible), take out each XY and RGB value and put it in output file. I have found these examples that kind of get me where I want to go, but I cant figure out how to bring it home.
I found that I can use imread to upload the gif or image, then I can use something similar too
rgbImage = permute(rgbImage, [3,2,1]);
serialValues = rgbImage(:)';
This does not seem to return the information I need or I dont understand how to put it together. This is the example output I am getting
al(:,:,1) =
Columns 1 through 9
0.9922 0.5373 0.0667 0.0667 0.0667 0.0667 0.0667 0.1333 0.4471
0.8275 0.2000 0.0667 0.0667 0.0667 0.0667 0.0667 0.0667 0.0235
0.2471 0.1020 0.0667 0.1333 0.1333 0.1333 0.1333 0.1333 0.4627
Columns 10 through 18
0.1333 0.2980 0.3333 0.7608 0.9961 0.5373 0.0667 0.0667 0.0667
0.0667 0.2902 0.2000 0.1725 0.4275 0.2000 0.0667 0.0667 0.0667
0.2078 0.0157 0.1216 0.0157 0.3059 0.1020 0.1333 0.1333 0.1333
Columns 19 through 22
0.0667 0.0667 0.4275 0.2000
0.0667 0.0667 0.0667 0.0667
0.1333 0.0667 0.1373 0.1333
val(:,:,2) =
Columns 1 through 9
0.6314 0.2000 0.0667 0.0667 0.0667 0.0667 0.0667 0.0667 0.1373
0.3059 0.0667 0.0667 0.0667 0.0667 0.0667 0.0667 0.0667 0.1137
0.1176 0.0667 0.1333 0.1333 0.1333 0.1333 0.1333 0.1333 0.3294
Columns 10 through 18
0.2392 0.3176 0.1333 0.6980 1.0000 0.8275 0.2667 0.0667 0.0667
0.0314 0.4196 0.0667 0.4118 0.5529 0.2824 0.0667 0.0667 0.0667
0.4510 0.4235 0 0.4863 0.4431 0.3059 0.0667 0.1333 0.1333
Columns 19 through 22
0.0667 0.2667 0.3333 0.0667
0.0667 0.0667 0.0667 0.0667
0.1333 0.0667 0.0667 0.1333
Which I believe is one value, either the red green or blue. Where are the other values at? I thought it might have been from the image or not getting converted correctly but I even tried this method which I feel did not work.
Read an image and convert it to an RGB image.
Read the first image in the sample indexed image file, corn.tif.
[X,map] = imread('corn.tif');
X is a 415-by-312 array of type uint8.
Verify that the colormap, map, is not empty, and convert the data in X to RGB.
if ~isempty(map)
Im = ind2rgb(X,map);
end
View the size and class of X.
whos Im
Name Size Bytes Class Attributes
Im 415x312x3 3107520 double
X is now a 415-by-312-by-3 array of type double.
I would like it to pull the information, pull all of the RGB colors with X/Y coordinates and then put it into a file to upload into FastLED to light up the specific LEDs I want. Any other help on guiding me to a proper solution is extremely helpful. Also if someone could assist in helping me understand the array of 3,2,1 after the permute, is that column, row and then RGB value?
  2 Comments
Stephen23
Stephen23 on 12 Sep 2018
Edited: Stephen23 on 12 Sep 2018
@Travis Potter: what exactly is al ? What is val ? You don't tell us anything about them, or how they are created. This makes it very difficult for us to make any comments or advice.
Please upload a sample .gif by clicking the paperclip button.
RGB images are typically encoded as an RxCx3 arrays, in which case each plane encodes the R, G, and B values respectively. You can learn about how images are represented in MATLAB by reading the MATLAB documentation:
Once you read the documentation it will be clear that your question "Extracting Every RGB value from a matrix" is not very clear:
  1. RGB images are typically stored in 3D arrays, not matrices.
  2. What does it mean to "extract" the RGB values? Why not just use indexing? E.g. to get the RGB values of the first pixel of image array I:
I(1,1,:)
Travis Potter
Travis Potter on 12 Sep 2018
The "al" and "val" are the same, the first is a missing the v. That is just the output I get from using imread() in matlab.
I am mixing up my terms as its just an image. The images of course are in a matrix or array, I was using the wrong terminology. I believe though you have pointed me in the right direction. I think I might be looking for indexing, I really appreciate your response and I am attaching a small gif now.

Sign in to comment.

Accepted Answer

Guillaume
Guillaume on 12 Sep 2018
Assumming your LED array has as many leds as pixels in the GIF, then the following code should translate the GIF into the CRGB array expected by FastLed:
sourceimage = 'corn.tif';
numframes = numel(imfinfo(sourceimage); %get number of frames
for frame = 1:numframes %iterate over the frames
[img, map] = imread(sourceimage, frame); %read frame
rgbimg = im2uint8(ind2rgb(img, map)); %convert to RGB and to 8-bit integer
crgb = permute(rgbimg, [3, 1, 2]); %change memory storage from RRR...GGG...BBB... to RGBRGBRGB....
crgb = crgb(:); %convert to 1D array.
%...
%your code to pass the crgb array to fastled.
%you can copy the whole crgb array directly into your FastLed led array
%it already has the correct memory layout
%note that the pixels are rearranged by column. So led[2] is the 2nd pixel of the first column
end
Note that I don't know anything about FastLed, I've just read its documentation for the first time now, so no guarantee that the above works.
  3 Comments
Guillaume
Guillaume on 12 Sep 2018
The reason you get problems with sourceimage is because you used double quotes instead of single quotes. imfinfo doesn't (yet) support strings, just plain char arrays.
Now that I know what you want to do with the RGB data, here's how I'd do it:
sourceimage = '/Users/tapotter/anime/anime1.gif';
numframes =numel(imfinfo(sourceimage));
fid = fopen('FastLEDAnimation.txt', 'a+'); %open the file OUTSIDE the loop!
for frame = 1:numframes
%write frame header here
%e.g
fprintf('\\Code for frame %d', frame);
[img, map] = imread(sourceimage, frame);
rgbimg = im2uint8(ind2rgb(img, map));
crgb = reshape(permute(rgbimg, [3, 1, 2]), 3, []); %makes a 3xnumpixels array
pixcrgb = [1:size(crgb, 2); crgb]; %add pixel index as first row
fprintf(fid, 'leds[%d].setRGB(%d, %d, %d);\n', crgb);
end
fclose(fid);
Travis Potter
Travis Potter on 12 Sep 2018
I tried using the code but I am still not getting the desired results. This is the code I used
sourceimage = '/Users/tapotter/anime/leda11.gif'; %Pull image which I am attaching to this post
numframes =numel(imfinfo(sourceimage));
fid = fopen('FastLEDAnimation.txt', 'a+'); %Open the file, outside the loop of course ;)
for frame = 1:numframes %Go through each frame of the gif
fprintf('Frame: %d Complete', frame); %Post to the console when each frame is complete
[img, map] = imread(sourceimage, frame);
rgbimg = im2uint8(ind2rgb(img, map));
crgb = reshape(permute(rgbimg, [3, 1, 2]), 3, []); %makes a 3xnumpixels array
pixcrgb = [1:size(crgb, 2); crgb];
fprintf(fid, 'leds[%d].setRGB(%d, %d, %d);\n', crgb);
fprintf(fid, 'FastLED.delay(200)')
end
fclose(fid);
Here is the output I am getting at the top, then I am showing kinda of what I was looking to get. Each time it goes through there should be only 1 LED number used on each frame. I am seeing multiple of the same number. As the GIF is 22x22 it should amount to 484 pixels or LEDS.
This is the current output directly from the file,
leds[0].setRGB(0, 0, 0);
leds[0].setRGB(0, 18, 20);
leds[20].setRGB(8, 8, 9);
leds[20].setRGB(34, 36, 20);
leds[34].setRGB(36, 20, 40);
leds[47].setRGB(33, 65, 70);
leds[22].setRGB(52, 54, 33);
leds[65].setRGB(70, 12, 70);
leds[80].setRGB(33, 65, 70);
leds[33].setRGB(65, 70, 33);
leds[65].setRGB(70, 33, 65);
leds[70].setRGB(20, 34, 36);
leds[19].setRGB(33, 22, 20);
leds[34].setRGB(36, 18, 20);
leds[20].setRGB(16, 8, 16);
leds[0].setRGB(0, 0, 0);
leds[0].setRGB(0, 0, 0);
leds[0].setRGB(0, 0, 0);
leds[8].setRGB(8, 9, 20);
leds[34].setRGB(36, 20, 34);
leds[36].setRGB(20, 34, 36);
leds[33].setRGB(65, 70, 35);
leds[72].setRGB(86, 45, 136);
leds[145].setRGB(47, 170, 183);
leds[24].setRGB(195, 214, 24);
leds[195].setRGB(214, 47, 170);
leds[183].setRGB(45, 136, 145);
leds[33].setRGB(84, 88, 20);
leds[40].setRGB(47, 22, 52);
leds[54].setRGB(18, 20, 20);
-----------------
--------
======DESIRED OUTPUT=========
leds[0].setRGB(33, 65, 70);
leds[1].setRGB(65, 70, 33);
leds[2].setRGB(70, 33, 65);
leds[3].setRGB(20, 34, 36);
leds[4].setRGB(33, 22, 20);
leds[5].setRGB(36, 18, 20);
leds[6].setRGB(16, 8, 16);
leds[7].setRGB(0, 0, 0);
leds[8].setRGB(0, 0, 0);
leds[9].setRGB(0, 0, 0);
leds[10].setRGB(8, 9, 20);
leds[11].setRGB(36, 20, 34);
leds[12].setRGB(20, 34, 36);
leds[13].setRGB(65, 70, 35);
leds[14].setRGB(86, 45, 136);
leds[15].setRGB(47, 170, 183);
leds[16].setRGB(195, 214, 24);
This is how I am thinking the image is suppose to be pulled pixel wise from the gif image. Thats what I need to translate into this LED panel.
0 > 1 > 2 > 3 > 4
// |
// .----<----<----<----'
// |
// 5 > 6 > 7 > 8 > 9
// |
// .----<----<----<----'
// |
// 10 > 11 > 12 > 13 > 14
// |
// .----<----<----<----'
// |
// 15 > 16 > 17 > 18 > 19
Thank you so much for your help and understanding in helping me write this little program. I know I am learning a lot as I go and have been stuck for a little while on this. Cheers

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!