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

📄 imagepr.cpp

📁 一个基于知识的人脸检测系统
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		chg1=0;chg2=0;

		//normal order propogation
		for(i=1;i<myPHeight-1;i++)
		{
			for(j=1; j<myPWidth-1; j++)
			{
				if(!(*(gFlag+i*myPWidth+j)) || *(RegionLabel+i*myPWidth+j)!=0 )
					continue;
				if(connect==8)//8-connected
				{  //for every unlabeled skin pixels
					if((*(RegionLabel+(i-1)*myPWidth+j-1)==Label)||(*(RegionLabel+(i-1)*myPWidth+j)==Label)
						||(*(RegionLabel+(i-1)*myPWidth+j+1)==Label)||(*(RegionLabel+i*myPWidth+j-1)==Label))
					{
						*(RegionLabel+i*myPWidth+j)=Label;
						chg1=1;
					}
				}
				else  //4-connected
				{
					if(*(RegionLabel+(i-1)*myPWidth+j)==Label||*(RegionLabel+i*myPWidth+j-1)==Label)
					{
						*(RegionLabel+i*myPWidth+j)=Label;
						chg1=1;
					}
				}
			}
		}

		if(chg1==0)// normal order scan ended for a certain region.
		{
			Label++;
			goto next;
		}

		//reverse propogation
		for(i=(int)myPHeight-2;i>=1;i--)
		{
			for(j=(int)myPWidth-2;j>=1;j--)
			{
				if(!(*(gFlag+i*myPWidth+j)) || *(RegionLabel+i*myPWidth+j)!=0 )
					continue;
				if(connect==8)//8-connected
				{
					if(*(RegionLabel+(i+1)*myPWidth+j+1)==Label||*(RegionLabel+(i+1)*myPWidth+j)==Label
						||*(RegionLabel+(i+1)*myPWidth+j-1)==Label||*(RegionLabel+i*myPWidth+j+1)==Label)
					{
						*(RegionLabel+i*myPWidth+j)=Label;
						chg2=1;
					}
				}
				else  //4-connected
				{
					if(*(RegionLabel+(i+1)*myPWidth+j)==Label||*(RegionLabel+i*myPWidth+j+1)==Label)
					{
						*(RegionLabel+i*myPWidth+j)=Label;
						chg2=1;
					}
				}
			}
		}

		if(chg2==0)//back scanning end.
		{
			Label++;
			goto next;
		}
		else //continue back scanning.
			goto labeling;

}

void ImagePr::FillHole()
{
/*
** function name: FillHole()
** purpose: fill all the holes besides the background(that have
   greatest area region)or fill certain area's region.
   BWFILL differs from many other binary image operations in
   that it operates on background pixels, rather than foreground
   pixels. If the foreground is 8-connected, the background is
   4-connected, and vice versa. Note, however, that you specify
   the connectedness of the foreground when you call BWFILL.
** global varible-- myPArray,gFlag,RegionLabel
** output: get every Region's label value
** call block: WhiteRegLabel()
** founder: Li Xuewei
** date:    2003
** mender:  Li Xuewei
** date: 
** version: 1.0
*/

	WhiteRegLabel();

	int label;
	LONG *AreaW;
	AreaW=new LONG[NumOfWhiteReg];

	int i,j;
	LONG maxarea=0;
	int maxlabel;
	for(label=1;label<=NumOfWhiteReg;label++)
	{
		AreaW[label-1]=0;
		for(i=1;i<myPHeight-1;i++)
			for(j=1;j<myPWidth-1;j++)
			{
				if(*(WhiteRegL+i*myPWidth+j)==label)
					AreaW[label-1]++;
			}
		if(AreaW[label-1]>maxarea)
		{
			maxarea=AreaW[label-1];
			maxlabel=label;
		}
	}

	//fill the holes.
	for(label=1;label<=NumOfWhiteReg;label++)
	{
		if(label!=maxlabel && AreaW[label-1]<2000)//300
		{
			for(i=1;i<myPHeight-1;i++)
				for(j=1;j<myPWidth-1;j++)
				{
					if(*(WhiteRegL+i*myPWidth+j)==label)
					{  //fill
						*(gFlag+i*myPWidth+j)=true;
						*(WhiteRegL+i*myPWidth+j)=0;
					}
				}
		}
	}

	//display the result.
	display();//

	delete []AreaW;
	delete []WhiteRegL;
}

