⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 imagepr.cpp

📁 一个基于知识的人脸检测系统
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/**************************************************
file name: ImagePr.cpp 
Copyright (c) 2001-2004 16-320,TJU
founder: Li Xuewei
date: 3,20,2003
mender: Li Xuewei
date: 
description:this implementation file can process the whole skin detection,
            facial feature extraction,and face verify.

version:1.0
*/

#include "stdafx.h"
#include "ImageProcess.h"
#include "ImagePr.h"
#include "math.h"

#include "afx.h"

#include <Mmsystem.h>

#define PI 3.1415926

#ifdef _DEBUG   //#if defined(_DEBUG)/#endif 
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// ImagePr

IMPLEMENT_DYNCREATE(ImagePr, CView)

ImagePr::ImagePr()
{
	myHSIArray=NULL;
}

ImagePr::~ImagePr()
{
}


BEGIN_MESSAGE_MAP(ImagePr, CView)
	//{{AFX_MSG_MAP(ImagePr)
		// NOTE - the ClassWizard will add and remove mapping macros here.
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// ImagePr drawing

void ImagePr::OnDraw(CDC* pDC)
{
	CDocument* pDoc = GetDocument();
	// TODO: add draw code here
}

/////////////////////////////////////////////////////////////////////////////
// ImagePr diagnostics

#ifdef _DEBUG
void ImagePr::AssertValid() const
{
	CView::AssertValid();
}

void ImagePr::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// ImagePr message handlers

void ImagePr::ReadDIB(CString fName)
{
/*
** function name: ReadDIB(CString fName)
** input: file name
** fName--
** output: 
** function description: open an image of 24-bmp
** global varible-- myPArray,myPWidth,myPHeight
** call block: none
** founder: Zhang Ge
** date:    2001
** mender:  Li Xuewei
** date: 
** version: 1.0
*/
	//BITMAPFILEHEADER tFileHead;
	//BITMAPINFOHEADER tFileInfo;
	int RowLength;
	int tPWidth;
	int tPHeight;	
	LONG tOffset;

	BYTE * tPArray;

	BYTE tBlue;
	BYTE tGreen;
	BYTE tRed;

	int i,j;

//	CFile f1("text.txt",CFile::modeWrite|CFile::typeBinary);

	CFile tPfile(fName,CFile::modeRead);	
	nHeadRead1=tPfile.Read(&tFileHead,14); 
	nInfoRead2=tPfile.Read(&tFileInfo,40);	

	//tFileHead.bfReserved1+tFileHead.bfSize+tFileHead.bfType;

//	f1.Write(&tFileHead,sizeof(BITMAPFILEHEADER));

	if(tFileInfo.biBitCount!=24)
	{
		AfxMessageBox("This file isn't a 24 bit BMP");
		return;
	}

	tOffset = tFileHead.bfOffBits-54;
	gOffset = tOffset;
	tPWidth = tFileInfo.biWidth;
	tPHeight = tFileInfo.biHeight;

	tPArray= new BYTE[tFileHead.bfSize-54];

	myPArray= new COLORREF[tPHeight*tPWidth];
	RGBImage= new COLORREF[tPHeight*tPWidth];

	// tPArray: File buffer
	tPfile.Read(tPArray,(tFileHead.bfSize-54));

	RowLength=tPWidth*3/4;
	if ((tPWidth*3)!=(RowLength*4))
		RowLength+=1;
	RowLength*=4;
	
	int tPP;
	for (i=tPHeight-1; i>=0; i--)// last row corresponded to 1st row's data
	{			
		tPP=tOffset;	
		for(j=0; j<tPWidth; j++)
		{
			tBlue=tPArray[tPP];
			tPP++;
			tGreen=tPArray[tPP];
			tPP++;
			tRed=tPArray[tPP];
			tPP++;
			*(myPArray+i*tPWidth+j)=RGB(tRed,tGreen,tBlue);	
			*(RGBImage+i*tPWidth+j)=RGB(tRed,tGreen,tBlue);
		}	
		tOffset+=RowLength;
	}	

	delete []tPArray;

	myPWidth=tPWidth;
	myPHeight=tPHeight;

	fileName=fName;
}

