#include "highgui.h"
#include "cv.h"
#include <iostream>
#include <math.h>
#include <vector>
using namespace std;
//已知a b c 三点 求ab 与 bc之间的夹角
double CalcuateABC(CvPoint *p1,CvPoint *p2,CvPoint *p3)
{
double line1,line2,line3;
line1=(double)sqrt((double)((p2->x-p3->x)*(p2->x-p3->x)+(p2->y-p3->y)*(p2->y-p3->y)));
line2=(double)sqrt((double)((p1->x-p3->x)*(p1->x-p3->x)+(p1->y-p3->y)*(p1->y-p3->y)));
line3=(double)sqrt((double)((p2->x-p1->x)*(p2->x-p1->x)+(p2->y-p1->y)*(p2->y-p1->y)));
double cosPoint;
cosPoint=acos(((line1*line1+line3*line3-line2*line2)/(2*line1*line3)))/3.14159*180.0;
return cosPoint;
}
//计算该点是指尖点还是指跟点
double Chose(CvPoint *p1,CvPoint *p2,CvPoint *p3)
{
return ((p1->x-p2->x)*(p3->y-p2->y)-(p3->x-p2->x)*(p1->y-p2->y));
}
//计算两点之间的距离
double JuLi(CvPoint *p1,CvPoint *p2)
{
return (double)sqrt((double)((p1->x-p2->x)*(p1->x-p2->x)+(p1->y-p2->y)*(p1->y-p2->y)));
}
void cvThresholdOtsu(IplImage* src, IplImage* dst)
{
int height=src->height;
int width=src->width;
//histogram
float histogram[256]={0};
for(int i=0;i<height;i++) {
unsigned char* p=(unsigned char*)src->imageData+src->widthStep*i;
for(int j=0;j<width;j++) {
histogram[*p++]++;
}
}
//normalize histogram
int size=height*width;
for(int i=0;i<256;i++) {
histogram[i]=histogram[i]/size;
}
//average pixel value
float avgValue=0;
for(int i=0;i<256;i++) {
avgValue+=i*histogram[i];
}
int threshold;
float maxVariance=0;
float w=0,u=0;
for(int i=0;i<256;i++) {
w+=histogram[i];
u+=i*histogram[i];
float t=avgValue*w-u;
float variance=t*t/(w*(1-w));
if(variance>maxVariance) {
maxVariance=variance;
threshold=i;
}
}
cvThreshold(src,dst,threshold,255,CV_THRESH_BINARY);
}
void cvSkinOtsu(IplImage* src, IplImage* dst)
{
assert(dst->nChannels==1&& src->nChannels==3);
IplImage* ycrcb=cvCreateImage(cvGetSize(src),8,3);
IplImage* cr=cvCreateImage(cvGetSize(src),8,1);
cvCvtColor(src,ycrcb,CV_BGR2YCrCb);
cvSplit(ycrcb,0,cr,0,0);
cvThresholdOtsu(cr,cr);
cvCopyImage(cr,dst);
cvReleaseImage(&cr);
cvReleaseImage(&ycrcb);
}
//================================YUV
void cvSkinYUV(IplImage* src,IplImage* dst)
{
IplImage* ycrcb=cvCreateImage(cvGetSize(src),8,3);
//IplImage* cr=cvCreateImage(cvGetSize(src),8,1);
//IplImage* cb=cvCreateImage(cvGetSize(src),8,1);
cvCvtColor(src,ycrcb,CV_BGR2YCrCb);
//cvSplit(ycrcb,0,cr,cb,0);
static const int Cb=2;
static const int Cr=1;
static const int Y=0;
//IplImage* dst=cvCreateImage(cvGetSize(_dst),8,3);
cvZero(dst);
for (int h=0;h<src->height;h++) {
unsigned char* pycrcb=(unsigned char*)ycrcb->imageData+h*ycrcb->widthStep;
unsigned char* psrc=(unsigned char*)src->imageData+h*src->widthStep;
unsigned char* pdst=(unsigned char*)dst->imageData+h*dst->widthStep;
for (int w=0;w<src->width;w++) {
if (pycrcb[Cr]>=133&&pycrcb[Cr]<=173&&pycrcb[Cb]>=77&&pycrcb[Cb]<=127)
{
memcpy(pdst,psrc,3);
}
pycrcb+=3;
psrc+=3;
pdst+=3;
}
}
//cvCopyImage(dst,_dst);
cvReleaseImage(&ycrcb);
}
//==========================ycrcb
void cvSkinSegment(IplImage* img, IplImage* 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);
cvSplit(imgYCrCb, imgY, imgCr, imgCb, 0);
int y, cr, cb, l, x1, y1, value;
unsigned char *pY, *pCr, *pCb, *pMask;
CvRect rec;
rec.x=240;
rec.y=320;
rec.width=100;
rec.height=100;
pY = (unsigned char *)imgY->imageData;
pCr = (unsigned char *)imgCr->imageData;
pCb = (unsigned char *)imgCb->imageData;
pMask = (unsigned char *)mask->imageData;
cvSetZero(mask);
//pY = &((unsigned char *)(imgY->imageData+rec.x*imgY->widthStep))[rec.y];
//pCr = &((unsigned char* )(imgCr->imageData+rec.x*imgCr->widthStep))[rec.y];
//pCb = &((unsigned char* )(imgCb->imageData+rec.x*imgCb->widthStep))[rec.y];
//pMask = &((unsigned char* )(mask->imageData+rec.x*mask->widthStep))[rec.y];
l = img->height * img->width;
for (int i = 0; i < l; i++){
// for (int i = 0; i < 30000; 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++;
}
cvReleaseImage(&imgY);
cvReleaseImage(&imgCr);
cvReleaseImage(&imgCb);
cvReleaseImage(&imgYCrCb);
}
//RGB转换rect某一块到yuv空间
void cvSkinSegment22(IplImage* img, IplImage* 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);
cvSplit(imgYCrCb, imgY, imgCr, imgCb, 0);
int y, cr, cb, l, x1, y1, value;
unsigned char *pY, *pCr, *pCb, *pMask;
CvRect rec;
rec.x=240;
rec.y=320;
rec.width=100;
rec.height=100;
//pY = (unsigned char *)imgY->imageData;
//pCr = (unsigned char *)imgCr->imageData;
//pCb = (unsigned char *)imgCb->imageData;
//pMask = (unsigned char *)mask->imageData;
cvSetZero(mask);
pY = &((unsigned char *)(imgY->imageData+rec.x*imgY->widthStep))[rec.y];
pCr = &((unsigned char* )(imgCr->imageData+rec.x*imgCr->widthStep))[rec.y];
pCb = &((unsigned char* )(imgCb->imageData+rec.x*imgCb->widthStep))[rec.y];
pMask = &((unsigned char* )(mask->imageData+rec.x*mask->widthStep))[rec.y];
l = img->height * img->width;
// for (int i = 0; i < l; i++){
for (int i = 0; i < 30000; 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++;
}
cvReleaseImage(&imgY);
cvReleaseImage(&imgCr);
cvReleaseImage(&imgCb);
cvReleaseImage(&imgYCrCb);
}
int main()
{
IplImage* img=0;
IplImage* dst_crotsu=0;
IplImage* dst_YUV=0;
IplImage* dst_ycrcb=0;
IplImage* dst_bgr=0;
IplImage* dst_gray=0;
IplImage *tempimg=0;
IplImage *imgdet=0;
CvPoint oldPoint;
oldPoint.x=0;
oldPoint.y=0;
CvCapture *Cap=0;
Cap=cvCaptureFromCAM(-1);
cvNamedWindow("src",1);
//cvNamedWindow("otsu",1);//最大类间方差
cvNamedWindow("yuv",1);
cvNamedWindow("yuv_good",1);
//cvNamedWindow("crcb",1);
//cvNamedWindow("contour",1);
//cvNamedWindow("det",1);
img=cvQueryFrame(Cap);
dst_crotsu=cvCreateImage(cvGetSize(img),8,1);
dst_YUV=cvCreateImage(cvGetSize(img),8,3);
dst_ycrcb=cvCreateImage(cvGetSize(img),8,1);
tempimg=cvCreateImage(cvGetSize(dst_ycrcb),dst_ycrcb->depth,dst_ycrcb->nChannels);
dst_bgr=cvCreateImage(cvGetSize(img),8,3);
dst_gray=cvCreateImage(cvGetSize(img),8,1);
imgdet=cvCreateImage(cvGetSize(img),8,3);
while(1)
{
img=cvQueryFrame(Cap);
CvRect detrect;
detrect.x=0;
detrect.y=0;
detre