void ImagePr::MomentDescription()
{
/**
** function name: FillHole()
** purpose: analysis every region's moment features
** global varible-- myPArray,gFlag,RegionLabel
** output: get every Region's label value
** call block: SmallRegionDel(),FillHole(),RegionLabeling(),GetCentroid(),
   GetMoment(),RemoveByMoment(),display(),FigureEllipse()
** founder: Li Xuewei
** date:    2003
** mender:  Li Xuewei
** date: 
** version: 1.0
*/

	SmallRegionDel();//remove the small area region and those have similiar intensity regions.
	delete []IntCentdx;
	delete []IntCentdy;
	delete []Rsum;/**/


	FillHole();//fill in the small holes

	erosion(1,gFlag); //new in 03.11.29
	dilate(1,gFlag); 
	//dilate(1,gFlag);erosion(1,gFlag);

	RegionLabeling();//label the skin regions again.
	//LabelForPixel();

	GetCentroid(); //get the intensity centroid.

//************ ellipse represent **********************/
//use the concept of moment to get the description of a region's fit ellipse.
	GetMoment();

/*********** remove those regions:
 1. long axes and short axes ratio is too big: >3
 2. those have complex shape (4*PI*S/P*P) :<0.3
 3. the area in ellipse is much smaller than the ellipse and
	this region's area is too small. ***********************/
	
	RemoveByMoment();	
	
//**************** display the result ****************/
	display();

//***********figure the ellipse *********************/
	FigureEllipse();	//freed the a and b and theta.

//************************************/
	SearchSkin();

//display the centroid.
	int label;
	for(label=1;label<=NumOfLabel;label++)
	{
		if(IntCentdx[label-1]>0 && IntCentdy[label-1]>0 )
		{
			//intensity centroid
			*(myPArray+IntCentdy[label-1]*myPWidth+IntCentdx[label-1])=RGB(0,255,255);
			*(myPArray+(IntCentdy[label-1]-1)*myPWidth+IntCentdx[label-1])=RGB(0,255,255);
			*(myPArray+(IntCentdy[label-1]+1)*myPWidth+IntCentdx[label-1])=RGB(0,255,255);
			*(myPArray+IntCentdy[label-1]*myPWidth+IntCentdx[label-1]-1)=RGB(0,255,255);
			*(myPArray+IntCentdy[label-1]*myPWidth+IntCentdx[label-1]+1)=RGB(0,255,255);
		}

	}
	
	//delete []IntCentdx; //allocate in GetCentroid().
	//delete []IntCentdy;
	//delete []Rsum;
}

void ImagePr::WhiteRegLabel()
{//WhiteRegLabel(int *RegionLabel,int connect)
/**
** function name: WhiteRegLabel()
** purpose: for every connected background regions,give it a label.
** global varible-- myPArray,gFlag,RegionLabel
** input: connectivity = 4 if connectivity = 8  in target region labeling.
** output: get every background Region's label value
** founder: Li Xuewei
** date:    2003
** mender:  Li Xuewei
** date: 
** version: 1.0
*/
	int i,j,chg1,chg2;
	int Label;

	WhiteRegL=new BYTE[myPHeight*myPWidth];
	for(i=0;i<(int)myPHeight;i++)
	{
		for(j=0; j<(int)myPWidth; j++)
		{
			*(WhiteRegL+i*myPWidth+j)=0;
		}
	}


/*********** detect the first skin pixels of a region *************/

	int connect=4;	//define the connectivity,differnt from skin regions
	Label=1;	//region tag;

next:	//look for every region
	for(i=1;i<myPHeight-1;i++)
		for(j=1; j<myPWidth-1; j++)
		{
			if(!*(gFlag+i*myPWidth+j) && *(WhiteRegL+i*myPWidth+j)==0)
			// if unlabeled,then start to label a new region
			{
				*(WhiteRegL+i*myPWidth+j)=Label;
				goto labeling;
			}
		}

	NumOfWhiteReg=Label-1;
	return;

labeling:
		//propogation labeling
		chg1=0;chg2=0;

		//normal order propogation
		for(i=1;i<myPHeight-1;i++)
		{
			for(j=1; j<myPWidth-1; j++)
			{
				if(*(gFlag+i*myPWidth+j) || *(WhiteRegL+i*myPWidth+j)!=0 )
					continue;//if it is skin pixel or it is labeled,then jump;
				if(connect==8)//8-connected
				{  
					//for every unlabeled skin pixels
					if((*(WhiteRegL+(i-1)*myPWidth+j-1)==Label)||(*(WhiteRegL+(i-1)*myPWidth+j)==Label)
						||(*(WhiteRegL+(i-1)*myPWidth+j+1)==Label)||(*(WhiteRegL+i*myPWidth+j-1)==Label))
					{
						*(WhiteRegL+i*myPWidth+j)=Label;
						chg1=1;
					}
				}
				else  //4-connected
				{
					if(*(WhiteRegL+(i-1)*myPWidth+j)==Label||*(WhiteRegL+i*myPWidth+j-1)==Label)
					{
						*(WhiteRegL+i*myPWidth+j)=Label;
						chg1=1;
					}
				}
			}
		}

		if(chg1==0)// normal order scan ended for a certain region.
		{
			Label++;
			goto next;
		}

		//reverse propogation
		for(i=myPHeight-2;i>=1;i--)
		{
			for(j=myPWidth-2;j>=1;j--)
			{
				if(*(gFlag+i*myPWidth+j) || *(WhiteRegL+i*myPWidth+j)!=0 )
					continue;
				if(connect==8)//8-connected
				{
					if(*(WhiteRegL+(i+1)*myPWidth+j+1)==Label||*(WhiteRegL+(i+1)*myPWidth+j)==Label
						||*(WhiteRegL+(i+1)*myPWidth+j-1)==Label||*(WhiteRegL+i*myPWidth+j+1)==Label)
					{
						*(WhiteRegL+i*myPWidth+j)=Label;
						chg2=1;
					}
				}
				else  //4-connected
				{
					if(*(WhiteRegL+(i+1)*myPWidth+j)==Label||*(WhiteRegL+i*myPWidth+j+1)==Label)
					{
						*(WhiteRegL+i*myPWidth+j)=Label;
						chg2=1;
					}
				}
			}
		}

		if(chg2==0)//back scanning end.
		{
			Label++;
			goto next;
		}
		else //continue back scanning.
			goto labeling;

}

