2016-04-06 12 views
2

Ich muss die letzten 10 Bilder aus der Videodatei abrufen/registrieren/merken. Dies ist eine kleine Version eines größeren Projekts zur Erkennung von Mikroausdrücken. Daher muss überprüft werden, ob "Zeilen" für die letzten 10 Bilder (erkannt) angezeigt wurden oder ob es für mehr als 10 angezeigt wird, dann wird es nicht erkannt. Ich bin auch gezwungen, mit vision.VideoFileReader und vision.OpticalFlow zu arbeiten. Wie macht man das?Bereich der letzten 10 Zahlen/Frames in Matlab

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

Was genau fragen Sie? Möchtest du dich an die letzten 10 Frames des Videos erinnern, die vor dem aktuellen Punkt eingelesen wurden? – rayryeng

+0

'isempty (punkte) == false' ->' ~ isempty (punkte) ' –

+0

ja, tut mir leid, dass ich das nicht richtig ausgedrückt habe. – UZIERSKI

Antwort

4

Wenn alles, was Sie zu tun versuchen wird herauszufinden, ob alle Punkte in jedem der letzten 10 Frames wurden gefunden, Sie so etwas tun kann:

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) 

Der Ringpuffer frameList wird Verfolge die letzten 10 Frames. Dieser Schritt ist nicht wirklich entscheidend. Was entscheidend ist, ist hasPoints, die ein Flag gleich ~isempty(points) für jeden der letzten 10 Frames speichert. Wenn all(hasPoints) wahr ist, haben alle der letzten 10 Frames ein Feature erkannt.

Diese Lösung ist nicht besonders effizient, da sie die Akkumulationsarrays wiederholt neu zuordnet, jedoch nur für 10 Frames unter Verwendung der this Lösung für einen Ringpuffer. Sie wissen jedoch, was sie über vorzeitige Optimierung sagen.

Denken Sie daran, dass ich nicht überprüfe, ob die Punkte in jedem Fall die gewünschten sind, nur dass die letzten 10 Rahmen einige Punkte haben. Aus Ihren Kommentaren scheint dies eine akzeptable Interpretation zu sein.

+0

Es gibt mir Fehler in Zeile 14 - Dimensionen von Matrizen, die verkettet werden, sind nicht konsistent. Kann ich diese ~ isempty (points) 'in die zweite if-Anweisung verschieben (indem ich einen anderen AND-Operator hinzufüge), anstatt sie zu verketten? Wird mir das die gleiche Ausgabe geben? – UZIERSKI

+0

Sie müssen sie verketten, um sie der Liste hinzuzufügen, sonst sammeln Sie niemals Informationen zu den vorherigen Frames an. Was ist "Größe (ist leer (Punkte))"? –

+0

Größe ist = 225 4 Wenn sie angezeigt werden – UZIERSKI

1

Ich habe nicht so viel mit Videos gearbeitet - aber eine allgemeine Prozedur wäre es in einem Array von Strukturen zu speichern. Rufen Sie, wenn Rahmen, dann können Sie es initialisieren mit:

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

wo prob1, prob2, ..., probn ist die Eigenschaften des Rahmens Sie speichern möchten. Dann speichern Sie jedes Mal, wenn Sie einen Rahmen laden, die Eigenschaften dieses Rahmens auf dieselbe Weise in einem Strukturrahmen.

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

wo val1, val2, ..., valn, alles sein, einschließlich des Rahmens als Matrix. Danach es in die

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

dann bei jedem Zeitpunkt haben Sie die Eigenschaften, die Sie von den 10 vorhergehenden Rahmen benötigen, die Sie durch Zugang:

frames(2).prob2 

Ihnen die zweite geben Eigenschaft des Rahmens vor 8 Frames. Es ist also nur eine kleine Änderung von dem, was Sie bereits haben, aber (wenn ich Ihre Frage richtig verstanden habe), sollte es das Problem lösen.