2010-06-04 12 views
18

Próbuję znaleźć/zaimplementować funkcję wyszukiwania i przewijania (dla wideo (.avi)) przy użyciu OpenCV w C++, ale nie mogę znaleźć sposobu na to, poza przechodzeniem przez cały plik raz i zapisanie każdego obrazu. Czy jest jakiś inny sposób?OpenCV Seek Funkcja/Rewind

Każda pomoc byłaby mile widziana; Dzięki z góry!

+1

Przy okazji, podobnie jak wskazówka, szukanie OpenCV nie działa prawidłowo na flv, jeśli utkniesz w dowolnym momencie, gdy szukanie nie działa. Zajęło mi dzień, aby to rozgryźć !!! –

Odpowiedz

37

Za pomocą cvSetCaptureProperty() możesz przełączać się między ramkami, w milisekundach lub w liczbie porządkowej.

int cvSetCaptureProperty(CvCapture* capture, int property_id, double value); 

property_id jest nieruchomość trzeba by użyć. To może być jeden z następujących:

  1. CV_CAP_PROP_POS_MSEC - pozycja w milisekundach z pliku zaczynając
  2. CV_CAP_PROP_POS_FRAMES - pozycja w ramkach
  3. CV_CAP_PROP_POS_AVI_RATIO - pozycja w jednostkach względnych (0 - początek plik, 1 - koniec pliku)
  4. CV_CAP_PROP_FRAME_WIDTH - szerokość klatek w strumieniu wideo (tylko dla kamer)
  5. CV_CAP_PROP_FRAME_HEIGHT - hei GHT ramki w strumieniu wideo (tylko dla kamer)
  6. CV_CAP_PROP_FPS - szybkość klatek (tylko dla kamer)
  7. CV_CAP_PROP_FOURCC - kod 4 postać kodera (tylko dla aparatów).

Pierwsze dwa są w Twoim interesie.

EDIT: więcej informacji :)

Można przechodzić klatek po prostu wielokrotnie nazywając wspomnianą funkcję z różnych indeksów ramy.

cvSetCaptureProperty(capture, CV_CAP_PROP_POS_FRAMES, frameIndex); 

Przykład:

IplImage* frame; 
CvCapture* capture = cvCreateFileCapture("test.avi"); 

/* iterate through first 10 frames */ 
for (int i = 0; i < 10; i++) 
{ 
    /* set pointer to frame index i */ 
    cvSetCaptureProperty(capture, CV_CAP_POS_FRAMES, i); 

    /* capture the frame and do sth with it */ 
    frame = cvQueryFrame(capture); 
} 

Można umieścić podobny kod do wykonania każdy użytkownik kliknie przycisk czas do przodu/do tyłu wideo.

Metoda C++ (OpenCV 2 i wyżej) będzie używać tej metody zamiast tego samego property_id i value.

bool VideoCapture::set(int property_id, double value) 
+0

Dowolne przykłady? Powiedzmy, że jeśli mam plik .avi, w jaki sposób mogę go użyć do przejścia przez ramki? – Cenoc

+0

Dzięki za wskaźnik przy okazji. – Cenoc

+0

Zmieniono moją odpowiedź. – Adi

0

W bibliotece highgui znajdują się funkcje paska wyszukiwania (cvCreateTrackbar i przyjaciele).

+0

sposób, w jaki to opisano, nie brzmi jak pasek wyszukiwania; brzmi to jak zwykły trackbar. Ponadto każdy przykład, który znalazłem w Internecie, wykorzystał go do innych losowych shizów, takich jak zmiana odcienia obrazu. – Cenoc

+0

Możesz podpiąć pasek śledzenia do dowolnej zmiennej/zdarzenia, które chcesz - w tym pozycji pliku. Musisz wykonać littl emore, niż wbudowany pasek wyszukiwania, ale jest tam –

1

Myślę, że musiałbyś przeczytać cały plik w tablicy IplImages, a następnie przejść przez to. Powodem jest, że cvQueryFrame jest procesem jednokierunkowym, czyta jedną klatkę na raz w kolejności. Nie mogę wymyślić innego sposobu. W zależności od długości filmu czas inicjalizacji może nie być zły.

Paski cvTrack są takie, jak mówisz, używane głównie do zmiany parametrów. Zmieniają wartość zmiennej (podanej jako parametr w formie wskaźnika) i wywołują funkcję zwrotną. Niestety są to jedyne elementy w stylu HighGUI, o ile wiem, że o ile wiem, to:

+0

Wow, wielkie dzięki. Zgadnij, że to dla mnie zawęża; Myślałem, że tak być może. Chyba muszę przestać być leniwym i to zrobić. – Cenoc