void ImagePr::display()
{
// display the result 
	int i,j;
	BYTE R,G,B;
	for(i=0; i<myPHeight; i++)
	{
		for (j=0; j<myPWidth; j++)
		{
			R=GetRValue(RGBImage[i*myPWidth+j]);//RGBImage
			G=GetGValue(RGBImage[i*myPWidth+j]);
			B=GetBValue(RGBImage[i*myPWidth+j]);

			if(*(gFlag+i*myPWidth+j)==true)
				*(myPArray+i*myPWidth+j)=RGB(R,G,B);
			else
				*(myPArray+i*myPWidth+j)=RGB(255,255,255);
		}
	} 

}

void ImagePr::GetCentroid()
{
/**
** function name:GetCentroid() 
** purpose: get intensity centroid of every labeled region
** global varible-- myPArray,gFlag,RegionLabel
** input: all the segmented and labeled regions.
** output: centroid,every region's area,
** founder: Li Xuewei
** date:    2003
** mender:  Li Xuewei
** date: 
*/
	int i,j,label;
	Rsum=new int [NumOfLabel];// the area of a region
							  // NumOfLabel is defined in RegionLabeling();
	int dRegion=0; // record the number of deleted regions.

	IntCentdx=new int[NumOfLabel];//record the  region's Intensity centroid.
	IntCentdy=new int[NumOfLabel];

	short ii; //ii is the intensity value.

	int   *avrint; //average intensity 
	avrint=new int[NumOfLabel];

	LONGLONG *sumIntCentdx,*sumIntCentdy;
	sumIntCentdx=new LONGLONG[NumOfLabel];
	sumIntCentdy=new LONGLONG[NumOfLabel];

	for(label=1;label<=NumOfLabel;label++)
	{
		Rsum[label-1]=0;
		avrint[label-1]=0;

		sumIntCentdx[label-1]=0;
		sumIntCentdy[label-1]=0;
	}

	int t;
	for(i=1;i<=myPHeight-2;i++)
	{
		for(j=1;j<=myPWidth-2;j++)
		{
			if(*(RegionLabel+i*myPWidth+j)>0)
			{
				t=*(RegionLabel+i*myPWidth+j);
				ii=(int)myHSIArray[i*myPWidth+j].I; //if ii=1,then for binary image.
				
				sumIntCentdx[t-1]+=j*ii;
				sumIntCentdy[t-1]+=i*ii; //row

				Rsum[t-1]++;	//region area

				avrint[t-1]+=myHSIArray[i*myPWidth+j].I;//
			}
		}
	}

	for(label=1;label<=NumOfLabel;label++)
	{
		IntCentdx[label-1]=int(sumIntCentdx[label-1]/avrint[label-1]);
		IntCentdy[label-1]=int(sumIntCentdy[label-1]/avrint[label-1]);
	}

	delete []sumIntCentdx;
	delete []sumIntCentdy;
	delete []avrint;
	
}

