Функция scanf()
автоматически удаляет пробелы, прежде чем пытаться проанализировать преобразования, отличные от символов. Исключение составляют форматы символов (в основном %c
, а также наборы сканирования %[…]
- и %n
); они не удаляют пробелы.
Используйте " %c"
с ведущим пробелом, чтобы пропустить дополнительное пустое пространство. Не используйте конечную заготовку в строке формата scanf()
.
Обратите внимание, что это все еще не потребляет никаких конечных пробелов, оставшихся во входном потоке, даже до конца строки, поэтому остерегайтесь что если также использовать getchar()
или fgets()
в том же входном потоке. Мы просто получаем scanf, чтобы пропускать пробелы до , например, для %d
и других несимвольных преобразований.
Обратите внимание, что не-пробелы " директивы "(использовать терминологию POSIX scanf ), отличную от преобразований, например, буквальный текст в scanf("order = %d", &order);
также не пропускает пробелы. Литерал order
должен соответствовать следующему символу, который нужно прочитать.
Итак, вы, вероятно, захотите " order = %d"
там, если хотите пропустить новую строку из предыдущей строки, но по-прежнему требуется литеральное совпадение на фиксированном string, как этот вопрос .
Чтобы избавиться от ошибки в памяти, рассмотрите возможность чтения в одном кадре внутри цикла, как показано в документации mmreader (doc mmreader
):
for k = 2000 : 2200
ims = read(B, k);
end
Причина imshow
не работает, что значение, возвращаемое read(...)
, равно Height x Width x Colors x NumFrames Where Height - высота видео, Width - ширина видео, Colors - количество цветов (обычно 3), а NumFrames - количество кадров, которые вы читаете.
Чтобы отобразить использование первого кадра:
imshow(ims(:,:,:,1));
Если вы хотите реализовать базовый видеопроигрыватель, вот пример:
mov = VideoReader('xylophone.mpg'); %# use mmreader on older versions
for i=1:mov.NumberOfFrames
img = read(mov,i);
imshow(img)
drawnow
end
Это считывает по одному кадру за раз и отображает его с помощью IMSHOW. Обратите внимание, что требуется вызвать DRAWNOW (или приостановить с небольшим значением), чтобы очередь событий GUI была сброшена.
Если вам интересно, я показал в предыдущем ответе пример графического интерфейса для просмотра кадров видеофайла.
Вот что я использую для разделения видео и объединения их в анимированные GIF. Я уверен, что вы можете приспособить его к тому, что вам нравится. Он полностью основан на фрагментах кода из справки MATLAB.
function [ startframe, endframe ] = catgif( inputvideoname, outputfilename,...
startframe, endframe, preview)
InputVideo = VideoReader(inputvideoname);
filename = outputfilename;
if (endframe > InputVideo.NumberOfFrames)
endframe = InputVideo.NumberOfFrames;
end
figure(1)
for ii = 1:endframe
if (ii >= startframe)
img = read(InputVideo,ii);
%Resize or rotate as appropriate.
%img = imresize(imrotate(img, -90),0.5, 'bicubic');
img = imresize(img,0.5, 'bicubic');
imshow(img,'Border','tight');
drawnow
frame = getframe(1);
im = frame2im(frame);
[imind,cm] = rgb2ind(im,256);
if ~strcmp(preview, 'yes')
if ii == startframe;
imwrite(imind,cm,filename,'gif', 'DelayTime', 0, 'Loopcount',inf);
else
imwrite(imind,cm,filename,'gif','DelayTime', 0, 'WriteMode','append');
end
end
end
end
Это разбивает видео на фреймы без необходимости в дополнительных кодеках:
clc;
close all;
% Open an sample avi file
filename = '.\003.AVI';
mov = MMREADER(filename);
% Output folder
outputFolder = fullfile(cd, 'frames');
if ~exist(outputFolder, 'dir')
mkdir(outputFolder);
end
%getting no of frames
numberOfFrames = mov.NumberOfFrames;
numberOfFramesWritten = 0;
for frame = 1 : numberOfFrames
thisFrame = read(mov, frame);
outputBaseFileName = sprintf('%3.3d.png', frame);
outputFullFileName = fullfile(outputFolder, outputBaseFileName);
imwrite(thisFrame, outputFullFileName, 'png');
progressIndication = sprintf('Wrote frame %4d of %d.', frame,numberOfFrames);
disp(progressIndication);
numberOfFramesWritten = numberOfFramesWritten + 1;
end
progressIndication = sprintf('Wrote %d frames to folder "%s"',numberOfFramesWritten, outputFolder);
disp(progressIndication);