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

조회 수: 1 (최근 30일)
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
Jan
Jan 2018년 9월 19일
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.

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

채택된 답변

Jan
Jan 2018년 9월 19일
편집: Jan 2018년 9월 19일
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
Jan
Jan 2018년 9월 19일
I've edited the code: ismember('rows') replaced by the faster any(Frame == oldFrame).
Travis Potter
Travis Potter 2018년 9월 20일
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.

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

추가 답변 (0개)

제품


릴리스

R2018a

Community Treasure Hunt

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

Start Hunting!

Translated by