Sunday, April 17, 2016

range of last 10 numbers/frames in Matlab

Leave a Comment

I need to retrieve/register/remember last 10 frames from the video file. This is a small version of a bigger project for detecting micro-expressions. Therefore it need to check if "lines" have been showing for last 10 frames (detected) or if it is showing for more than 10 then it not detected. I'm also enforced to work with vision.VideoFileReader and vision.OpticalFlow. How to do this?

file = 'MEXTest.mp4'; vid = vision.VideoFileReader(file,'ImageColorSpace','RGB','VideoOutputDataType','single'); optFlo = vision.OpticalFlow('OutputValue','Horizontal and vertical components in complex form','ReferenceFrameDelay',3); shapeInsertOptFloColor = vision.ShapeInserter('Shape','Lines','BorderColor','Custom','CustomBorderColor',[255 255 0]);  numFrames = 0; frameList = {}; hasLines = zeros(10, 1, 'logical');  figH = figure;  while ~isDone(vid)     colorFrame  = step(vid);     colorFrameRes = imresize(colorFrame,0.3);     grayFrame = rgb2gray(colorFrameRes);      optFloVectors = step(optFlo, grayFrame);     lines = oflo(optFloVectors,20);     motionVectors = step(shapeInsertOptFloColor, colorFrameRes, lines);     imshow(motionVectors); title('Optical Flow on Frame');      notEmpty = ~isempty(lines);     if numel(notEmpty) ~= 1, notEmpty = 1; end      hasLines = [hasLines(2:end); notEmpty];      if numFrames >= 10         frameList = [frameList(2:end) colorFrame];     else         frameList = [frameList colorFrame];     end      numFrames = numFrames + 1;      if numFrames >= 10 && all(hasLines)         disp('Micro-Expression Detected')     else         disp('Not detected')     end      if ~ishghandle(figH)         close all         break     end end release(vid); 

2 Answers

Answers 1

If all you are trying to do is find out if any points have been found in each of the last 10 frames, you can do something like this:

vid = vision.VideoFileReader('MEXTest.mp4','ImageColorSpace','Intensity','VideoOutputDataType','uint8');  numFrames = 0;  frameList = {} hasPoints = zeros(10, 1, 'logical')  while ~isDone(vid)     frame = step(vid);     points = detectMinEigenFeatures(frame);      notEmpty = ~isempty(points)     if numel(notEmpty) ~= 1, notEmpty = 1; end      % Do the check for 10 frames before this step     % if you want to exclude the current frame from the 10     hasPoints = [hasPoints(2:end); notEmpty]      % Stashing the frames may not be necessary, this     % just shows how to build up a circular buffer     if numFrames >= 10         frameList = [frameList(2:end) frame]     else         frameList = [frameList frame]     end      % Count last frame now that it has been added     numFrames = numFrames + 1;      if numFrames >= 10 && all(hasPoints)         disp('Detected')     else         disp('Not Detected')     end end release(vid) 

The circular buffer frameList will keep track of the last 10 frames. That step is not really crucial. What is crucial is hasPoints which stores a flag equal to ~isempty(points) for each of the last 10 frames. If all(hasPoints) is true, than all of the last 10 frames detected a feature.

This solution is not super-efficient because it reallocates the accumulation arrays repeatedly, but it only does so for 10 frames using this solution for a circular buffer. You know what they say about premature optimization though.

Keep in mind that I do not check if the points are the ones you want in every case, just that the last 10 frames have some points detected. From your comments, it seems as though this is an acceptable interpretation.

Answers 2

I have not worked so much with videos - but a general procedure would be to store it in an array of structs. Call if frames, then you can initialize it with:

frames(10) = struct('prob1',0,'prob2',0,...,'probn',0); 

where prob1, prob2,..., probn is the properties of the frame you want to save. Then every time you load a frame, you save the properties of that frame to a struct frame in the same manner.

frame = struct('prob1',val1,'prob2',val2,...,'probn',valn); 

where val1, val2, ..., valn, be be everything, including the frame as a matrix. After this save it to the list

frames = [frames(2:end),frame]; 

then at every point in time you have the properties you need from the 10 previous frames, which you access by:

frames(2).prob2 

which will give you the second property of the frame 8 frames ago. So it is just a minor change from what you already have, but (if I understood your question correctly) it should solve the problem.

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment