openFrameworks使用ofxOpencv进行肤色检测
【摘要】
由于ofxOpencv里的ofxCVColorImage是RGB格式的,没想到调用getCvImage()函数得到的IplImage居然也是RGB格式,结果害得我一开始肤色检测的结果十分诡异。。。作者也够懒的,这么简单居然也不做个转换!
这个就是调换RB通道的代码:
void testApp::cvRGB_or_BGR(IplI...
由于ofxOpencv里的ofxCVColorImage是RGB格式的,没想到调用getCvImage()函数得到的IplImage居然也是RGB格式,结果害得我一开始肤色检测的结果十分诡异。。。作者也够懒的,这么简单居然也不做个转换!
这个就是调换RB通道的代码:
-
void testApp::cvRGB_or_BGR(IplImage* src_image, IplImage* dst_image)
-
{
-
if (src_image != NULL && dst_image != NULL)
-
{
-
uchar* src_data=(uchar *)src_image->imageData;
-
uchar* dst_data=(uchar *)dst_image->imageData;
-
-
int step = src_image->widthStep/sizeof(uchar);
-
int channels = src_image->nChannels;
-
//uchar *b,*g,*r;
-
-
for(int i=0;i<src_image->height;i++)
-
{
-
for(int j=0;j<src_image->width;j++)
-
{
-
dst_data[i*step+j*channels + 2] = src_data[i*step+j*channels + 0]; // b
-
dst_data[i*step+j*channels + 1] = src_data[i*step+j*channels + 1]; // g
-
dst_data[i*step+j*channels] = src_data[i*step+j*channels + 2]; // r
-
}
-
}
-
}
-
-
//cvShowImage("RGB", dst_image); // debug
-
}
以下是在网上找到的opencv基于c的肤色检测代码:
-
void testApp::cvSkinSegment(IplImage* img, IplImage* mask) // mask是单通道的
-
{
-
CvSize imageSize = cvSize(img->width, img->height);
-
IplImage *imgY = cvCreateImage(imageSize, IPL_DEPTH_8U, 1);
-
IplImage *imgCr = cvCreateImage(imageSize, IPL_DEPTH_8U, 1);
-
IplImage *imgCb = cvCreateImage(imageSize, IPL_DEPTH_8U, 1);
-
-
IplImage *imgYCrCb = cvCreateImage(imageSize, img->depth, img->nChannels);
-
cvCvtColor(img,imgYCrCb,CV_BGR2YCrCb);
-
//cvShowImage("img", img); // debug
-
//cvShowImage("YCrCb", imgYCrCb); // debug
-
-
cvSplit(imgYCrCb, imgY, imgCr, imgCb, 0);
-
int y, cr, cb, l, x1, y1, value;
-
unsigned char *pY, *pCr, *pCb, *pMask;
-
-
pY = (unsigned char *)imgY->imageData;
-
pCr = (unsigned char *)imgCr->imageData;
-
pCb = (unsigned char *)imgCb->imageData;
-
pMask = (unsigned char *)mask->imageData;
-
cvSetZero(mask);
-
-
l = img->height * img->width;
-
-
for (int i = 0; i < l; i++)
-
{
-
y = *pY;
-
cr = *pCr;
-
cb = *pCb;
-
cb -= 109;
-
cr -= 152
-
;
-
x1 = (819*cr-614*cb)/32 + 51;
-
y1 = (819*cr+614*cb)/32 + 77;
-
x1 = x1*41/1024;
-
y1 = y1*73/1024;
-
value = x1*x1+y1*y1;
-
-
if(y<100)
-
(*pMask)=(value<700) ? 255:0;
-
else
-
(*pMask)=(value<850)? 255:0;
-
-
pY++;
-
pCr++;
-
pCb++;
-
pMask++;
-
}
-
-
//cvShowImage("mask", mask); // debug
-
-
cvReleaseImage(&imgY);
-
cvReleaseImage(&imgCr);
-
cvReleaseImage(&imgCb);
-
cvReleaseImage(&imgYCrCb);
-
-
//return mask;
-
}
我移植的基于c++的肤色检测代码:
-
void testApp::cvSkinSegment(cv::Mat img, cv::Mat mask) // mask是单通道的
-
{
-
cv::Size imageSize = img.size();
-
cv::Mat imgY, imgCr, imgCb;
-
cv::Mat imgYCrCb = cv::Mat(imageSize, CV_8UC3);
-
vector<cv::Mat> imgVec;
-
-
cvtColor(img,imgYCrCb,CV_BGR2YCrCb);
-
-
split(imgYCrCb, imgVec);
-
imgY = imgVec[0];
-
imgCr = imgVec[1];
-
imgCb = imgVec[2];
-
-
int y, cr, cb, x1, y1, value;
-
uchar *pY, *pCr, *pCb, *pMask;
-
-
mask.zeros(mask.size(), mask.type());
-
-
int nRows = img.rows;
-
int nCols = img.cols;
-
-
for (int i = 0; i < nRows; i++)
-
{
-
pY = imgY.ptr<uchar>(i);
-
pCr = imgCr.ptr<uchar>(i);
-
pCb = imgCb.ptr<uchar>(i);
-
pMask = mask.ptr<uchar>(i);
-
-
for (int j = 0; j<nCols; j++)
-
{
-
y = pY[j];
-
cr = pCr[j];
-
cb = pCb[j];
-
cb -= 109;
-
cr -= 152;
-
-
x1 = (819*cr - 614*cb)/32 + 51;
-
y1 = (819*cr + 614*cb)/32 + 77;
-
x1 = x1 * 41/1024;
-
y1 = y1 * 73/1024;
-
value = x1*x1 + y1*y1;
-
-
if(y<100)
-
(pMask[j])=(value<700) ? 255:0;
-
else
-
(pMask[j])=(value<850)? 255:0;
-
}
-
-
}
-
-
}
其原理请移步这里
文章来源: panda1234lee.blog.csdn.net,作者:panda1234lee,版权归原作者所有,如需转载,请联系作者。
原文链接:panda1234lee.blog.csdn.net/article/details/20050505
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)