openFrameworks使用ofxOpencv进行肤色检测

举报
ShaderJoy 发表于 2021/12/30 01:11:25 2021/12/30
【摘要】 由于ofxOpencv里的ofxCVColorImage是RGB格式的,没想到调用getCvImage()函数得到的IplImage居然也是RGB格式,结果害得我一开始肤色检测的结果十分诡异。。。作者也够懒的,这么简单居然也不做个转换! 这个就是调换RB通道的代码: void testApp::cvRGB_or_BGR(IplI...

由于ofxOpencv里的ofxCVColorImage是RGB格式的,没想到调用getCvImage()函数得到的IplImage居然也是RGB格式,结果害得我一开始肤色检测的结果十分诡异。。。作者也够懒的,这么简单居然也不做个转换!

这个就是调换RB通道的代码:


  
  1. void testApp::cvRGB_or_BGR(IplImage* src_image, IplImage* dst_image)
  2. {
  3. if (src_image != NULL && dst_image != NULL)
  4. {
  5. uchar* src_data=(uchar *)src_image->imageData;
  6. uchar* dst_data=(uchar *)dst_image->imageData;
  7. int step = src_image->widthStep/sizeof(uchar);
  8. int channels = src_image->nChannels;
  9. //uchar *b,*g,*r;
  10. for(int i=0;i<src_image->height;i++)
  11. {
  12. for(int j=0;j<src_image->width;j++)
  13. {
  14. dst_data[i*step+j*channels + 2] = src_data[i*step+j*channels + 0]; // b
  15. dst_data[i*step+j*channels + 1] = src_data[i*step+j*channels + 1]; // g
  16. dst_data[i*step+j*channels] = src_data[i*step+j*channels + 2]; // r
  17. }
  18. }
  19. }
  20. //cvShowImage("RGB", dst_image); // debug
  21. }


以下是在网上找到的opencv基于c的肤色检测代码:


  
  1. void testApp::cvSkinSegment(IplImage* img, IplImage* mask) // mask是单通道的
  2. {
  3. CvSize imageSize = cvSize(img->width, img->height);
  4. IplImage *imgY = cvCreateImage(imageSize, IPL_DEPTH_8U, 1);
  5. IplImage *imgCr = cvCreateImage(imageSize, IPL_DEPTH_8U, 1);
  6. IplImage *imgCb = cvCreateImage(imageSize, IPL_DEPTH_8U, 1);
  7. IplImage *imgYCrCb = cvCreateImage(imageSize, img->depth, img->nChannels);
  8. cvCvtColor(img,imgYCrCb,CV_BGR2YCrCb);
  9. //cvShowImage("img", img); // debug
  10. //cvShowImage("YCrCb", imgYCrCb); // debug
  11. cvSplit(imgYCrCb, imgY, imgCr, imgCb, 0);
  12. int y, cr, cb, l, x1, y1, value;
  13. unsigned char *pY, *pCr, *pCb, *pMask;
  14. pY = (unsigned char *)imgY->imageData;
  15. pCr = (unsigned char *)imgCr->imageData;
  16. pCb = (unsigned char *)imgCb->imageData;
  17. pMask = (unsigned char *)mask->imageData;
  18. cvSetZero(mask);
  19. l = img->height * img->width;
  20. for (int i = 0; i < l; i++)
  21. {
  22. y = *pY;
  23. cr = *pCr;
  24. cb = *pCb;
  25. cb -= 109;
  26. cr -= 152
  27. ;
  28. x1 = (819*cr-614*cb)/32 + 51;
  29. y1 = (819*cr+614*cb)/32 + 77;
  30. x1 = x1*41/1024;
  31. y1 = y1*73/1024;
  32. value = x1*x1+y1*y1;
  33. if(y<100)
  34. (*pMask)=(value<700) ? 255:0;
  35. else
  36. (*pMask)=(value<850)? 255:0;
  37. pY++;
  38. pCr++;
  39. pCb++;
  40. pMask++;
  41. }
  42. //cvShowImage("mask", mask); // debug
  43. cvReleaseImage(&imgY);
  44. cvReleaseImage(&imgCr);
  45. cvReleaseImage(&imgCb);
  46. cvReleaseImage(&imgYCrCb);
  47. //return mask;
  48. }

我移植的基于c++的肤色检测代码:


  
  1. void testApp::cvSkinSegment(cv::Mat img, cv::Mat mask) // mask是单通道的
  2. {
  3. cv::Size imageSize = img.size();
  4. cv::Mat imgY, imgCr, imgCb;
  5. cv::Mat imgYCrCb = cv::Mat(imageSize, CV_8UC3);
  6. vector<cv::Mat> imgVec;
  7. cvtColor(img,imgYCrCb,CV_BGR2YCrCb);
  8. split(imgYCrCb, imgVec);
  9. imgY = imgVec[0];
  10. imgCr = imgVec[1];
  11. imgCb = imgVec[2];
  12. int y, cr, cb, x1, y1, value;
  13. uchar *pY, *pCr, *pCb, *pMask;
  14. mask.zeros(mask.size(), mask.type());
  15. int nRows = img.rows;
  16. int nCols = img.cols;
  17. for (int i = 0; i < nRows; i++)
  18. {
  19. pY = imgY.ptr<uchar>(i);
  20. pCr = imgCr.ptr<uchar>(i);
  21. pCb = imgCb.ptr<uchar>(i);
  22. pMask = mask.ptr<uchar>(i);
  23. for (int j = 0; j<nCols; j++)
  24. {
  25. y = pY[j];
  26. cr = pCr[j];
  27. cb = pCb[j];
  28. cb -= 109;
  29. cr -= 152;
  30. x1 = (819*cr - 614*cb)/32 + 51;
  31. y1 = (819*cr + 614*cb)/32 + 77;
  32. x1 = x1 * 41/1024;
  33. y1 = y1 * 73/1024;
  34. value = x1*x1 + y1*y1;
  35. if(y<100)
  36. (pMask[j])=(value<700) ? 255:0;
  37. else
  38. (pMask[j])=(value<850)? 255:0;
  39. }
  40. }
  41. }


其原理请移步这里

文章来源: panda1234lee.blog.csdn.net,作者:panda1234lee,版权归原作者所有,如需转载,请联系作者。

原文链接:panda1234lee.blog.csdn.net/article/details/20050505

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。