服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - C++基于OpenCV实现手势识别的源码

C++基于OpenCV实现手势识别的源码

2022-01-05 16:08OKjokull C/C++

这篇文章主要介绍了C++基于OpenCV手势识别的实现源码,这里用到背景减法模型知识,具体实例代码跟随小编一起看看吧

先给大家上效果图:

C++基于OpenCV实现手势识别的源码

源码在下面

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

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

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

C++基于OpenCV实现手势识别的源码

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

C++基于OpenCV实现手势识别的源码

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

C++基于OpenCV实现手势识别的源码

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

大概就是
手部区域提取是使用背景减法完成的。
对于尖端点,深度点凸度缺陷。
提取轮廓和检测凸点的主要代码在函数中
无效检测(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<NCHANNELS; n++)
          {
              if( ch[n] )
              {
                  int v = ptr[n] + (c == 'i' || c == 'l' ? 1 : -1);
                  ptr[n] = CV_CAST_8U(v);
              }
              printf("%d,", ptr[n]);
          }
          printf(" CodeBook %s Side\n", c == 'i' || c == 'o' ? "High" : "Low" );
          }
          break;
      }
  }		
  
  cvReleaseCapture( &capture );
  cvDestroyWindow( "Raw" );
  cvDestroyWindow( "ForegroundCodeBook");
  cvDestroyWindow( "CodeBook_ConnectComp");
  return 0;
}

要直接跑代码调试的,可以直接去下载

到此这篇关于C++基于OpenCV实现手势识别的源码的文章就介绍到这了,更多相关OpenCV手势识别内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/weixin_39276851/article/details/120236329

延伸 · 阅读

精彩推荐
  • C/C++OpenCV实现拼接图像的简单方法

    OpenCV实现拼接图像的简单方法

    这篇文章主要为大家详细介绍了OpenCV实现拼接图像的简单方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    iteye_183805102021-07-29
  • C/C++使用C++制作简单的web服务器(续)

    使用C++制作简单的web服务器(续)

    本文承接上文《使用C++制作简单的web服务器》,把web服务器做的功能稍微强大些,主要增加的功能是从文件中读取网页并返回给客户端,而不是把网页代码...

    C++教程网5492021-02-22
  • C/C++深入C++拷贝构造函数的总结详解

    深入C++拷贝构造函数的总结详解

    本篇文章是对C++中拷贝构造函数进行了总结与介绍。需要的朋友参考下...

    C++教程网5182020-11-30
  • C/C++c/c++实现获取域名的IP地址

    c/c++实现获取域名的IP地址

    本文给大家汇总介绍了使用c/c++实现获取域名的IP地址的几种方法以及这些方法的核心函数gethostbyname的详细用法,非常的实用,有需要的小伙伴可以参考下...

    C++教程网10262021-03-16
  • C/C++关于C语言中E-R图的详解

    关于C语言中E-R图的详解

    今天小编就为大家分享一篇关于关于C语言中E-R图的详解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看...

    Struggler095962021-07-12
  • C/C++C语言实现双人五子棋游戏

    C语言实现双人五子棋游戏

    这篇文章主要为大家详细介绍了C语言实现双人五子棋游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    两片空白7312021-11-12
  • C/C++C语言main函数的三种形式实例详解

    C语言main函数的三种形式实例详解

    这篇文章主要介绍了 C语言main函数的三种形式实例详解的相关资料,需要的朋友可以参考下...

    ieearth6912021-05-16
  • C/C++c/c++内存分配大小实例讲解

    c/c++内存分配大小实例讲解

    在本篇文章里小编给大家整理了一篇关于c/c++内存分配大小实例讲解内容,有需要的朋友们可以跟着学习参考下。...

    jihite5172022-02-22