千家信息网

如何使用C++中的OpenCV实现手势识别

发表于:2024-11-12 作者:千家信息网编辑
千家信息网最后更新 2024年11月12日,如何使用C++中的OpenCV实现手势识别,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。先给大家上效果图:源码在下面使用
千家信息网最后更新 2024年11月12日如何使用C++中的OpenCV实现手势识别

如何使用C++中的OpenCV实现手势识别,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

先给大家上效果图:

源码在下面

使用 RGB 值分割手部区域,即手部的 GB 值将与背景不同
或者使用边缘检测
或者
背景减法。

我这里使用了背景减法模型。OpenCV为我们提供了不同的背景减法模型,codebook 它的作用是对某些帧进行一段时间的精确校准。其中对于它获取的所有图像;它计算每个像素的平均值和偏差,并相应地指定框。

在前景中它就像一个黑白图像,只有手是白色的

用 Convex Hull 来找到指尖。Convex hull 基本上是包围手部区域的凸集。

包围手的红线是凸包。基本上它是一个凸起;如果我们在红色区域内取任意两点并将它们连接起来形成一条线,那么这条线就完全位于集合内。

黄点是缺陷点,会有很多这样的缺陷点,即每个谷都有一个缺陷点。现在根据缺陷点的数量,我们可以计算展开的手指数量。

大概就是
手部区域提取是使用背景减法完成的。
对于尖端点,深度点凸度缺陷。
提取轮廓和检测凸点的主要代码在函数中
无效检测(IplImage* img_8uc1,IplImage* img_8uc3);

将相机放在稳定的背景前;运行代码,等待一段时间。校准完成后。你会看到显示一些干扰的连接组件图像。把你的手放在相机视图中。

没什么好说的直接看代码会比较容易理解
核心代码

int main(int argc, char** argv){    const char* filename = 0;    IplImage* rawImage = 0, *yuvImage = 0;     IplImage *ImaskCodeBook = 0,*ImaskCodeBookCC = 0;    CvCapture* capture = 0;    int c, n, nframes = 0;    int nframesToLearnBG = 300;    model = cvCreateBGCodeBookModel();           model->modMin[0] = 3;    model->modMin[1] = model->modMin[2] = 3;    model->modMax[0] = 10;    model->modMax[1] = model->modMax[2] = 10;    model->cbBounds[0] = model->cbBounds[1] = model->cbBounds[2] = 10;    bool pause = false;    bool singlestep = false;    for( n = 1; n < argc; n++ )    {        static const char* nframesOpt = "--nframes=";        if( strncmp(argv[n], nframesOpt, strlen(nframesOpt))==0 )        {            if( sscanf(argv[n] + strlen(nframesOpt), "%d", &nframesToLearnBG) == 0 )            {                help();                return -1;            }        }        else            filename = argv[n];    }    if( !filename )    {        printf("Capture from camera\n");        capture = cvCaptureFromCAM( 0 );    }    else    {        printf("Capture from file %s\n",filename);        capture = cvCreateFileCapture( filename );    }    if( !capture )    {        printf( "Can not initialize video capturing\n\n" );        help();        return -1;    }       for(;;)    {        if( !pause )        {            rawImage = cvQueryFrame( capture );            ++nframes;            if(!rawImage)                 break;        }        if( singlestep )            pause = true;                       if( nframes == 1 && rawImage )        {            // CODEBOOK METHOD ALLOCATION            yuvImage = cvCloneImage(rawImage);            ImaskCodeBook = cvCreateImage( cvGetSize(rawImage), IPL_DEPTH_8U, 1 );            ImaskCodeBookCC = cvCreateImage( cvGetSize(rawImage), IPL_DEPTH_8U, 1 );            cvSet(ImaskCodeBook,cvScalar(255));                        cvNamedWindow( "Raw", 1 );            cvNamedWindow( "ForegroundCodeBook",1);            cvNamedWindow( "CodeBook_ConnectComp",1);        }             if( rawImage )        {            cvCvtColor( rawImage, yuvImage, CV_BGR2YCrCb );                    if( !pause && nframes-1 < nframesToLearnBG  )                cvBGCodeBookUpdate( model, yuvImage );            if( nframes-1 == nframesToLearnBG  )                cvBGCodeBookClearStale( model, model->t/2 );                                   if( nframes-1 >= nframesToLearnBG  )            {                              cvBGCodeBookDiff( model, yuvImage, ImaskCodeBook );               centers if desired                cvCopy(ImaskCodeBook,ImaskCodeBookCC);                  cvSegmentFGMask( ImaskCodeBookCC );                            cvShowImage( "CodeBook_ConnectComp",ImaskCodeBookCC);                detect(ImaskCodeBookCC,rawImage);                            }                       cvShowImage( "Raw", rawImage );            cvShowImage( "ForegroundCodeBook",ImaskCodeBook);                    }            c = cvWaitKey(10)&0xFF;        c = tolower(c);               if(c == 27 || c == 'q')            break;         switch( c )        {        case 'h':            help();            break;        case 'p':            pause = !pause;            break;        case 's':            singlestep = !singlestep;            pause = false;            break;        case 'r':            pause = false;            singlestep = false;            break;        case ' ':            cvBGCodeBookClearStale( model, 0 );            nframes = 0;            break;            case 'y': case '0':        case 'u': case '1':        case 'v': case '2':        case 'a': case '3':        case 'b':             ch[0] = c == 'y' || c == '0' || c == 'a' || c == '3';            ch[1] = c == 'u' || c == '1' || c == 'a' || c == '3' || c == 'b';            ch[2] = c == 'v' || c == '2' || c == 'a' || c == '3' || c == 'b';            printf("CodeBook YUV Channels active: %d, %d, %d\n", ch[0], ch[1], ch[2] );            break;        case 'i':         case 'o':         case 'k':         case 'l':             {            uchar* ptr = c == 'i' || c == 'o' ? model->modMax : model->modMin;            for(n=0; n

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注行业资讯频道,感谢您对的支持。

0