2014-06-12 10 views
8

Próbuję znaleźć tętno z wideo mojej skóry. W tym celu robię przycięty prostokąt pikseli z mojej klatki wideo i uśredniam czerwony (lub zielony) komponent we wszystkich tych pikselach (wtedy oczywiście widzę, jak ta średnia zmienia się w ramce do ramki).Uzyskanie częstości akcji serca z prostego wideo: kod wewnątrz

Wykonuję szybką transformatę Fouriera wektora (średnia wartość koloru każdej przyciętej sekcji każdej klatki), aby zobaczyć, które częstotliwości są najbardziej widoczne. Mam nadzieję, że spoczynkowe tętno człowieka, ~ 1Hz, będzie bardzo wyraźne.

Jako test, zrobiłem film o ścianie lub innych obiektach, które nie powinny mieć okresowej zmiany koloru. Użyłem statywu i trzech różnych kamer różnych marek. Każdy z nich ma podobne, jeśli nie identyczne, szczyty częstotliwości tła, szczególnie przy 1 Hz, 2 Hz, 5 Hz i 10 Hz. Strzelałem pod naturalnym światłem i fluorescencyjne i nadal występuje.

Moim ostatecznym celem jest odróżnienie, za pomocą tej analizy, żywej skóry od nie-unaczynionej skóry. Zatem zrozumienie, dlaczego otrzymuję te szczyty częstotliwości dla obiektów nieożywionych, to VITAL.

Czy ktokolwiek z was mógłby uruchomić ten kod na swoich własnych filmach i pomóc wyjaśnić, czy jestem po prostu idiotą?

strzelanie

Aparat:

Kodak Playsport

1920x1080 30fps (60i) importuje jak mp4

Canon VIXIA HF200 1440x1080 30fps (60i) bitrate 12Mbps importuje jak .mts który Ponownie kod do mp4

Kod oparty na:

http://www.ignaciomellado.es/blog/Measuring-heart-rate-with-a-smartphone-camera#video

clear all 
close all 
clc 

%% pick data file name to be analyzed, set directory it is found in 
dataDir = './data'; 
vidname = ['Filename.MP4']; 

%% define path to file and pull out video 
inFile = fullfile(dataDir,vidname); 
video = VideoReader(inFile); 

%% make 1D array with length equal to number of frames (time) 

brightness = zeros(1, video.NumberOfFrames); 
video_framerate = round(video.FrameRate); % note some places in the code must use integer value for framerate, others we directly use the unrounded frame rate 

%% set region of interest for what you want to get average brightness of 
frame = read(video, 1); 
imshow(frame) 
rect = getrect; 
close all 

xmin_pt = round(rect(1)); 
ymin_pt = round(rect(2)); 
section_width = round(rect(3)); 
section_height = round(rect(4)); 

%% select component of video (red green or blue) 
component_selection = 1; % pick red , green, or blue 

%% make 1D array of ROI averages 
for i = 1:video.NumberOfFrames, 
    frame = read(video, i); 
    section_of_interest = frame(ymin_pt:ymin_pt+section_height,xmin_pt:xmin_pt+section_width,:); 
    colorPlane = section_of_interest(:, :, component_selection); 
    brightness(i) = sum(sum(colorPlane))/(size(frame, 1) * size(frame, 2)); 
end 


%% Filter out non-physiological frequencies 
BPM_L = 40; % Heart rate lower limit [bpm] 
BPM_H = 600; % Heart rate higher limit [bpm] This is currently set high to investigate the signal 

% Butterworth frequencies must be in [0, 1], where 1 corresponds to half the sampling rate 
[b, a] = butter(2, [((BPM_L/60)/video_framerate * 2), ((BPM_H/60)/video_framerate * 2)]); 
filtBrightness = filter(b, a, brightness); 


%% Trim the video to exlude the time where the camera is stabilizing 
FILTER_STABILIZATION_TIME = 3; % [seconds] 
filtBrightness = filtBrightness((video_framerate * FILTER_STABILIZATION_TIME + 1):size(filtBrightness, 2)); 

%% Do FFT on filtered/trimmed signal 
fftMagnitude = abs(fft(filtBrightness)); 

%% Plot results 

figure(1) 
subplot(3,1,1) 
plot([1:length(brightness)]/video.FrameRate,brightness) 
xlabel('Time (seconds)') 
ylabel('Color intensity') 
title('original signal') 

subplot(3,1,2) 
plot([1:length(filtBrightness)]/video.FrameRate,filtBrightness) 
xlabel('Time (seconds)') 
ylabel('Color intensity') 
title('after butterworth filter and trim') 


