OpenCV i OpenGL

0

Witajcie!
Ostatnio zacząłem pewien projekt związany z prostym przechwytywaniem ruchu z wykorzystaniem bibliotek OpenCV i OpenGL. Program ma wyglądać mniej więcej tak, że będą wyświetlone 2 okna: okno stworzone za pomocą funkcji imShow() z obrazem z kamery oraz drugie stworzone za pomocą glutCreateWindow() z narysowaną kulą, która będzie przemieszczana za pomocą ruchu. Problem mam taki, że wyświetla sięjedno, albo drugie. Jak wywołuję jako pierwszą funkcję z oknem stworzonym w OpenCV to widać obraz z kamery, a jak najpierw wywołam funkcję z OpenGl to widzę to co jest tam narysowane i nie uruchamia się kamera. Jest to mój pierwszy projekt tego typu, dlatego nie mam w tym temacie doświadczenia. Kod wygląda tak:

int Test( int argc, char ** argv )
{
    VideoCapture cap( 0 ); // Uruchomienie kamery 0 (domyślna)

    TermCriteria termcrit( TermCriteria::COUNT | TermCriteria::EPS, 20, 0.03 );
    Size subPixWinSize( 10, 10 ), winSize( 31, 31 );

    const int MAX_COUNT = 500;
    bool needToInit = false;
    bool nightMode = false;

    if( argc == 1 ||( argc == 2 && strlen( argv[ 1 ] ) == 1 && isdigit( argv[ 1 ][ 0 ] ) ) )
         cap.open( argc == 2 ? argv[ 1 ][ 0 ] - '0'
        : 0 );
    else if( argc == 2 )
         cap.open( argv[ 1 ] );

    if( !cap.isOpened() ) // Sprawdzenie poprawności otwarcia
         return - 1;

    namedWindow( "LK Demo", 1 );

    setMouseCallback( "LK Demo", onMouse, 0 );

    Mat gray, prevGray, image;
    vector < Point2f > points[ 2 ];

    for(;; )
    {
        Mat frame;
        cap >> frame; // get a new frame from camera
        //cvtColor(frame, image,COLOR_BGR2HSV);
        //cvtColor(frame1, edges1, COLOR_RGB2GRAY);
        //GaussianBlur(edges, edges, Size(7,7), 1.5, 1.5);
        //Canny(edges, edges, 100, 30, 3); //Wykrywanie krawędzi
        //imshow("Kamera 1", image);
        //if(waitKey(30) >= 0) break;

        frame.copyTo( image );
        cvtColor( image, gray, COLOR_BGR2GRAY );

        if( nightMode )
             image = Scalar::all( 0 );

        if( needToInit )
        {
            // automatic initialization
            goodFeaturesToTrack( gray, points[ 1 ], MAX_COUNT, 0.01, 10, Mat(), 3, 0, 0.04 );
            cornerSubPix( gray, points[ 1 ], subPixWinSize, Size( - 1, - 1 ), termcrit );
            addRemovePt = false;
        }
        else if( !points[ 0 ].empty() )
        {
            vector < uchar > status;
            vector < float > err;
            if( prevGray.empty() )
                 gray.copyTo( prevGray );

            calcOpticalFlowPyrLK( prevGray, gray, points[ 0 ], points[ 1 ], status, err, winSize,
            3, termcrit, 0, 0.001 );
            size_t i, k;
            for( i = k = 0; i < points[ 1 ].size(); i++ )
            {
                if( addRemovePt )
                {
                    if( norm( point - points[ 1 ][ i ] ) <= 5 )
                    {
                        addRemovePt = false;
                        continue;
                    }
                }

                if( !status[ i ] )
                     continue;

                points[ 1 ][ k++ ] = points[ 1 ][ i ];
                circle( image, points[ 1 ][ i ], 3, Scalar( 0, 255, 0 ), - 1, 8 );
            }
            points[ 1 ].resize( k );
        }

        if( addRemovePt && points[ 1 ].size() <( size_t ) MAX_COUNT )
        {
            vector < Point2f > tmp;
            tmp.push_back( point );
            cornerSubPix( gray, tmp, winSize, Size( - 1, - 1 ), termcrit );
            points[ 1 ].push_back( tmp[ 0 ] );
            addRemovePt = false;
        }

        needToInit = false;
        imshow( "LK Demo", image );

        char c =( char ) waitKey( 10 );
        if( c == 27 )
             break;

        switch( c )
        {
        case 'r':
            needToInit = true;
            break;
        case 'c':
            points[ 0 ].clear();
            points[ 1 ].clear();
            break;
        case 'n':
            nightMode = !nightMode;
            break;
        }

        std::swap( points[ 1 ], points[ 0 ] );
        cv::swap( prevGray, gray );
    }
    return 0;
}

//OpenGL
void display()
{
    glClear( GL_COLOR_BUFFER_BIT );

    glBegin( GL_POLYGON );
    glColor3f( 1, 0, 0 ); glVertex3f( - 0.6, - 0.75, 0.5 );
    glColor3f( 0, 1, 0 ); glVertex3f( 0.6, - 0.75, 0 );
    glColor3f( 0, 0, 1 ); glVertex3f( 0, 0.75, 0 );
    glEnd();

    glFlush();
}

void Test2( int argc, char ** argv )
{
    glutInit( & argc, argv );
    glutInitDisplayMode( GLUT_SINGLE | GLUT_RGB );

    glutInitWindowPosition( 80, 80 );
    glutInitWindowSize( 400, 300 );
    glutCreateWindow( "OGL" );

    glutDisplayFunc( display );

    glutMainLoop();
}

int main( int argc, char ** argv )
{
    Test2( argc, argv );
    Test( argc, argv );

    return 0;
}

Aktualnie jako pierwsza jest wywoływana fukcja Test2() i dlatego widać narysowany przykładowy trójkąt w OpenGL, a okno z widokiem z kamery już się nie uruchamia. Mógłby mi ktoś wytłumaczyć co się dzieje i co robię źle? ;) Zpewne chodzi o tą nieskończoną pętlę, ale nie wiem jak rozwiązać ten problem....

0
glutMainLoop();

Ta funkcja trwa aż do zamknięcia okna.
Gdyby tak nie było, funkcja main by się od razu skończyła, i program by zakończył pracę.

Również to jest z zasady problematyczne:

for(;; )
{
. 
.
.
char c =( char ) waitKey( 10 );
. 
.
.
}

Program ma według ciebie w nieskończonej pętli czekać na klawisz. A kiedy miałby się zajmować choćby rysowaniem grafiki? :-)

Program okienkowy nie różni się pod tym względem od konsolowego: wszystko w ramach jednego wątka wykonuje się po kolei. Jeśli umieścisz w nim nieskończoną pętlę, to wpadnie w nieskończoną pętlę i program się zawiesi.

W treści posta zupełnie pomijasz fakt, że używasz biblioteki GLUT (FreeGLUT?). To biblioteka pomocnicza dla OpenGL, ale nie jest częścią OpenGL.
Nie wiem czy FreeGLUT w ogóle obsługuje wielookienkowość. Jeżeli nie, zostaje ci tworzenie okna np. przez WinAPI i właściwą obsługę komunikatów. Na pewno da się to zrobić.

0

Masz rację zapomniałem napisać o bibliotece GLUT.
Program z założenia ma wyglądać tak, że dane z okna OpenCV (śledzenie punktu) mają być przenoszone i wyświetlane w oknie OpenGL. Słownie wydawało się to proste, ale z tego wynika, że jużtakie nie jest ...

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0