loading
Hello. My name is Erdenebayar. I live in Mongolia. I made a hand motion detection via RGB camera, and control tetris's elements. I used to OpenCV programming. 
This is very simple... Enjoy

Step 1: Used Items...

- laptop
- web camera 

Step 2: Write OpenCV Code

#include "Game.h" //#include "OpenCV_source.h" #include #include #include #include #include #include #include #include #include #include //use OPenCV namespace using namespace std; using namespace cv; //dynamic control int lowerH=0; int lowerS=58; int lowerV=125; int upperH=180; int upperS=173; int upperV=229; void setwindowSettings(){ cvNamedWindow("Thresh"); //cvInRangeS(hsv, cvScalar(0, 58, 125), cvScalar(180, 173, 229), imgThreshed); cvCreateTrackbar("LowerH", "Thresh", &lowerH, 180, NULL); //cvSetTrackbarPos("LowerH", "Thresh", 50 ); cvCreateTrackbar("UpperH", "Thresh", &upperH, 180, NULL); //cvSetTrackbarPos("UpperH", "webcam", 150 ); cvCreateTrackbar("LowerS", "Thresh", &lowerS, 256, NULL); cvCreateTrackbar("UpperS", "Thresh", &upperS, 256, NULL); cvCreateTrackbar("LowerV", "Thresh", &lowerV, 256, NULL); cvCreateTrackbar("UpperV", "Thresh", &upperV, 256, NULL); } /* ================== Main ================== */ #ifndef LINUX int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) #else int main() #endif { IO mIO; int mScreenHeight = mIO.GetScreenHeight(); Pieces mPieces; Board mBoard (&mPieces, mScreenHeight); Game mGame (&mBoard, &mPieces, &mIO, mScreenHeight); unsigned long mTime1 = SDL_GetTicks(); ////OPenCV declaration-------------------------------------------------------------------- CvCapture* capture = 0; Mat frame, frameCopy, image; CvSeq* p_seqCircles; float* P_fitXYRadius ; IplImage *hsv, *hue, *sat, *val; IplImage* displayedImage = 0; int depth; CvSize size; CvMemStorage* storage = cvCreateMemStorage(0); setwindowSettings(); capture = cvCaptureFromCAM( 1 ); //0=default, -1=any camera, 1..99=your camera //capture = cvCaptureFromCAM( CV_CAP_ANY ); //0=default, -1=any camera, 1..99=your camera //if(!capture) cout << "No camera detected" << endl; cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH, 300 ); cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT, 200 ); assert(capture); // This is passed /////////////// /////////////// /////////////// //////read from camera if( !capture ){cout << "No camera detected" << endl;} cvNamedWindow( "result", CV_WINDOW_AUTOSIZE ); //create window cvNamedWindow( "hsv", CV_WINDOW_AUTOSIZE ); //create window cvNamedWindow( "Threshhold", CV_WINDOW_AUTOSIZE ); //create window // ----- Main Loop ------------------------------------------------------------------------while (!mIO.IsKeyDown (SDLK_ESCAPE)) //reset { //-----OpenCv camera-------------------------------------------------------------------IplImage* iplImg = cvQueryFrame( capture ); size = cvGetSize(iplImg); depth = iplImg->depth; IplImage* imgThreshed = cvCreateImage(cvGetSize(iplImg), 8, 1); frame = iplImg; cvShowImage( "result", iplImg ); hue = cvCreateImage(size, depth, 1); sat = cvCreateImage(size, depth, 1); val = cvCreateImage(size, depth, 1); hsv = cvCreateImage(size, depth, 3); cvZero(hue); cvZero(sat); cvZero(val); cvZero(hsv); if( frame.empty() ) break; ////line & CIRCLE //cvCircle(iplImg, cvPoint(160, 120), 60, cvScalar(0, 255, 0), 1, 4); //goliin toirog //cvRectangle(iplImg, cvPoint(115, 96), cvPoint(211, 158), cvScalar(0, 255, 0), 1, 4); //goliin tegsh untsugt //cvLine(iplImg, cvPoint(iplImg->origin, iplImg->origin ), cvPoint(115, 96), cvScalar(255,0,0), 1, 4); //zuun deed zuraas //cvLine(iplImg, cvPoint(200, 200 ), cvPoint(iplImg->origin, iplImg->origin), cvScalar(255,0,0), 1, 4); //baruun deed zuraas //cvLine(iplImg, cvPoint(200, 200 ), cvPoint(iplImg->origin, iplImg->origin), cvScalar(255,0,0), 1, 4); //zuun dood zuraas //cvLine(iplImg, cvPoint(200, 200 ), cvPoint(iplImg->origin, iplImg->origin), cvScalar(255,0,0), 1, 4); //baruun dood zuraas if( iplImg->origin == IPL_ORIGIN_TL ) { frame.copyTo( frameCopy ); cvCvtColor(iplImg, hsv, CV_BGR2HSV); cvSplit(hsv, hue, sat, val, 0); //split image //cvInRangeS(hsv, cvScalar(0, 58, 125), cvScalar(180, 173, 229), imgThreshed); cvInRangeS(hsv, cvScalar(lowerH,lowerS,lowerV) , cvScalar(upperH,upperS,upperV), imgThreshed); cvDilate(imgThreshed, imgThreshed, 0, 6); //ihesgeh cvErode(imgThreshed, imgThreshed,0, 10); //bagasgah cvSmooth(imgThreshed,imgThreshed,CV_GAUSSIAN,15,15); p_seqCircles = cvHoughCircles(imgThreshed, storage, CV_HOUGH_GRADIENT,2,imgThreshed->height/4,100,30,10,50 ); //////////////////////////// //p_seqCircles->total = 1; //////////////////////////// printf("circles == %d\n", p_seqCircles->total); int px, py; for(int i=0; itotal; i++ ) { P_fitXYRadius = (float*) cvGetSeqElem (p_seqCircles,i); cvCircle(iplImg,cvPoint (cvRound(P_fitXYRadius[0]) ,cvRound(P_fitXYRadius[1])) ,3,CV_RGB(255,0,0),CV_FILLED); cvCircle(iplImg,cvPoint(cvRound(P_fitXYRadius[0]),cvRound(P_fitXYRadius[1])) ,20,CV_RGB(255,0,0),3); cvCircle(imgThreshed,cvPoint(cvRound(P_fitXYRadius[0]),cvRound(P_fitXYRadius[1])) ,3,CV_RGB(251,80,80),CV_FILLED); cvCircle(imgThreshed,cvPoint(cvRound(P_fitXYRadius[0]),cvRound(P_fitXYRadius[1])) ,cvRound(P_fitXYRadius[2]),CV_RGB(250,80,80),3); px=cvRound(P_fitXYRadius[0]); py=cvRound(P_fitXYRadius[1]); printf("x == %d\n", px); printf("y == %d\n", py); } //cvCircle(iplImg,cvPoint(cvRound(P_fitXYRadius[0]), cvRound(P_fitXYRadius[1])) ,3,CV_RGB(255,0,0),CV_FILLED); //cvCircle(iplImg,cvPoint(cvRound(P_fitXYRadius[0]),cvRound(P_fitXYRadius[1])), cvRound(P_fitXYRadius[2]),CV_RGB(255,0,0),3); ///////////////////////////////////////////// /*for (int i = 0; i < p_seqCircles->total; i++) { float *p = (float*)cvGetSeqElem(p_seqCircles, i); CvPoint center = cvPoint(cvRound(p[0]),cvRound(p[1])); CvScalar val = cvGet2D(iplImg, center.y, center.x); if (val.val[0] < 1) continue; printf("%d %d %d\n", cvRound(p[0]),cvRound(p[1]), cvRound(p[2])); cvCircle(iplImg, center, cvRound(p[2]),CV_RGB(0,255,0), 1, CV_AA, 0); }*/ ///////////////////////////////////////////// } else flip( frame, frameCopy, 0 ); ///////////////////////////////////////////////// /////////////////////////////////////// cvShowImage( "result", iplImg ); cvShowImage( "hsv", hsv ); cvShowImage( "Threshhold", imgThreshed ); //if( waitKey( 10 ) >= 0 ) //break; //Tetris-------------------------------------------------------------------------------// ----- Draw ----mIO.ClearScreen (); // Clear screen mGame.DrawScene (); // mIO.UpdateScreen (); // // ----- Input -----int mKey = mIO.Pollkey(); switch (mKey) { case (SDLK_RIGHT): //baruun { if (mBoard.IsPossibleMovement (mGame.mPosX + 1, mGame.mPosY, mGame.mPiece, mGame.mRotation)) mGame.mPosX++; break; } case (SDLK_LEFT): //zuun { if (mBoard.IsPossibleMovement (mGame.mPosX - 1, mGame.mPosY, mGame.mPiece, mGame.mRotation)) mGame.mPosX--; break; } case (SDLK_DOWN): //doosh { if (mBoard.IsPossibleMovement (mGame.mPosX, mGame.mPosY + 1, mGame.mPiece, mGame.mRotation)) mGame.mPosY++; break; } case (SDLK_SPACE): //pad doosh { while (mBoard.IsPossibleMovement(mGame.mPosX, mGame.mPosY, mGame.mPiece, mGame.mRotation)) { mGame.mPosY++;); mBoard.StorePiece (mGame.mPosX, mGame.mPosY - 1, mGame.mPiece, mGame.mRotation); mBoard.DeletePossibleLines (); if (mBoard.IsGameOver()) { mIO.Getkey(); exit(0); } mGame.CreateNewPiece(); break; } case (SDLK_UP): { if (mBoard.IsPossibleMovement (mGame.mPosX, mGame.mPosY, mGame.mPiece, (mGame.mRotation + 1) % 4)) mGame.mRotation = (mGame.mRotation + 1) % 4; break; } } unsigned long mTime2 = SDL_GetTicks(); if ((mTime2 - mTime1) > WAIT_TIME) { if (mBoard.IsPossibleMovement (mGame.mPosX, mGame.mPosY + 1, mGame.mPiece, mGame.mRotation)) { mGame.mPosY++; } else { mBoard.StorePiece (mGame.mPosX, mGame.mPosY, mGame.mPiece, mGame.mRotation); mBoard.DeletePossibleLines (); if (mBoard.IsGameOver()) { mIO.Getkey(); exit(0); } mGame.CreateNewPiece(); } mTime1 = SDL_GetTicks(); } } return 0; }#include "Game.h" //#include "OpenCV_source.h" #include #include #include #include #include #include #include #include #include #include //use OPenCV namespace using namespace std; using namespace cv; //dynamic control int lowerH=0; int lowerS=58; int lowerV=125; int upperH=180; int upperS=173; int upperV=229; void setwindowSettings(){ cvNamedWindow("Thresh"); //cvInRangeS(hsv, cvScalar(0, 58, 125), cvScalar(180, 173, 229), imgThreshed); cvCreateTrackbar("LowerH", "Thresh", &lowerH, 180, NULL); //cvSetTrackbarPos("LowerH", "Thresh", 50 ); cvCreateTrackbar("UpperH", "Thresh", &upperH, 180, NULL); //cvSetTrackbarPos("UpperH", "webcam", 150 ); cvCreateTrackbar("LowerS", "Thresh", &lowerS, 256, NULL); cvCreateTrackbar("UpperS", "Thresh", &upperS, 256, NULL); cvCreateTrackbar("LowerV", "Thresh", &lowerV, 256, NULL); cvCreateTrackbar("UpperV", "Thresh", &upperV, 256, NULL); } /* ================== Main ================== */ #ifndef LINUX int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) #else int main() #endif { IO mIO; int mScreenHeight = mIO.GetScreenHeight(); Pieces mPieces; Board mBoard (&mPieces, mScreenHeight); Game mGame (&mBoard, &mPieces, &mIO, mScreenHeight); unsigned long mTime1 = SDL_GetTicks(); ////OPenCV declaration-------------------------------------------------------------------- CvCapture* capture = 0; Mat frame, frameCopy, image; CvSeq* p_seqCircles; float* P_fitXYRadius ; IplImage *hsv, *hue, *sat, *val; IplImage* displayedImage = 0; int depth; CvSize size; CvMemStorage* storage = cvCreateMemStorage(0); setwindowSettings(); capture = cvCaptureFromCAM( 1 ); //0=default, -1=any camera, 1..99=your camera //capture = cvCaptureFromCAM( CV_CAP_ANY ); //0=default, -1=any camera, 1..99=your camera //if(!capture) cout << "No camera detected" << endl; cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH, 300 ); cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT, 200 ); assert(capture); // This is passed /////////////// /////////////// /////////////// //////read from camera if( !capture ){cout << "No camera detected" << endl;} cvNamedWindow( "result", CV_WINDOW_AUTOSIZE ); //create window cvNamedWindow( "hsv", CV_WINDOW_AUTOSIZE ); //create window cvNamedWindow( "Threshhold", CV_WINDOW_AUTOSIZE ); //create window // ----- Main Loop ------------------------------------------------------------------------while (!mIO.IsKeyDown (SDLK_ESCAPE)) //reset { //-----OpenCv camera-------------------------------------------------------------------IplImage* iplImg = cvQueryFrame( capture ); size = cvGetSize(iplImg); depth = iplImg->depth; IplImage* imgThreshed = cvCreateImage(cvGetSize(iplImg), 8, 1); frame = iplImg; cvShowImage( "result", iplImg ); hue = cvCreateImage(size, depth, 1); sat = cvCreateImage(size, depth, 1); val = cvCreateImage(size, depth, 1); hsv = cvCreateImage(size, depth, 3); cvZero(hue); cvZero(sat); cvZero(val); cvZero(hsv); if( frame.empty() ) break; ////line & CIRCLE //cvCircle(iplImg, cvPoint(160, 120), 60, cvScalar(0, 255, 0), 1, 4); //goliin toirog //cvRectangle(iplImg, cvPoint(115, 96), cvPoint(211, 158), cvScalar(0, 255, 0), 1, 4); //goliin tegsh untsugt //cvLine(iplImg, cvPoint(iplImg->origin, iplImg->origin ), cvPoint(115, 96), cvScalar(255,0,0), 1, 4); //zuun deed zuraas //cvLine(iplImg, cvPoint(200, 200 ), cvPoint(iplImg->origin, iplImg->origin), cvScalar(255,0,0), 1, 4); //baruun deed zuraas //cvLine(iplImg, cvPoint(200, 200 ), cvPoint(iplImg->origin, iplImg->origin), cvScalar(255,0,0), 1, 4); //zuun dood zuraas //cvLine(iplImg, cvPoint(200, 200 ), cvPoint(iplImg->origin, iplImg->origin), cvScalar(255,0,0), 1, 4); //baruun dood zuraas if( iplImg->origin == IPL_ORIGIN_TL ) { frame.copyTo( frameCopy ); cvCvtColor(iplImg, hsv, CV_BGR2HSV); cvSplit(hsv, hue, sat, val, 0); //split image //cvInRangeS(hsv, cvScalar(0, 58, 125), cvScalar(180, 173, 229), imgThreshed); cvInRangeS(hsv, cvScalar(lowerH,lowerS,lowerV) , cvScalar(upperH,upperS,upperV), imgThreshed); cvDilate(imgThreshed, imgThreshed, 0, 6); //ihesgeh cvErode(imgThreshed, imgThreshed,0, 10); //bagasgah cvSmooth(imgThreshed,imgThreshed,CV_GAUSSIAN,15,15); p_seqCircles = cvHoughCircles(imgThreshed, storage, CV_HOUGH_GRADIENT,2,imgThreshed->height/4,100,30,10,50 ); //////////////////////////// //p_seqCircles->total = 1; //////////////////////////// printf("circles == %d\n", p_seqCircles->total); int px, py; for(int i=0; itotal; i++ ) { P_fitXYRadius = (float*) cvGetSeqElem (p_seqCircles,i); cvCircle(iplImg,cvPoint (cvRound(P_fitXYRadius[0]) ,cvRound(P_fitXYRadius[1])) ,3,CV_RGB(255,0,0),CV_FILLED); cvCircle(iplImg,cvPoint(cvRound(P_fitXYRadius[0]),cvRound(P_fitXYRadius[1])) ,20,CV_RGB(255,0,0),3); cvCircle(imgThreshed,cvPoint(cvRound(P_fitXYRadius[0]),cvRound(P_fitXYRadius[1])) ,3,CV_RGB(251,80,80),CV_FILLED); cvCircle(imgThreshed,cvPoint(cvRound(P_fitXYRadius[0]),cvRound(P_fitXYRadius[1])) ,cvRound(P_fitXYRadius[2]),CV_RGB(250,80,80),3); px=cvRound(P_fitXYRadius[0]); py=cvRound(P_fitXYRadius[1]); printf("x == %d\n", px); printf("y == %d\n", py); } //cvCircle(iplImg,cvPoint(cvRound(P_fitXYRadius[0]), cvRound(P_fitXYRadius[1])) ,3,CV_RGB(255,0,0),CV_FILLED); //cvCircle(iplImg,cvPoint(cvRound(P_fitXYRadius[0]),cvRound(P_fitXYRadius[1])), cvRound(P_fitXYRadius[2]),CV_RGB(255,0,0),3); ///////////////////////////////////////////// /*for (int i = 0; i < p_seqCircles->total; i++) { float *p = (float*)cvGetSeqElem(p_seqCircles, i); CvPoint center = cvPoint(cvRound(p[0]),cvRound(p[1])); CvScalar val = cvGet2D(iplImg, center.y, center.x); if (val.val[0] < 1) continue; printf("%d %d %d\n", cvRound(p[0]),cvRound(p[1]), cvRound(p[2])); cvCircle(iplImg, center, cvRound(p[2]),CV_RGB(0,255,0), 1, CV_AA, 0); }*/ ///////////////////////////////////////////// } else flip( frame, frameCopy, 0 ); ///////////////////////////////////////////////// /////////////////////////////////////// cvShowImage( "result", iplImg ); cvShowImage( "hsv", hsv ); cvShowImage( "Threshhold", imgThreshed ); //if( waitKey( 10 ) >= 0 ) //break; //Tetris-------------------------------------------------------------------------------// ----- Draw ----mIO.ClearScreen (); // Clear screen mGame.DrawScene (); // mIO.UpdateScreen (); // // ----- Input -----int mKey = mIO.Pollkey(); switch (mKey) { case (SDLK_RIGHT): //baruun { if (mBoard.IsPossibleMovement (mGame.mPosX + 1, mGame.mPosY, mGame.mPiece, mGame.mRotation)) mGame.mPosX++; break; } case (SDLK_LEFT): //zuun { if (mBoard.IsPossibleMovement (mGame.mPosX - 1, mGame.mPosY, mGame.mPiece, mGame.mRotation)) mGame.mPosX--; break; } case (SDLK_DOWN): //doosh { if (mBoard.IsPossibleMovement (mGame.mPosX, mGame.mPosY + 1, mGame.mPiece, mGame.mRotation)) mGame.mPosY++; break; } case (SDLK_SPACE): //pad doosh { while (mBoard.IsPossibleMovement(mGame.mPosX, mGame.mPosY, mGame.mPiece, mGame.mRotation)) { mGame.mPosY++;); mBoard.StorePiece (mGame.mPosX, mGame.mPosY - 1, mGame.mPiece, mGame.mRotation); mBoard.DeletePossibleLines (); if (mBoard.IsGameOver()) { mIO.Getkey(); exit(0); } mGame.CreateNewPiece(); break; } case (SDLK_UP): { if (mBoard.IsPossibleMovement (mGame.mPosX, mGame.mPosY, mGame.mPiece, (mGame.mRotation + 1) % 4)) mGame.mRotation = (mGame.mRotation + 1) % 4; break; } } unsigned long mTime2 = SDL_GetTicks(); if ((mTime2 - mTime1) > WAIT_TIME) { if (mBoard.IsPossibleMovement (mGame.mPosX, mGame.mPosY + 1, mGame.mPiece, mGame.mRotation)) { mGame.mPosY++; } else { mBoard.StorePiece (mGame.mPosX, mGame.mPosY, mGame.mPiece, mGame.mRotation); mBoard.DeletePossibleLines (); if (mBoard.IsGameOver()) { mIO.Getkey(); exit(0); } mGame.CreateNewPiece(); } mTime1 = SDL_GetTicks(); } } return 0; }

Step 3: Calibre for Light and Background

calibre image threshhold using "changer"

Step 4: Working...

http://youtu.be/byS0B8yZOqc
Keep it simple!!!!'

About This Instructable

3,235views

13favorites

License:

More by mr_erdenebayar:play tetris games using hand motion via RGB camera 
Add instructable to: