• 大小: 8KB
    文件类型: .cpp
    金币: 1
    下载: 0 次
    发布日期: 2023-12-18
  • 语言: C/C++
  • 标签: 肤色检测  

资源简介

利用OpenCV实现了基于YCbCr、混合高斯以及YCbCg肤色检测,同时其中YCbCr、混合高斯给出两种不同方式(直接和间接)读取图像数据的实现。

资源截图

代码片段和文件信息

#include “stdafx.h“
#include “SubFun.h“

//YCbCr 椭圆肤色分割1
void EllipseSkinSegment1(Mat ColorIm Mat& SkinBW)
{
int m = ColorIm.rows;
int n = ColorIm.cols;
SkinBW = Mat::zeros(m n CV_8UC1);

Mat YCbCr Y Cr Cb;
vector channels;
cvtColor(ColorIm YCbCr CV_BGR2YCrCb);//必须要用CV_BGR2YCrCb,不能用CV_RGB2YCrCb
split(YCbCr channels);
Y = channels.at(0);
Cr = channels.at(1);
Cb = channels.at(2);

Y.convertTo(Y CV_32FC1);
Cr.convertTo(Cr CV_32FC1);
Cb.convertTo(Cb CV_32FC1);

float Cx = 109.38 Cy = 152.02;
float Ecx = 1.60 Ecy = 2.41;
float a = 25.39 b = 14.03;
float Theta = 2.53;

Mat RotateM = (Mat_(2 2) <<
cos(Theta) sin(Theta) -sin(Theta) cos(Theta));
Mat Diff = Mat::zeros(2 1 CV_32FC1);;
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
Diff.at(0 0) = Cb.at(i j) - Cx;
Diff.at(1 0) = Cr.at(i j) - Cy;
Mat RotateVal = RotateM*Diff;
float x = RotateVal.at(0 0);
float y = RotateVal.at(1 0);
float EllipseV = pow((x - Ecx) 2.0) / (a*a) + pow((y - Ecy) 2.0) / (b*b);
if (EllipseV <= 1)
{
SkinBW.at(i j) = 255;
}
if (Y.at(i j) < 80.0)
{
SkinBW.at(i j) = 0;
}
}
}
//imshow(“原始肤色区域“ SkinBW);
//形态学开操作,去掉小的噪点区域
int KnelW = 5;
morphologyEx(SkinBW SkinBW MORPH_OPEN Mat(KnelW KnelW CV_8U) Point(-1 -1) 1);
}



//YCbCr 椭圆肤色分割2
void EllipseSkinSegment2(Mat ColorIm Mat& SkinBW)
{
int m = ColorIm.rows;
int n = ColorIm.cols;
SkinBW = Mat::zeros(m n CV_8UC1);

Mat YCbCr Y Cr Cb;
vector channels;
cvtColor(ColorIm YCbCr CV_BGR2YCrCb);//必须要用CV_BGR2YCrCb,不能用CV_RGB2YCrCb
split(YCbCr channels);
Y = channels.at(0);
Cr = channels.at(1);
Cb = channels.at(2);

Y.convertTo(Y CV_32FC1);
Cr.convertTo(Cr CV_32FC1);
Cb.convertTo(Cb CV_32FC1);

float Cx = 109.38 Cy = 152.02;
float Ecx = 1.60 Ecy = 2.41;
float a = 25.39 b = 14.03;
float Theta = 2.53;

Mat RotateM = (Mat_(2 2) <<
cos(Theta) sin(Theta) -sin(Theta) cos(Theta));
Mat Diff = Mat::zeros(2 1 CV_32FC1);;
for (int i = 0; i < m; i++)
{
float* YRow = Y.ptr(i);
float* CbRow = Cb.ptr(i);
float* CrRow = Cr.ptr(i);
uchar* SkinBWRow = SkinBW.ptr(i);
for (int j = 0; j < n; j++)
{
Diff.at(0 0) = CbRow[j] - Cx;
Diff.at(1 0) = CrRow[j] - Cy;
Mat RotateVal = RotateM*Diff;
float x = RotateVal.at(0 0);
float y = RotateVal.at(1 0);
float EllipseV = pow((x - Ecx) 2.0) / (a*a) + pow((y - Ecy) 2.0) / (b*b);
if (EllipseV <= 1)
{
SkinBWRow[j] = 255;
}
if (YRow[j] < 80.0)
{
SkinBWRow[j] = 0;
}
}
}
//imshow(“原始肤色区域“ SkinBW);
//形态学开操作,去掉小的噪点区域
int KnelW = 5;
morphologyEx(SkinBW SkinBW MORPH_OPEN Mat(KnelW KnelW CV_8U) Point(-1 -1) 1);
}




//混合高斯肤色分割
void MixGaus

评论

共有 条评论