void ImagePr::HSItrans(char tp)
{
/*
** input: tp
** tp--varible of char type,it is used to judge whether HSI-RGB.
** output: 
** function description: image format transformation from HSI-RGB or RGB-HSI
** global varible-- myHSIArray,myPArray
** call block: none
** founder: Zhang Ge
** date:    2001
** mender:  Li Xuewei
** date: 2003
** version: 1.0
*/
	if (myHSIArray==NULL) myHSIArray= new sHSI[myPHeight*myPWidth];

	double tH,tS,tI,fR,fG,fB;
	BYTE R,G,B;
	int i,j;
	double v;
	
	switch (tp)
	{
	case 't':
		for(i=0; i<(int)myPHeight; i++)
		{
			for (j=0; j<(int)myPWidth; j++)
			{				
				R=GetRValue(myPArray[i*myPWidth+j]);
				G=GetGValue(myPArray[i*myPWidth+j]);
				B=GetBValue(myPArray[i*myPWidth+j]);
				fR=R;
				fG=G;
				fB=B;

				myHSIArray[i*myPWidth+j].I=(int)(fR+fG+fB)/3; ///*
				if(fR+fG+fB==0)//当I=0时,S没有意义,定义为0。
					myHSIArray[i*myPWidth+j].S=0;
				else
				myHSIArray[i*myPWidth+j].S
						=float(1-min(min(fR,fG),fB)*3/(fR+fG+fB));

				v=atan2(1.73205081*(G-B),(2*R-G-B));//atan2 returns value between -PI to PI;
				if(v<0)
					v+=2*PI;
				myHSIArray[i*myPWidth+j].H=int(v*180/PI);//change arc to angle.
				
			}
		}
		break;

	case 'v':    //con't
		for(i=0; i<(int)myPHeight; i++)
		{
			for (j=0; j<(int)myPWidth; j++)
			{
				tH=PI*(myHSIArray[i*myPWidth+j].H)/180;
				tS=myHSIArray[i*myPWidth+j].S;
				tI=myHSIArray[i*myPWidth+j].I;
			
				if(tS==0)
				{
					if(tI==0)
					{
						fR=fG=fB=0;
					}
					else
					{
						fR=fG=fB=tI;
					}
				}
				else
				{
				}

				R=(BYTE)fR;
				G=(BYTE)fG;
				B=(BYTE)fB;
				myPArray[i*myPWidth+j]=RGB(R,G,B);				

			}
		}
		break;
	}
	
}

void ImagePr::sobel()
{
/*
** function name: sobel()
** function description: image edge detection
** global varible-- myPArray
** call block: none
** founder: Li Shuda
** date:    2002
** mender:  Li Xuewei
** date: 
** version: 1.0
*/
	int * tPArray; //int
	
	int    i,j,v;
	double vx,vy;	
    	
	tPArray= new int[myPHeight*myPWidth]; //

	for(i=0; i<myPHeight; i++)
	{
		for (j=0; j<myPWidth; j++)
		{
			*(tPArray+i*myPWidth+j)=myHSIArray[i*myPWidth+j].I;//COLORREF myPArray
		}
	}
    for(i=0;i<myPWidth;i++)//置第一行和最后一行像素值为零;可无
    {
      *(tPArray+i)=0;
      *(tPArray+i+(myPHeight-1)*myPWidth)=0;
	} 
	 
    for(j=0;j<myPHeight;j++) //置第一列和最后一列像素值为零;可无
    {
      *(tPArray+j*myPWidth)=0;
	  *(tPArray+(j+1)*myPWidth-1)=0;
    }

	/*for(i=0;i<360;i++)//gradient angle
		fany[i]=0;

	double tf;*/
	
	//double t1,t2,t3,t4;
	//int t;
	
	for(j=1;j<myPHeight-1;j++)
	{
		for(i=1;i<myPWidth-1;i++)
		{
			
		 vx=*(tPArray+(i+1)+(j-1)*myPWidth)+2 * *(tPArray+(i+1)+(j)*myPWidth)
             +*(tPArray+(i+1)+(j+1)*myPWidth)-
             (*(tPArray+(i-1)+(j-1)*myPWidth)+2 * *(tPArray+(i-1)+(j)*myPWidth)
             +*(tPArray+(i-1)+(j+1)*myPWidth));
          vy=*(tPArray+(i-1)+(j+1)*myPWidth)+2 * *(tPArray+(i)+(j+1)*myPWidth)
             +*(tPArray+(i+1)+(j+1)*myPWidth)-
             (*(tPArray+(i-1)+(j-1)*myPWidth)+2 * *(tPArray+(i)+(j-1)*myPWidth)
             +*(tPArray+(i+1)+(j-1)*myPWidth));/**/
         
		  /* weber fechner law
		  t1=(*(tPArray+(i+1)+(j-1)*myPWidth)-*(tPArray+i+j*myPWidth))/ double(*(tPArray+i+j*myPWidth));
		  t2=(*(tPArray+(i+1)+(j+1)*myPWidth)-*(tPArray+i+j*myPWidth))/ double(*(tPArray+i+j*myPWidth));
		  t3=(*(tPArray+(i-1)+(j+1)*myPWidth)-*(tPArray+i+j*myPWidth))/ double(*(tPArray+i+j*myPWidth));
		  t4=(*(tPArray+(i-1)+(j-1)*myPWidth)-*(tPArray+i+j*myPWidth))/ double(*(tPArray+i+j*myPWidth));
		
		  t=*(tPArray+ i +j * myPWidth);

		  if(abs(t1)>0.02 || abs(t2)>0.02 ||abs(t3)>0.02|| abs(t4)>0.02)
			  *(myPArray+i+j*myPWidth)=RGB(t,t,t);
		  else
			  *(myPArray+i+j*myPWidth)=RGB(255,255,255);*/
		  
			 /* gradient angle
			 if(!(vx==0 && vy==0))
			  {
				  tf=atan2(vy,vx);
				  if(tf<0)
						tf+=2*PI;//
				  fany[int(tf*180/PI)]++;
			  }
			
			//v=int(v/2.55);*/
			
		  v=(int)sqrt(vx*vx+vy*vy);//v=abs(vx)+abs(vy);
	   
			if(v>255)
				v=255;
			if(v<0)
				v=0;
		  
			*(myPArray+i+j*myPWidth)=RGB(v,v,v);
		  
		  //bilevel display
		   /*if(v>150) //
			   *(myPArray+i+j*myPWidth)=RGB(0,0,0);
		   else
			   *(myPArray+i+j*myPWidth)=RGB(t,t,t);*/
		}
	}

	  delete []tPArray;
	 
}

