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....