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