void ImagePr::visionSobel()
{
/*
** function name: visionSobel()
** function description: image edge detction by using vision intensity
** global varible-- myHSIArray,myPArray
** call block: none
** founder: Li Xuewei
** date:    2003
** mender:  Li Xuewei
** date: 
** version: 1.0
*/
	short * tPArray;//COLORREF
		
	int  i,j,v;
	double vx,vy;

	double t;	
    	
	tPArray= new short[myPHeight*myPWidth];//COLORREF
	gradient=new short[myPHeight*myPWidth];

	for(i=0; i<myPHeight; i++)
	{
		for (j=0; j<myPWidth; j++)
		{
			t=myHSIArray[i*myPWidth+j].I;//COLORREF myPArray
			t=t*100/256;
			if(t>=0 &&t <18)
				t=7.519+2.098*t;
			if(t>=18 && t<=100)
				t=-58.936+79.192*log(t)/log(10);/**/

			//t=t*255/100;

			if(t>255)
				t=255;
			if(t<0)
				t=0;
			*(tPArray+i*myPWidth+j)=short(t);

			*(gradient+i*myPWidth+j)=0;
		}
	}
    for(i=0;i<myPWidth;i++)//the pixels of the first and last row are be set to zero.
    {
		*(tPArray+i)=0;
        *(tPArray+i+(myPHeight-1)*myPWidth)=0;
	} 
	 
    for(j=0;j<myPHeight;j++) //the pixels of the first and last coloum are be set to zero.
    {
        *(tPArray+j*myPWidth)=0;
	    *(tPArray+(j+1)*myPWidth-1)=0;
    }

	int thresh=binarizeForImage('n');

	for(i=0;i<180;i++)//gradient angle
		fany[i]=0;

	double tf;
	int ti;

	for(j=1;j<myPHeight-1;j++)
		for(i=1;i<myPWidth-1;i++)
		{
		      //vertical edge
			  vx=*(tPArray+(i+1)+(j-1)*myPWidth)+ 2 * *(tPArray+(i+1)+(j)*myPWidth)
				 +*(tPArray+(i+1)+(j+1)*myPWidth)-
				 (*(tPArray+(i-1)+(j-1)*myPWidth)+ 2 * *(tPArray+(i-1)+(j)*myPWidth)
				 +*(tPArray+(i-1)+(j+1)*myPWidth));
			  //horizontal edge
			  vy=*(tPArray+(i-1)+(j+1)*myPWidth)+ 2 * *(tPArray+(i)+(j+1)*myPWidth)
				 +*(tPArray+(i+1)+(j+1)*myPWidth)-
				 (*(tPArray+(i-1)+(j-1)*myPWidth)+ 2 * *(tPArray+(i)+(j-1)*myPWidth)
				 +*(tPArray+(i+1)+(j-1)*myPWidth));

			  if(!(vx==0 && vy==0))//this point's gradient is not 0
			  {
				  tf=atan2(vy,vx);
				  if(tf<0)
						tf+=PI;//

				  ti=int(tf*180/PI);
				  if(ti==180)
					  ti=0;
				  fany[ti]++;
			  }/**/

			  
			  //vx=vx*2.55;
			  //vy*=2.55;
			  v=(int)sqrt(vx*vx+vy*vy);	

			  if(v>255)//
				   v=255;
			
			  *(myPArray+i+j*myPWidth)=RGB(v,v,v);

			  //eye extraction
			  /*if(v>50&& *(tPArray+j*myPWidth+i)<thresh)
				  *(myPArray+i+j*myPWidth)=RGB(255,0,255);
			  else
				  *(myPArray+i+j*myPWidth)=RGB(255,255,255);//*/


			   *(gradient+i+j*myPWidth)=v;
		}

	delete []tPArray;
}