void ImagePr::FigureEllipse()
{
/*
purpose:figure out the ellipse by moment description.
*/
 
	int i0,j0; //the two intensity centroid.
	double theta0;
	int cox,coy; //the row and coloum value.
	int length;

	int label;
	for(label=1;label<=NumOfLabel;label++)//display the ellipse.
	{
		if(IntCentdx[label-1]>0) //this region is remained.
		{
			i0=(int)IntCentdy[label-1];
			j0=(int)IntCentdx[label-1];
			theta0=theta[label-1];
			
			if(sin(theta0)>0.97)//vertical direction
			{
				int t1,t2;

				length=i0-a[label-1]>0?i0-a[label-1]:1;//long
				t1=i0+a[label-1]<myPHeight-1?i0+a[label-1]:(myPHeight-1);
			//	for(;length<=t1;length++) //long axis
				//	*(myPArray+length*myPWidth+j0)=RGB(255,0,255);
				
				length=j0-b[label-1]>0?j0-b[label-1]:1;//short
				t2=j0+b[label-1]<myPWidth-1?j0+b[label-1]:(myPWidth-1);
				//for(;length<=t2;length++) //short axis
					//*(myPArray+i0*myPWidth+length)=RGB(255,255,0);
			}

			else{
			//display the long axis.
			for(length=1;length<=a[label-1]*cos(theta0);length++)//right
			{
				cox=j0+length;
				coy=(int)(i0+tan(theta0)*length);
			//	if(cox>0&& cox<(int)myPWidth && coy>0&& coy<(int)myPHeight)//
				//	*(myPArray+coy*myPWidth+cox)=RGB(255,0,255);
			}
			for(length=1;length<=a[label-1]*cos(theta0);length++)//left
			{
				cox=j0-length;
				coy=(int)(i0-tan(theta0)*length);
				//if(cox>0&&cox<(int)myPWidth &&coy>0&& coy<(int)myPHeight)//
				//	*(myPArray+coy*myPWidth+cox)=RGB(255,0,255);
			}

			//display the short axis.
			
			for(length=1;length<=b[label-1]*cos(theta0);length++)//down
			{
				coy=i0+length;
				cox=(int)(j0-tan(theta0)*length);
				//if(cox>0&&cox<(int)myPWidth &&coy>0&& coy<(int)myPHeight)//
				//	*(myPArray+coy*myPWidth+cox)=RGB(255,255,0);
			}
			for(length=1;length<=b[label-1]*cos(theta0);length++)//up
			{
				coy=i0-length;  //row
				cox=(int)(j0+tan(theta0)*length);//coloum
				//if(cox<(int)myPWidth && cox>0 && coy>0&& coy<(int)myPHeight)//
				//	*(myPArray+coy*myPWidth+cox)=RGB(255,255,0);
			}
			}//else

		}
	}

	//delete []Rsum;

	delete []a;
	//delete []b;
	delete []theta;

}

void ImagePr::GetMoment()
{//see page 8 at book: <moment's function of images>.

/*
** function name:GetMoment() 
** purpose: get moment features of every labeled region
** global varible-- myPArray,gFlag,RegionLabel,IntCentroid,Rsum
** input: all the segmented and labeled regions.
** output: long and short axis,slope angle.
** founder: Li Xuewei
** date:    2003
** mender:  Li Xuewei
** date: 
*/
	//the ellipse's long and short axis.
	a=new int[NumOfLabel];
	b=new int[NumOfLabel];

	LONGLONG *mu20,*mu02,*mu11,*mu00; //center moment
	mu20=new LONGLONG[NumOfLabel]; //64-bit signed integer.
	mu02=new LONGLONG[NumOfLabel];
	mu11=new LONGLONG[NumOfLabel];
	mu00=new LONGLONG[NumOfLabel];

	LONGLONG *I1,*I2; //inertia moment;
	I1=new LONGLONG[NumOfLabel];
	I2=new LONGLONG[NumOfLabel];

	theta=new double[NumOfLabel];//the angle of ellipse.

	int label;
	int i,j;
	short ii;
	for(label=1;label<=NumOfLabel;label++)//initialize
	{
		mu02[label-1]=0;
		mu20[label-1]=0;
		mu11[label-1]=0;
		mu00[label-1]=0;
	}
		
	for(i=1;i<=(int)myPHeight-2;i++)
	{
		for(j=1;j<=(int)myPWidth-2;j++)
		{
			label=*(RegionLabel+i*myPWidth+j);
			if(label>0 && IntCentdx[label-1]>0)//this region is not deleted.
			{
				ii=myHSIArray[i*myPWidth+j].I; 

				mu20[label-1]+=(j-IntCentdx[label-1])*(j-IntCentdx[label-1])*ii;
				mu02[label-1]+=(i-IntCentdy[label-1])*(i-IntCentdy[label-1])*ii;
				mu11[label-1]+=(i-IntCentdy[label-1])*(j-IntCentdx[label-1])*ii;
				mu00[label-1]+=ii;
			}
		}
	}

⌨️ 快捷键说明

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