Autor Wątek: biblioteka do pobierania klatki filmu i nakładania na to innego obrazka  (Przeczytany 3794 razy)

Offline slowbro

  • Użytkownik

# Czerwiec 12, 2016, 23:46:42
Witam wszystkich

Jaką bibliotekę polecilibyście do odtwarzania filmu avi (nie będzie to player do odtwarzania filmów) tak, aby można było na pobraną klatkę filmu nakładać jeszcze jakiś obrazek zdefiniowany np. jako JPG czy PNG i taki obraz wyświetlić na ekranie?

Znalazłem coś takiego na tutorialach NEHE, ale nie do końca odpowiada mi to, ponieważ nie umożliwia nakładania na klatkę filmu innego obrazka i wyświetlenie tego na razem na ekranie.

Pozdrawiam

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline FrozenShade

  • Użytkownik
    • Skullstone's official site

# Czerwiec 13, 2016, 09:27:13
Bibliotekę dla jakiego języka?

Cytuj
nie do końca odpowiada mi to, ponieważ nie umożliwia nakładania na klatkę filmu innego obrazka i wyświetlenie tego na razem na ekranie

A w jaki sposób miała by to umożliwić? Dostałeś klatkę, dalsza obróbka należy do ciebie.

Przykładowo - Player z JavaFX generuje eventy z klatkami, każda w formacie YCbCr, dostajesz po prostu bufor z kawałkiem pamięci. I jest to normalne, jeśli chcesz coś dalej z tym zrobić to jedziesz po tym buforze, czytasz, np konwertujesz sobie na RGB, malujesz coś na tym, wysyłasz do GPU albo malujesz na Formie. Albo czysty YCrCb wysyłasz do szadera, podajesz na jego wejście jeszcze jedną teksturę i wszystko sobie malujesz tam.

Niestety, nie podałeś żadnych szczegółów na temat tego, co chcesz zrobić.

Offline Xenox93

  • Użytkownik

# Czerwiec 13, 2016, 14:41:22
FrozenShade ma rację, nie ma innej możliwości uzyskania tego co chcesz niż shader i przetwarzanie danych wejściowych( czyt. klatka/zdjęcie ) w Pixel/Fragment shader ;)

Ostatecznie możesz wspomóc się efektem stosowanym w post-processing'u, tzn. rysowanie full-screen quad'a itp. Zależy co chcesz osiągnąć i jak ^^

Ogólnie twoje rozwiązanie przypomina mi nakładanie znaku wodnego, który używa się choćby w TV ( logo kanału telewizyjnego ) w lewym/prawym górnym rogu.

Ostatecznie jak chcesz utrwalić efekt swojej pracy, to możesz zapisać jako plik wideo.

Offline slowbro

  • Użytkownik

# Czerwiec 14, 2016, 19:56:10
Już doprecyzowuje. Chodzi o bibliotekę do C++, którą można wykorzystać obok OpenGL. Chce zrobić coś takiego jak w demku Channel 88/Fuse https://www.youtube.com/watch?v=KMUugXmectc Większość demka to wyświetlany film z nakładanymi jakimiś obrazkami jak np. informacja o autorach. Nie potrzebuje zapisywać do pliku video, tylko odtwarzać go:)

Znalazłem bibliotekę OpenCV i jej specyfikacja wygląda obiecująco:)

Offline Durson

  • Użytkownik

# Czerwiec 14, 2016, 20:27:13
Nie polecam openCv, może w nowych wersjach coś się poprawiło, ale ostatnim razem jak korzystałem była fatalna dokumentacja i samo api też nie najprzyjemniejsze. Na twoim miejscu wziąłbym jakąś bibliotekę, która nie jest totalnym bloatem, tylko robi dokładnie to co chcesz. Spójrz może na ffmpeg.

Offline FrozenShade

  • Użytkownik
    • Skullstone's official site

# Czerwiec 14, 2016, 22:48:16
Wyświetlaj czysty film na obiekcie położonym na całym ekranie. Na to połóż (jako nowe obiekty z teksturą) jakieś prostokąty z wyrysowaną grafiką/tekstem.

Tak właśnie robimy w Skullstone (szkic):


Tło i ghul to video odtwarzane z pliku za pomocą playera, klatki są zrzucane do tekstur pełnoekranowego prostokąta a tam w szaderze rozkodowywany z YCbCr.
Napis 'Skullstone" i opcje menu to osobne obiekty ze swoimi własnymi teksturami.

To chyba efekt, który chciałeś osiągnąć ;)

