2013-09-22 5 views
3

Я искал stackoverflow для аналогичного вопроса, и я нашел вопрос «movie2avi-frame-size-error-and-keep-frame-size-constant». К сожалению, ответ на этот вопрос не разрешил мою проблему (было предложено использовать xlim, ylim и zlim).movie2avi - как исправить размер рамки?

В дальнейшем я отправляю слегка модифицированную версию известного примера, приведенного в другом месте.

%# figure 
figure, set(gcf, 'Color','white') 
Z = peaks; surf(Z); axis tight 
set(gca, 'nextplot','replacechildren', 'Visible','off'); 
[az,el]=view; 
xl=xlim; 
yl=ylim; 
zl=zlim; 

%# preallocate 
nFrames = 20; 
mov(1:nFrames) = struct('cdata',[], 'colormap',[]); 

%# create movie 
for k=1:nFrames 
    view([(az-k*10) el]); 
    xlim(xl);ylim(yl);zlim(zl); 
    drawnow;pause(0.1); 
    mov(k) = getframe(gca); 
end 
close(gcf) 

%# save as AVI file, and open it using system video player 
movie2avi(mov, 'myPeaks1.avi', 'compression','None', 'fps',10); 

Идея состоит в том, чтобы повернуть фигуру и создать фильм. Все работает отлично, за исключением последней команды, то есть movie2avi. Тзд ошибка

Error using avifile/addframe>ValidateFrame (line 290) 
Frame must be 435 by 344. 

Error in avifile/addframe (line 158) 
ValidateFrame(aviobj,width, height,dims); 

Error in movie2avi (line 67) 
avimov = addframe(avimov,mov); 

Error in more_video_test (line 24) 
movie2avi(mov, 'myPeaks1.avi', 'compression','None', 'fps',10); 

Я посмотрел на подходах-к-Create-A-видео-в-MATLAB здесь в StackOverflow и обнаружили, что:

а) Решение FFmpeg работает, но я хотел бы избежать Это.
b) Все остальные решения не прошли даже QTWriter. Как я могу исправить размер кадра, чтобы работали все эти другие решения?

Большое спасибо.

Ed

+2

Посмотрите на новый класс 'VideoWriter' в MATLAB. Вы все еще используете 'getframe', но затем вы используете метод writeVideo для сохранения каждого кадра внутри цикла. http://www.mathworks.com/help/matlab/ref/videowriterclass.html – chappjc

+0

Это не «приятное» решение, поэтому я не буду публиковать его как ответ, но я думаю, что если вы укажете прямоугольник в getFrame (напримерgetframe (gca, [0 0 435 344]);) должен решить эту проблему ... – pseudoDust

+0

Кроме того, это может помочь установить атрибут позиции оси. – pseudoDust

ответ

2

Проблема заключается в том, что из-за вращения графика размер изменяется по оси, так что в итоге с последовательностью кадров различных размеров. Вы можете увидеть это, если вставить строки

s = size(mov(k).cdata); 
fprintf('%d %d\n', s(2), s(1)) 

внутри цикла, непосредственно после того, как вы схватил кадр

mov(k) = getframe(gca); 

В результате

435 344 
435 343 
435 343 
436 342 
435 343 
435 343 
435 343 
435 343 
435 343 
435 343 
435 343 
435 343 
435 343 
435 343 
435 343 
435 343 
435 343 
435 343 
435 343 
435 343 

Поскольку первый кадр имеет размер 435 x 344, movie2avi ожидает, что следующие кадры будут иметь одинаковый размер - но это не так.

Чтобы исправить это, вы можете установить размер оси (&), используя set(gca, 'Position', [...]). Более простым способом является захват кадра не от оси, а от фигуры. То есть, вместо того, чтобы использовать mov(k) = getframe(gca);

mov(k) = getframe(gcf); 

кадры затем имеют однородный размер 560 х 420.

На моей машине, в результате AVI имеет кадры вверх дном. Чтобы исправить это, вы также можете вставить строку

mov(k).cdata = mov(k).cdata(end :-1: 1, :, :); 

после захвата рамки.

+0

@Donda - Большое вам спасибо. Я использовал обходной путь и изменил writeVideo, чтобы получить поворот. На маке мне не нужно было вставлять лишнюю строку, чтобы избежать перевернутых кадров. Это проблема Windows? –

+0

Добро пожаловать. Я не уверен в этой ошибке. Я нахожусь в Linux, но раньше делал фильмы, и мне не пришлось переворачивать ... –

1

Я нашел альтернативное решение для моего вопроса.

%# figure 
figure, set(gcf, 'Color','white') 
Z = peaks; surf(Z); axis tight 
set(gca, 'nextplot','replacechildren', 'Visible','off'); 
axis vis3d 

% With VideoWriter 

writerObj = VideoWriter('myPeaks3.avi'); 
open(writerObj); 

%# preallocate 
nFrames = 90; 
mov(1:nFrames) = struct('cdata',[], 'colormap',[]); 

%# create movie 
for k=1:nFrames 
    camorbit(360/nFrames,0,'data','z'); 
    drawnow; 
    mov(k) = getframe(gcf); 
    writeVideo(writerObj,mov(k)); 
end; 

% Close file 

close(writerObj); 

 Смежные вопросы

  • Нет связанных вопросов^_^