freq_dimension = ((1:round(length(filtBrightness)))-1)*(video_framerate/length(filtBrightness)); 

subplot(3,1,3) 
plot(freq_dimension,fftMagnitude) 
axis([0,15,-inf,inf]) 
xlabel('Frequency (Hz)') 
ylabel('|Y(f)|') 
title('Fft of filtered signal') 
+0

Czy masz oświetlenie fluorescencyjne, które migocze przy częstotliwości ~ 60 Hz? Lub cokolwiek częstotliwość AC jest w twoim locale? Lub coś innego, jak telewizor lub coś z odświeżaniem i tworzeniem odbić (nawet jeśli nie jest to widoczne na własne oczy)? – twalberg

+0

Próbowałem zarówno pod naturalnym oświetleniem (na zewnątrz), jak iw biurze, w którym mamy fluorescencję. 60 Hz jest dość szybkie. Nie mogę zrozumieć komponentów 1, 2, 5 i 10Hz, które wydają się pojawiać we wszystkich moich sygnałach. Wydaje się, że są one nieodłączne z czymś, co używam lub robię, ale nie jestem pewien. Miałam nadzieję, że ktoś doświadczyłby tego wcześniej lub miał film, który mogliby sami uruchomić. – user3734804

+0

Myślałem, że zakłócenia uderzają w coś, co jest bliskie, ale nie dokładnie przy wielokrotności szybkości klatek 30 klatek na sekundę (która może, ale nie musi być dokładnie 30 Hz na początek). Pojawiłoby się to z niektórymi znaczącymi komponentami częstotliwości w dziedzinie częstotliwości ... – twalberg

Odpowiedz

1

Twoim celem jest, aby „znaleźć tętno z filmu mojej skóry” oraz „... aby odróżnić, z tej analizy, mieszka skórę od non-unaczynionej skórze” Ale twoja podejście to "weź wideo ... przycinaj ... średni czerwony (lub zielony) komponent. Zobacz, jak się zmienia".

Myślę, że jest problem z tym założeniem. Średnia oznacza dominację sygnału większości. Ludzka wizja to (zdumiewający) procesor danych wizualnych i zwykle potrzeba dziesiątków lat ciężkiej pracy, aby maszyna znalazła się nawet w niewielkiej kolejności w tym, co robi. Jeśli nie możesz spojrzeć swoimi oczami na 90% otaczających cię osób i zmierzyć ich tętno, wówczas podejście uśredniające może nie być rozwiązaniem.

Istnieje nieskończona liczba statystyk, które można wykonać, aby sprawdzić, jak rozkład zmienia się w czasie, a średnia jest tylko jedną z nich. Jeśli spojrzysz tylko na średnią, może brakować informacji.

Jak to zrobić:

  1. chciałbym działać na ramki do ramki różnic.
  2. Większość kodeków wideo ma nierównomierny odstęp czasowy. Otrzymałbym te wartości, aby móc śledzić zmiany w stosunku do faktycznego (nie zakładanego) czasu. Twoje obecne (prawdopodobnie fałszywe) sygnały mogą pochodzić z CODEC, a także ze sprzętu.
  3. Zrobiłbym film taki, że każda nowa klatka jest różnicą między nim a poprzednią ramką. Oglądałem to 20 razy i sprawdzałem, czy mój (zdumiewający) ludzki system przetwarzania obrazu może widzieć cokolwiek wyraźnie związanego z biciem serca lub wyraźnie NIE.
  4. Dla "NIE" usuń je z przetwarzania, przez maskę, filtr lub inne. W celu znalezienia sposobu na ukształtowanie ich jako regionu zainteresowania: usunięcie wszystkich innych elementów, histogramu z obciętym pikselem pikseli lub inne ulepszenia obrazu (rozmycie, wyostrzenie, zmiana koloru, krawędź, obrót tak, aby największy sygnał jest wzdłuż zaktualizowanych osi pikseli a następnie proces ..)

pO urządzenie ludzki wzrok może uzyskać dobry sygnał, to chciałbym pracować na co matematyka/komputer dostać sygnał z czystej wiedzy, że aparatura ludzka jest lepszy.

Gdybym śledził punkty/funkcje, które poruszają się w czasie, sprawdziłbym metody metrologii subpikselowej. Zrobiłem to kilka lat temu (thesis) i chociaż myślę, że treść może być istotna, to może być na tyle różna, aby zasługiwać na pierwszy odczyt przed skopiowaniem i uruchomieniem kodu.

Powodzenia.

Powiązane problemy