问题
I'm new to Matlab processing, and I would like to read and process a large video (more than 200k frames) inside a "for loop" (or without it). In particular, i would like to:
- read the video with VideoReader,
- subdivide the video into n-epoch of 1000 frames each ones,
- process every epoch of 1000 frames, reading: the first frame of the epoch, skip two, read the frame, skip two, and so on (for example i=1:3:nFrames),
- considering every epoch i need to convert every "RGB-frame" read into im2bw
- after the conversion i need to make the "corr2" 2D cross-correlation considering the first video frame ("mov(1,1).cdata") and every frames read within the epoch,
- store the result from "corr2" into a vector.
In summary, this is what i need to do. Thank You all
This is what I have so far, about "corr2":
for frame_ind = 1 : nFrames
mov(frame_ind).cdata = im2bw(rgb2gray(read(xyloObj,frame_ind)),0.20);
end
%% Corr2 to compare BW video frames
for frame_ind2 = 1:(frame_ind-1)
R(frame_ind2)=corr2(mov(1,frame_ind2).cdata,mov(1,frame_ind2+1).cdata);
end
TF= isnan(R);
g=sum(TF);
f=(length(R)-g);
if (g~=(length(R)))
%%If Part has errors
disp('"Part_1" has video interferences/noise/problems, see "Testresult.txt" for more information.');
else
%%If Part has not errors
displ=strcat('"Part_1" has not video interferences/noise/problems.');
end
回答1:
Here is my version:
mov = VideoReader('movie.avi');
nFrames = mov.NumberOfFrames;
len = 1000; %# epoch length
step = 3; %# step size
%# indices of each epoch
indices = bsxfun(@plus, 1:step:len, (0:ceil(nFrames/len-1))'*len); %#'
indices = num2cell(indices,2);
indices{end}(indices{end}>nFrames) = [];
%# loop over each epoch
corr_coef = cell(size(indices));
for e=1:numel(indices)
%# read first image in epoch
img1 = read(mov, indices{e}(1));
img1 = rgb2gray(img1); %# instead of im2bw(img1, graythresh(img1))
%# read rest of images in epoch
corr_coef{e} = zeros(1,numel(indices{e})-1);
for f=2:numel(indices{e})
img2 = read(mov, indices{e}(f));
img2 = rgb2gray(img2);
%# compute corr2 between the two images
corr_coef{e}(f-1) = corr2(img1,img2);
end
end
The cell array corr_coef
contains the correlation coefficients in each epoch, where each cell contains a vector corr_coef{e}(i)
of corr2
between the first frame and the (i+1)-th frame.
Note that if one of the frames is constant (all black for example), the 2D correlation coefficient is simply NaN (zero divided by zero in the formula)
回答2:
% create video handle and get number of frames
vidObj = VideoReader(video_file);
nFrames = get(vidObj, 'NumberOfFrames');
blocksize = 1000;
BlocksIDs = 1:blocksize:nFrames;
nBlocks = numel(BlocksIDs);
frame_step = 3;
% cell array with all correlations values grouped by block
xcorrs_all_blocks = cell(1, nBlocks);
for j = 1 : nBlocks
% if this is the last block, process until the last frame
if j == nBlocks
last_frame = nFrames;
% otherwise, read until next block
else
last_frame = BlocksIDs(j + 1);
end
% compute the frame numbers that we want to look at
frame_indices = BlocksIDs(j) : frame_step : last_frame;
nFrames = numel(frame_indices);
first_frame = [];
% pre-allocate array holding the in-block corr2 values.
xcorrs_this_block = nan(1, nFrames-1);
for k = 1 : nFrames
% read-in raw frame from video file.
raw_frame = read(vidObj, frame_indices(k));
% determine level for bw conversion - this might help.
level = graythresh(raw_frame);
raw_frame = im2bw(raw_frame, level);
if k == 1
% save current frame as first frame for later corr2 processing
first_frame = raw_frame;
else
% calc the correlation between the first frame in the block and each successive frame
xcorrs_this_block(k-1) = corr2(first_frame, raw_frame);
end
end
% save all xcorr values into global cell array.
xcorrs_all_blocks{j} = xcorrs_this_block;
end
来源:https://stackoverflow.com/questions/11718704/how-to-process-large-video-in-matlab-with-for-loop-and-without-memory-error