Offline slowbro

  • Użytkownik

# Czerwiec 14, 2016, 23:23:08
@FrozenShade: Jaka biblioteka używana jest od odtwarzania filmu z pliku?

Offline FrozenShade

  • Użytkownik
    • Skullstone's official site

# Czerwiec 15, 2016, 01:28:32
@slowbro: nie znam takich bibliotek do c++ bo nie piszę w tym języku. Skullstone jest pisany w Javie, używam zwykłego playera z JavaFX.
Ja jedynie chciałem Ci zwrócić uwagę, że wcale nie musisz sobie komplikować życia i malować po klatkach wyciąganych z filmu. Weź dowolna bibliotekę, którą uda ci się obsłużyć i za pomocą której wyświetlisz video.
« Ostatnia zmiana: Czerwiec 15, 2016, 01:32:33 wysłana przez FrozenShade »

Offline Interceptor

  • Użytkownik

# Czerwiec 15, 2016, 22:08:48
@slowbro: używałem kodu z nehe do pobierania klatki filmu, dalej już wiele różnych postprocessingów. Całość sprawdziła się świetnie w dużym korporacyjnym projekcie tak że polecam tą metodę.

Offline slowbro

  • Użytkownik

# Czerwiec 18, 2016, 10:12:53
Dziękuje wszystkim za wskazówki:)

Offline slowbro

  • Użytkownik

# Czerwiec 20, 2016, 01:09:32
Witam

Pisze program do wyświetlania AVI w OpenGL na podstawie tutorialu Nehe http://nehe.gamedev.net/tutorial/playing_avi_files_in_opengl/23001/ Dodałem małą obsługę błędów na własny użytek. Przy próbie uruchomienia programu pojawia się komunikat w związku z funkcją ShowWindow. W przypadku funkcji ShowWindow(hWnd,SW_SHOW) przekazuje do niej jako argument uchwyt do okna i pokazuje się komunikat "Can't show the window" pomimo tego, że we wcześniej w kodzie jest tworzenie uchwytu do okna i nie jest sygnalizowany błąd w jego tworzeniu:

Oto część kodu dotycząca utworzenia okna:
// Create The Window
if (!(hWnd=CreateWindowEx( dwExStyle, // Extended Style For The Window
"OpenGL", // Class Name
title, // Window Title
dwStyle | // Defined Window Style
WS_CLIPSIBLINGS | // Required Window Style
WS_CLIPCHILDREN, // Required Window Style
0, 0, // Window Position
WindowRect.right-WindowRect.left, // Calculate Window Width
WindowRect.bottom-WindowRect.top, // Calculate Window Height
NULL, // No Parent Window
NULL, // No Menu
hInstance, // Instance
NULL))) // Dont Pass Anything To WM_CREATE
{
KillGLWindow(); // Reset The Display
MessageBox(NULL,"Window Creation Error.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
oraz dalsza część kodu dotycząca ShowWindow oraz SetForegroundWindow:
if(!ShowWindow(hWnd,SW_SHOW)) // Show The Window
{
MessageBox(NULL,"Can't show the window","ERROR",MB_OK|MB_ICONEXCLAMATION);
}

if(!SetForegroundWindow(hWnd)) // Slightly Higher Priority
{
MessageBox(NULL,"Can't set foreground window","ERROR",MB_OK|MB_ICONEXCLAMATION);
}

Offline karol57

  • Użytkownik

  • +1
# Czerwiec 20, 2016, 14:06:34
!ShowWindow(...) zwraca true, gdy okno było wcześniej ukryte i się pokazało, a false gdy było pokazane i funkcja nic nie zrobiła.

Następnym razem najpierw przeczytaj dokumentację.
ShowWindow [...]
Return value
Type: BOOL
If the window was previously visible, the return value is nonzero.
If the window was previously hidden, the return value is zero.

EDIT: Przeczytaj https://msdn.microsoft.com/pl-pl/library/windows/desktop/ms633539(v=vs.85).aspx, bo zaraz wrócisz z kolejnym pytaniem.

EDIT2: Jeżeli dodajesz własną obsługę błędów to przyzwyczaj się, że w WinAPI różne funkcje mogą różnie sygnalizować błędy, więc musisz czytać dokumentację. Przydatna może być funkcja GetLastError, która pozwoli ci na szybsze znalezienie przyczyny błędu (tutaj masz listę wszystkich błędów). I czytaj dokumentacje, bo nie każda funkcja sygnalizuje błąd (jak teraz zauważyłeś).
« Ostatnia zmiana: Czerwiec 20, 2016, 14:13:02 wysłana przez karol57 »

Offline slowbro

  • Użytkownik

# Czerwiec 25, 2016, 12:54:42
@karol57: dzięki za sugestie, na pewno z nich skorzystam:)

Posuwając się dalej z tematem udało się na podstawie tutoriala NEHE wyświetlić na kwadracie klatki pobierane z filmu AVI. Wszystko działa poprawnie w tym zakresie. Dalej zależy mi, aby na drugim  kwadracie wyświetlić inna teksturę. Do pobierania pliku graficznego w formacie PNG dla tej tekstury wykorzystuje bibliotekę SOIL.  Napisałem kod na podstawie informacji dostępnych na internecie. Nie wiem gdzie jest błąd w kodzie, ale na ekranie pokazują się dwa kwadraty tyle, że na pierwszym i drugim pokazuje się klatki pobrane z filmu AVI. Zamysł jest taki, że tekstura pobrana z pliku PNG ma pojawić się na kwadracie na pierwszym planie (od użytkownika), a klatki z filmu na kwadracie na drugim planie. Oto link do ekranu ilustrującym zagadnienie https://zapodaj.net/3c72479b0d9bd.png.html Gdzie tkwi błąd, czego szukać?

Oto kod najważniejszych fragmenty kodu:
int LoadGLTextures()                       
{   
    texture[0] = SOIL_load_OGL_texture
        (
        "Data/1.png",
        SOIL_LOAD_AUTO,
        SOIL_CREATE_NEW_ID,
        SOIL_FLAG_INVERT_Y
        );
 
    if(texture[0] == 0)
return false;
 
 // Typical Texture Generation Using Data From The Bitmap
 //   glBindTexture(GL_TEXTURE_2D, texture[0]);
 //   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
 //   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
 
    return true;                                        // Return Success
}
Load GLTextures jest wywoływane w części inicjującej kodu. Oto najważniejsze fragmenty tej części:

glEnable(GL_TEXTURE_2D);
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);


