Error using VideoWriter/writeVideo (line 344) Frame must be 2560 by 1360 - Help

9 ビュー (過去 30 日間)
Mark Dawnson
Mark Dawnson 2019 年 2 月 3 日
回答済み: Walter Roberson 2024 年 12 月 13 日
Hey,
This is my code for writing a video that syncronizes my data plot with the behavior video. I keep getting this error and I dont know how to fix it.
VID = VideoReader('Trial-12.m4v');
%Creat matlab structure to make a new video
v = VideoWriter('ko_base_livetrace.m4v','MPEG-4');
%Frame rate of the video you are reading
fps_vid = VID.frameRate;
%Frame rate of FP data
fps_data = signal.sampling_rate;
%How long you want new video to be
vid_duration = VID.duration;
%Frame rate of created video will be the frame rate of the behavior video
%v.FrameRate = fps_vid/300;
v.FrameRate = (floor((VID.NumberOfFrames/5))+1)/vid_duration;
%Number of frames in this new video
vid_frames = floor(vid_duration * fps_vid);
%Open the new video for writing
open(v);
%Create a structure to hold the FP trace data as needed as you generate frames
dataNeeded = [];
%Create a list of the times to pull from for x-axis of plot.
times= [1/fps_data:1/fps_data:(fps_data*vid_duration)]';
%The time in the behavior video you want to be the start of the new video.
startTime = 0;
%Find which frame this is in the video
frameStart = startTime*fps_vid+1;
%The location in FP data trace will always start from when plotting during
%video (just the start time in the FP data)
minPoint = (startTime)*fps_data + 1;
minD = -2 %floor(min(deltaFTrialTwo(minPoint:vid_duration*fps_data))*100);
maxD = 4 %ceil(max(deltaFTrialTwo(minPoint:vid_duration*fps_data))*100);
%Loop through frame by frame of behavior video, create matlab figure
%displaying that frame of video plus a plot of FP data up to that time
%point. Then save as a frame of new video.
frameCount = 0;
for n = frameStart:5:(frameStart+vid_frames)
%Create new figure
p = figure(1);
set(gcf,'color','w');
%Set the dimensions of the figure to be the size of your monitor
set(p, 'Position', [1 1 1920 980])
%Create new subplot location and fill with current berhavior video
%frame.
subplot('Position',[0.05 0.5 .9 0.6])
imshow(read(VID,n));
%Create new subplot for FP trace
s = subplot(2,1,2);
%Data needed for this frame for FP plot, is all data from minPoint to
%current time.
%THIS IS ALTERED TO SUBTRACT 1 SECOND FROM FP DATA TO ACCOUNT FOR 1S
%DELAY TRACKING START.
dataNeeded = df(minPoint:((n/fps_vid)*fps_data)+ 1);
%Get list of times (in seconds) for labeling x-axis of FP plot
timeNeeded = times(minPoint:((n/fps_vid)*fps_data)+ 1,1);
%Plot the data
plot(timeNeeded,dataNeeded,'k','LineWidth',2);
%Label stuff, change axis limits and font sizes
xlabel('Time (s)');
ylabel('DeltaF/F (%)');
ylim([minD maxD]);
xlim([0 vid_duration]);
set(gca,'fontsize',30)
set(gca,'FontWeight','bold');
%Create an image frame from the figure
A = getframe(figure(1));
%Write the frame to new video
writeVideo(v,A);
frameCount = frameCount + 1;
end
%Close new video
close(v)

回答 (2 件)

Pratik
Pratik 2024 年 12 月 12 日
Hi Mark,
I used the same code but replaced the 'Trial-12.m4v' random values to reproduce the error on my end. But it is not reproducible using this approach and is working fine.
Please refer to the following code:
% Create dummy data for the video and FP data
dummyFrame = uint8(255 * rand(1080, 1920, 3)); % Create a random RGB image
dummyFrames = repmat({dummyFrame}, 1, 300); % Assume 300 frames
dummy_fps_vid = 30; % Dummy frame rate for the video
dummy_vid_duration = 10; % Dummy video duration in seconds
dummy_fps_data = 100; % Dummy frame rate for FP data
dummy_df = rand(dummy_fps_data * dummy_vid_duration, 1); % Dummy FP data
dummy_times = (1/dummy_fps_data:1/dummy_fps_data:dummy_vid_duration)'; % Dummy time vector
% Create MATLAB structure to make a new video
v = VideoWriter('ko_base_livetrace.m4v', 'MPEG-4');
% Frame rate of created video
v.FrameRate = (floor((length(dummyFrames)/5)) + 1) / dummy_vid_duration;
% Number of frames in this new video
vid_frames = floor(dummy_vid_duration * dummy_fps_vid);
% Open the new video for writing
open(v);
% Create a structure to hold the FP trace data as needed as you generate frames
dataNeeded = [];
% The time in the behavior video you want to be the start of the new video.
startTime = 0;
% Find which frame this is in the video
frameStart = startTime * dummy_fps_vid + 1;
% The location in FP data trace will always start from when plotting during video
minPoint = (startTime) * dummy_fps_data + 1;
minD = -2; % Dummy min value for y-axis
maxD = 4; % Dummy max value for y-axis
% Loop through frame by frame of behavior video, create MATLAB figure
% displaying that frame of video plus a plot of FP data up to that time point.
% Then save as a frame of new video.
frameCount = 0;
for n = frameStart:5:(frameStart + vid_frames)
% Create new figure
p = figure(1);
set(gcf, 'color', 'w');
% Set the dimensions of the figure to be the size of your monitor
set(p, 'Position', [1 1 1920 980]);
% Create new subplot location and fill with current behavior video frame.
subplot('Position', [0.05 0.5 .9 0.6]);
imshow(dummyFrames{mod(n, length(dummyFrames)) + 1});
% Create new subplot for FP trace
s = subplot(2, 1, 2);
% Data needed for this frame for FP plot, is all data from minPoint to current time.
dataNeeded = dummy_df(minPoint:((n/dummy_fps_vid) * dummy_fps_data) + 1);
% Get list of times (in seconds) for labeling x-axis of FP plot
timeNeeded = dummy_times(minPoint:((n/dummy_fps_vid) * dummy_fps_data) + 1, 1);
% Plot the data
plot(timeNeeded, dataNeeded, 'k', 'LineWidth', 2);
% Label stuff, change axis limits and font sizes
xlabel('Time (s)');
ylabel('DeltaF/F (%)');
ylim([minD maxD]);
xlim([0 dummy_vid_duration]);
set(gca, 'fontsize', 30);
set(gca, 'FontWeight', 'bold');
% Create an image frame from the figure
A = getframe(figure(1));
% Write the frame to new video
writeVideo(v, A);
frameCount = frameCount + 1;
end
% Close new video
close(v);
I can deduce that there is some issue with the video used, it will be easier to figure out if I have the access to the video. For now it seems that frame size of the video might be changing causing the error.

Walter Roberson
Walter Roberson 2024 年 12 月 13 日
A = getframe(figure(1));
The exact size of the frame returned by getframe() can vary a little. In particular, it can vary according to the exact size required to render the numeric labels -- and your numeric labels vary as you are executing.
The work-around is to record the exact size of the frame returned on the first iteration. For iterations after that, after the getframe(), imresize() the frame to match the saved size.
A.cdata = imresize(A.cdata, SAVED_SIZE);
The resulting video might jiggle the exact position of the right hand axes boundary, but at least it will work.

カテゴリ

Help Center および File ExchangeMATLAB Support Package for USB Webcams についてさらに検索

タグ

Community Treasure Hunt

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

Start Hunting!

Translated by