Using a 'for' loop to read gif RGB and pixel index, cant get textscan with 'if' statement to work

2 views (last 30 days)
Hello All,
I have been working on a porting program to take a gif frame by frame, read each pixel and RGB value, then put it into a formatted text file. I have gotten it to work but I am trying to make the code output smaller. I am trying to read each frame, then read the previous frame to see if the pixel index number and RGB value match, if they do not match, add a new entry into the formatted file. If there is a match just skip adding a entry and check the next pixel index number and RGB value. Here is my code,
sourceimage = '/Users/tapotter/Animations/leda36.gif'; %Pull file to load
numframes = numel(imfinfo(sourceimage)); %Pull the number of frames
fida = fopen('FastLEDAnimation.txt', 'a+'); %Open files to use.
fidp = fopen('previousframe.txt', 'wt+'); %Create and open a temporary file to check values against.
for frame = 1:numframes %Go through each frame of the gif
[img, map] = imread(sourceimage, frame); % Open the image and create the map
rgbimg = im2uint8(ind2rgb(img, map)); %turn the index into unit8 rgb format
crgb = reshape(permute(rgbimg, [3, 1, 2]), 3, []); %makes a 3xnumpixels array
framedelay = imfinfo(sourceimage); %Pulls the frame delay from imfinfo
fdelay = framedelay.DelayTime; %Get the frame delay
pixcrgb = [1:size(crgb, 2); double(crgb)]; %Sets up the readout to include what pixel its on but only goes through 255, then repeats 200 times with 255
P = textscan(fidp, 'leds[%d].setRGB(%d, %d, %d);\n', pixcrgb'); %Go through and see if textscan can find these values
if isempty(P) %If the textscan returns empty write to the file
fprintf(fida, 'leds[%d].setRGB(%d, %d, %d);\n', pixcrgb);
end
fprintf(fida, '\nFastLED.delay(%d);\nFastLED.show();\n', fdelay); %Add the delay to the formatted text
fprintf(fidp, 'leds[%d].setRGB(%d, %d, %d);\n', pixcrgb); %Add all of the current pixel 'index' numbers and RGB values for reference as the 'previous' frame next iteration
end
fclose(fida); %Close the files and delete the fidp file.
fclose(fidp);
delete(fidp);
fprintf('\nComplete!\n\n');
Currently it does not return anything during the loop and never writes the 'fprintf(fida, 'leds[%d].setRGB(%d, %d, %d);\n', pixcrgb);' portion to the file. When looking at the previousframe.txt, it continously writes information and append's it. What I was hoping for was it would clear the previousframe.txt and only store the last frames values. I have tried a couple different loops but cant seem to wrap my head around it. Any suggestions on how I might right the loop section? Specifically this part is where I need help,
P = textscan(fidp, 'leds[%d].setRGB(%d, %d, %d);\n', pixcrgb'); %Go through and see if textscan can find these values
if isempty(P) %If the textscan returns empty write to the file
fprintf(fida, 'leds[%d].setRGB(%d, %d, %d);\n', pixcrgb);
end
fprintf(fida, '\nFastLED.delay(%d);\nFastLED.show();\n', fdelay); %Add the delay to the formatted text
fprintf(fidp, 'leds[%d].setRGB(%d, %d, %d);\n', pixcrgb); %Add all of the current pixel 'index' numbers and RGB values for reference as the 'previous' frame next iteration
end
  1 Comment
Jan
Jan on 19 Sep 2018
I'm surprised that this command does not throw an error:
P = textscan(fidp, 'leds[%d].setRGB(%d, %d, %d);\n', pixcrgb')
The 3rd argument is not valid, because textscan expects "N — Number of times to apply formatSpec", but not a matrix.

Sign in to comment.

Accepted Answer

Jan
Jan on 19 Sep 2018
Edited: Jan on 19 Sep 2018
It is not clear, what you want to achieve. Do you want to omit writing e.g. "leds[1].setRGB(2, 3, 4)", if this string occurs in the former block already? Then using a file to store the temporary values is very indirect. Why not using the available values instead?
% [Code EDITED]
sourceimage = '/Users/tapotter/Animations/leda36.gif'; %Pull file to load
numframes = numel(imfinfo(sourceimage)); %Pull the number of frames
fid = fopen('FastLEDAnimation.txt', 'a+'); %Open files to use.
framedelay = imfinfo(sourceimage); % Once only outside the loop
fdelay = framedelay.DelayTime; % Get the frame delay
oldFrame = Inf; % Arbitrary unique value
for iframe = 1:numframes %Go through each frame of the gif
[img, map] = imread(sourceimage, iframe);
rgbimg = im2uint8(ind2rgb(img, map));
crgb = reshape(permute(rgbimg, [3, 1, 2]), 3, []);
Frame = [1:size(crgb, 2); double(crgb)];
changed = any(Frame ~= oldFrame, 1);
oldFrame = Frame;
fprintf(fid, 'leds[%d].setRGB(%d, %d, %d);\n', Frame(:, changed));
fprintf(fid, '\nFastLED.delay(%d);\nFastLED.show();\n', fdelay);
end
fclose(fid);
% delete(fidp); % No DELETE for file identifier of closed file!
fprintf('\nComplete!\n\n');
Please read doc delete. If the former file identifier was e.g. 4. Then delete(4) tries to delete a figure with the handle 4. delete needs a file name for removing a file.
  3 Comments
Travis Potter
Travis Potter on 20 Sep 2018
One last question, the pixel index starts at '1' in the file, but I need it to start at 0 and go to 483. How would I bring the
fprintf(fid, 'leds[%d].setRGB(%d, %d, %d);\n', Frame(:, changed));
To always minus 1 from the first variable '%d' in the "leds[]" section listed above.

Sign in to comment.

More Answers (0)

Categories

Find more on Data Import and Export in Help Center and File Exchange

Products


Release

R2018a

Community Treasure Hunt

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

Start Hunting!