OpenAVI("data/face2.avi");
 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 256, 256, 0, GL_RGB, GL_UNSIGNED_BYTE, data);

I dalej fragment wyświetlający scenę:

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer

GrabAVIFrame(frame); // Grab A Frame From The AVI

glLoadIdentity();
glTranslatef(0.0f,0.0f,-5.0f);
 
// na quada nakladamy klatke filmu z AVI
glBegin(GL_QUADS);               
        // Front Face
        glTexCoord2f(1.0f, 1.0f); glVertex3f( 11.0f,  8.3f, -20.0f);
        glTexCoord2f(0.0f, 1.0f); glVertex3f(-11.0f,  8.3f, -20.0f);
        glTexCoord2f(0.0f, 0.0f); glVertex3f(-11.0f, -8.3f, -20.0f);
        glTexCoord2f(1.0f, 0.0f); glVertex3f( 11.0f, -8.3f, -20.0f);
    glEnd();                        // Done Drawing The Background

// na klada nakladmy teksture pobrana z pliku PNG
glBindTexture(GL_TEXTURE_2D, texture[0]);
glBegin(GL_QUADS);
// Front Face
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);
glEnd();






« Ostatnia zmiana: Czerwiec 25, 2016, 12:56:43 wysłana przez slowbro »

Offline Kos

  • Użytkownik
    • kos.gd

# Czerwiec 25, 2016, 12:59:56
Pewnie nie robisz glBindTexture przed GrabAVIFrame i nadpisujesz sobie tę teksturę z PNG klatkami z filmu. Klasyczny problem ze starym OpenGL - mnóstwo stanu globalnego. :(

A w ogóle to skąd wytrzasnąłeś glTexCoord2f i glVertex3f? To są straszne openglowe archaizmy. Teraz się robi tablicę ze współrzędnymi, wysyła na GPU i rysuje "całą na raz". https://www.opengl.org/wiki/Vertex_Specification

Offline slowbro

  • Użytkownik

# Czerwiec 25, 2016, 13:41:24
Kos: W całym tutorialu NEHE dotyczącym AVI nie ma w kodzie wykorzystania glBindTexture. Tekstura na podstawie klatki filmu pobranej a AVI jest tworzona za pomocą glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 256, 256, 0, GL_RGB, GL_UNSIGNED_BYTE, data)
« Ostatnia zmiana: Czerwiec 25, 2016, 13:44:48 wysłana przez slowbro »