bool ImagePr::IsDebugSkinClassify=false;

void ImagePr::skinclassify()
{
/*
** function name: skinclassify()
** function description: postprocessing after skin pixels classification,
** global varible-- myHSIArray,myPArray,gFlag
** call block: Dilate(),Erosion(),
** founder: Li Xuewei
** date:    2003
** mender:  Li Xuewei
** date: 
** version: 1.0
*/
	int	R,G,B;
	int j,i;
	bool *flag; // record if the pixel is skin pixel.

	COLORREF * Temp_myPArray;
	Temp_myPArray= new COLORREF[myPHeight*myPWidth];

	flag=new bool[myPHeight*myPWidth];

	IsDebugSkinClassify=true;

//classify the skin region and non-skin region.

//	
	//HistEqulization();
FirstClassify();
//	TestClassify(); //not good for shadow

	for(i=0; i<myPHeight; i++)///*
	{
		for (j=0; j<myPWidth; j++)
		{
			*(flag+i*myPWidth+j)=*(gFlag+i*myPWidth+j);
		}
	}

//***********	remove the single pixel	****************	

	int R1,G1,B1,R2,G2,B2,R3,G3,B3,R4,G4,B4;

	for(i=1; i<myPHeight-1; i++)
	{
		for (j=1; j<myPWidth-1; j++)
		{
			R=GetRValue(myPArray[i*myPWidth+j]);
			G=GetGValue(myPArray[i*myPWidth+j]);
			B=GetBValue(myPArray[i*myPWidth+j]);

			R1=GetRValue(myPArray[(i-1)*myPWidth+j]);
			G1=GetGValue(myPArray[(i-1)*myPWidth+j]);
			B1=GetBValue(myPArray[(i-1)*myPWidth+j]);

			R2=GetRValue(myPArray[i*myPWidth+j-1]);
			G2=GetGValue(myPArray[i*myPWidth+j-1]);
			B2=GetBValue(myPArray[i*myPWidth+j-1]);

			R3=GetRValue(myPArray[(i+1)*myPWidth+j]);
			G3=GetGValue(myPArray[(i+1)*myPWidth+j]);
			B3=GetBValue(myPArray[(i+1)*myPWidth+j]);

			R4=GetRValue(myPArray[i*myPWidth+j+1]);
			G4=GetGValue(myPArray[i*myPWidth+j+1]);
			B4=GetBValue(myPArray[i*myPWidth+j+1]);

			if((R+G+B)==765&&((R1+G1+B1)!=765&&(R2+G2+B2)!=765&&(R3+G3+B3)!=765&&(R4+G4+B4)!=765))
			{
				//*(Temp_myPArray+i*myPWidth+j)=RGB((R1+R2+R3+R4)/4,(G1+G2+G3+G4)/4,(B1+B2+B3+B4)/4);
				*(Temp_myPArray+i*myPWidth+j)=RGB(R,G,B);
				*(gFlag+i*myPWidth+j)=true;
				*(flag+i*myPWidth+j)=true;
			}
		}
	}
	
	
//*****************close operation***********************//
//connected the unconnected regions
		
	int size;//  2*size-1 is the structure element's size. 

	//firstly,remove the pixel if there is less than 12 skin pixels in it's 5*5 adjcent region.
/*	int subi,subj;
	int count;
	size=2;
	for(i=size; i<myPHeight-size; i++)//size=2
	{
		for (j=size; j<myPWidth-size; j++)
		{
			count=0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -