📄 imagepr.cpp
字号:
for(subi=i-size;subi<=i+size;subi++)//for a 5*5 region
{
for(subj=j-size;subj<=j+size;subj++)
count+=*(flag+subi*(int)myPWidth+subj);
}
if(count>(2*size+1)*(2*size+1)/2)
*(gFlag+i*myPWidth+j)=true;
else
*(gFlag+i*myPWidth+j)=false;
}
}//*/
DilateFactor=new bool[myPWidth*myPHeight];
for(i=0;i<myPHeight;i++)
for(j=0;j<myPWidth;j++)
*(DilateFactor+i*myPWidth+j)=0;
size=1;//2*size+1 is the structure element's size.
dilate(size,gFlag); //dilate(size,gFlag);
erosion(size,gFlag); //erosion(size,gFlag);
//********** open operation ****************************
//used to remove the elments that less than strcture.
erosion(size,gFlag);
dilate(size,gFlag);///**/
/*size=3;//2*size+1 is the structure element's size.
dilate(Temp_myPArray,size);
erosion(Temp_myPArray,size); */
//************* remove the small region *****************//
//******* if the standard deviation of a pixel's 8*8 block
// less than a certain threshhold,then remove it *********
//by Kwok-Wai Wong.
/*size=3;//
int t; //temperoary varible
double avrint,sd; //average intensity,standard deviation.
for(i=0; i<myPHeight; i++)//refresh flag.
{
for (j=0; j<myPWidth; j++)
{
*(flag+i*myPWidth+j)=*(gFlag+i*myPWidth+j);
}
}
for(i=size; i<(int)myPHeight-size; i++)
{
for (j=size; j<(int)myPWidth-size; j++)
{
if(*(flag+i*myPWidth+j)==true)
{
avrint=0;
count=0;//record the number of skin pixels of adjacent region.
for(subi=i-size;subi<=i+size;subi++)//for a 5*5 region
{
for(subj=j-size;subj<=j+size;subj++)
{
t=*(flag+subi*myPWidth+subj)==true?(int)myHSIArray[subi*myPWidth+subj].I:0;
count+=*(flag+subi*myPWidth+subj);
avrint+=t;
}
}
avrint/=count;
//compute the standard deviation
sd=0;
for(subi=i-size;subi<=i+size;subi++)//for a 5*5 region
{
for(subj=j-size;subj<=j+size;subj++)
{
if (*(flag+subi*myPWidth+subj))
{
t=(int)myHSIArray[subi*myPWidth+subj].I;
sd+=(t-avrint)*(t-avrint);
}
}
}
sd=pow(sd/count,0.5);//average intensity distance?
if(sd<1.5)//
//this value is estimated.
//if it is too small ,then no result,
//but if too big ,some face will be removed.
*(gFlag+i*myPWidth+j)=false;
}
}
}//*/
/* size=2; // filter the bw image by pixel density
int t; //temperoary variable
for(i=0; i<myPHeight; i++)//refresh flag.
{
for (j=0; j<myPWidth; j++)
{
*(flag+i*myPWidth+j)=*(gFlag+i*myPWidth+j);
}
}
count=0;
for(i=size; i<myPHeight-size; i++)
{
for (j=size; j<myPWidth-size; j++)
{
if(*(flag+i*myPWidth+j)==true)
{
t=0;//record the number of skin pixels of adjacent region.
for(subi=i-size;subi<=i+size;subi++)//for a 5*5 region
{
for(subj=j-size;subj<=j+size;subj++)
{
t+=*(flag+subi*myPWidth+subj);
}
}
if( t < 20 )//size*size/2
{
*(gFlag+i*myPWidth+j)=false;
count++;
}
}
}
}//*/
//***************** display the final result. ****************/
for(i=0; i<myPHeight; i++)
{
for (j=0; j<myPWidth; j++)
{
R=GetRValue(RGBImage[i*myPWidth+j]);//Temp_myPArray
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);
}
} //*/
delete []Temp_myPArray;
delete []flag;
}
void ImagePr::IngSheen()
{
/*
** function name: IngSheen()
** function description: skin pixels classification using IngSheen's algorithm
** global varible-- myHSIArray,myPArray
** call block: none
** founder: Li Xuewei
** date: 2003
** mender: Li Xuewei
** date:
** version: 1.0
*/
double R,G,B;
int j,i;
int h;
double s;
double i1,i2,i3;
double v;
for(i=0; i<myPHeight; i++)
{
for (j=0; j<myPWidth; j++)
{
R=GetRValue(RGBImage[i*myPWidth+j]);
G=GetGValue(RGBImage[i*myPWidth+j]);
B=GetBValue(RGBImage[i*myPWidth+j]);
i1=(R+G+B)/3;// by Ing-Sheen Hsieh
i2=(R-B)/2;
i3=(2*G-R-B)/4;
s=sqrt(i2*i2+i3*i3);
v=atan2(i3,i2);
if(v<0)
v+=2*PI;
h=(int)(v*180/PI);
if( (h>=1&&h<=28&& s>=13&& s<=110)
||(h>=332&&h<=360&& s>=13&& s<=110)
||(h>=309&&h<=331&& s>=13&& s<=75))
*(myPArray+i*myPWidth+j)=RGB((double)R,(double)G,(double)B);
else
*(myPArray+i*myPWidth+j)=RGB(255,255,255);
}
}
}
void ImagePr::dilate( int size,bool *gFlg)
{
/*
** function name: dilate(COLORREF *Tp, int size)
** input:Tp, size
** Tp--image matrix
** size--define the SE's scale.
** output:changed gFlag
** function description: dilate the image using defined SE by size.
** global varible-- myHSIArray,myPArray,gFlag
** call block: none
** founder: Li Xuewei
** date: 2003
** mender: Li Xuewei
** date:
** version: 1.0
*/
int subi,subj;
int i,j;
bool *flag;
flag=new bool[myPHeight*myPWidth];
for(i=0; i<myPHeight; i++)//flag is mid-varity,so must be refresh before used.
{
for (j=0; j<myPWidth; j++)
{
*(flag+i*myPWidth+j)=*(gFlg+i*myPWidth+j);
//*(DilateFactor+i*myPWidth+j)=*(gFlg+i*myPWidth+j);
}
}
for(i=size; i<myPHeight-size; i++)
{
for (j=size; j<myPWidth-size; j++)
{
if(*(flag+i*myPWidth+j)==true)
{//once a pixel is a skin pixel,then its 8-connected pixels be set to be skin pixels.
for(subi=i-size;subi<=i+size;subi++)//for a 3*3 region
for(subj=j-size;subj<=j+size;subj++)
{
*(gFlg+subi*myPWidth+subj)=true;
}
}
}
}
delete []flag;
}
void ImagePr::erosion(int size,bool *gFlg)//size decided the window's magnitude,ex.3*3 or 5*5.
{ // erosion(COLORREF *Tp, int size,bool *gflg)
/*
** function name: erosion(COLORREF *Tp, int size)
** input:Tp, size
** Tp--image matrix
** size--define the SE's scale.
** output:changed gFlag
** function description: erosion the image using defined SE by size.
** global varible-- myHSIArray,myPArray,gFlag
** call block: none
** founder: Li Xuewei
** date: 2003
** mender: Li Xuewei
** date:
** version: 1.0
*/
int subi,subj;
int i,j;
int count;
bool *flag;
flag=new bool[myPHeight*myPWidth];
for(i=0; i<myPHeight; i++)//flag is mid-varity,so must be refresh before used.
{
for (j=0; j<myPWidth; j++)
{
*(flag+i*myPWidth+j)=*(gFlg+i*myPWidth+j);
}
}
//for every pixel,if not all of it's 8-connected region are skin pixels,
//then it be made non-skin.
for(i=size; i<myPHeight-size; i++)
{
for (j=size; j<myPWidth-size; j++)
{
if(*(flag+i*myPWidth+j)==true)
{
count=0;
for(subi=i-size;subi<=i+size;subi++)//if size=1,for a 3*3 region
for(subj=j-size;subj<=j+size;subj++)
{
count+=*(flag+subi*myPWidth+subj);
}
if(count<(2*size+1)*(2*size+1))
{
*(gFlg+i*myPWidth+j)=false;
}
}
}
}
delete []flag;
}
void ImagePr::FirstClassify()
{
/*
** function name: FirstClassify()
** function description: classify the skin form image the first time by HSI threshhold
** global varible-- myHSIArray,myPArray,gFlag
** call block: none
** founder: Li Xuewei
** date: 2003.3
** mender: Li Xuewei
** date: 2003.8.12
*/
int R,G,B;
int j,i;
int h,ii;
double s;
gFlag=new bool[myPHeight*myPWidth];
//postprocess();
//visionImage();
// HistEqulization();
//classify the skin region and non-skin region.
for(i=0; i<myPHeight; i++)
{
for (j=0; j<myPWidth; j++)
{
R=GetRValue(RGBImage[i*myPWidth+j]);
G=GetGValue(RGBImage[i*myPWidth+j]);
B=GetBValue(RGBImage[i*myPWidth+j]);
h=(int)myHSIArray[i*myPWidth+j].H;
s=myHSIArray[i*myPWidth+j].S;
ii=(int)myHSIArray[i*myPWidth+j].I;
// ii=*(EqualizInten+i*myPWidth+j);
*(gFlag+i*myPWidth+j)=true;
if(ii>45 ) //&& *(tflg+i*myPWidth+j)
{
if(ii>=220) //highlight region: >230
{//
if(!((h>270&&h<=360||h>0 && h<72)&&s>0.04&& s<0.30 ))//&&G>=B
*(gFlag+i*myPWidth+j)=false;
else
{
*(myPArray+i*myPWidth+j)=RGB(R,G,B);//0,255,255
}
}
else if(ii>=96) //normal region: 96--230
{
if (!(((h>=345&&h<=360||h>0 &&h<42)&&( s>0.06&& s<0.40))
||((ii<175&&s>0.40&&s<=0.99)&&(h>5&&h<70)&&R-G<90)))//for pure yellow
*(gFlag+i*myPWidth+j)=false;
else
{
*(myPArray+i*myPWidth+j)=RGB(R,G,B);//255,0,255
}
}
else //dark region 40-96
{//
if(!((h>0&&h<35||h>=330&&h<=360)&& (s>0.10 && s<1.00)&& R-G<90))
*(gFlag+i*myPWidth+j)=false;
else
{
*(myPArray+i*myPWidth+j)=RGB(R,G,B);//255,0,0
}
}
}
else
*(gFlag+i*myPWidth+j)=false;
if(*(gFlag+i*myPWidth+j)==false)
*(myPArray+i*myPWidth+j)=RGB(255,255,255);
else
/*if(*(FilterFlag+i*myPWidth+j))
{
*(gFlag+i*myPWidth+j)=false;
*(myPArray+i*myPWidth+j)=RGB(255,255,255);
}*/
;
//*(myPArray+i*myPWidth+j)=RGB((double)R,(double)G,(double)B);
}
}
}
void ImagePr::SmallRegionDel()
{
/*
** function name: SmallRegionDel()
** function description: remove the small or similar intensity regions.
** global varible-- myHSIArray,myPArray,gFlag,RegionLabel,
** output:changed gFlag,RegionLabel,i.e. for those deleted regions
** call block: RegionLabeling()
** founder: Li Xuewei
** date: 2003
** mender: Li Xuewei
** date: 2003.8.12
*/
//get the start time
start=clock();
//skin classification
skinclassify();
// FilterFeature();
//labeling the region
RegionLabeling();
//LabelByPixel();
orig_label=NumOfLabel;//record the original number of labels.
GetCentroid();
//************* delete the small region and find the centroid of every region *************
int i,j,label;
int dRegion=0; ///* record the number of deleted regions.
short t;
double *avrInt,*sd; //average intensity and standard deviation.
avrInt=new double[NumOfLabel];
sd=new double[NumOfLabel];
for(label=1;label<=NumOfLabel;label++)//initialize
{
avrInt[label-1]=0;
sd[label-1]=0;
}
for(i=1;i<=myPHeight-2;i++)
{
for(j=1;j<=myPWidth-2;j++)
{
if(*(RegionLabel+i*myPWidth+j)==label)
{
avrInt[label-1]+=myHSIArray[i*myPWidth+j].I;//
}
}
}
//compute the average intensity.
for(label=1;label<=NumOfLabel;label++)
{
avrInt[label-1]/=Rsum[label-1];
}
//compute the deviation of intensity
for(i=1;i<=myPHeight-2;i++)
{
for(j=1;j<=myPWidth-2;j++)
{
label=*(RegionLabel+i*myPWidth+j);
if(label>0)
{
t=myHSIArray[i*myPWidth+j].I;
sd[label-1]+=pow(t-avrInt[label-1],2);
}
}
}
//remove the small and those regions have similar intensity.
for(label=1;label<=NumOfLabel;label++)
{
sd[label-1]=pow(sd[label-1]/Rsum[label-1],0.5);
if(Rsum[label-1]<300 || sd[label-1]<16) //360 is the threshhold
{
Rsum[label-1]=0;
IntCentdx[label-1]=0;//
IntCentdy[label-1]=0;//
dRegion++;
}
}
for(i=1;i<=myPHeight-2;i++)
{
for(j=1;j<=myPWidth-2;j++)
{
label=*(RegionLabel+i*myPWidth+j);
if(Rsum[label-1]==0)//remove this region's label
{
*(gFlag+i*myPWidth+j)=false;
*(RegionLabel+i*myPWidth+j)=0;
}
}
}
delete []sd;
delete []avrInt;//*/
display();
//g_delregion=dRegion;
//get the end time
finish=clock();
delete []RegionLabel;//allocate in RegionLabeling();
}
void ImagePr::RegionLabeling()
{
// int RegionLabeling(bool *gFlag,short *RegionLabel,int connect)
/*
** purpose: for every connected regions,give it a label.
** global varible-- myPArray,gFlag,RegionLabel
** input: connectivity = 4 or 8, gFlag, defined RegionLabel array pointer.
** output: get every Region's label value
** founder: Li Xuewei
** date: 2003
** mender: Li Xuewei
** date:
** version: 1.0
*/
//skinclassify();
int i,j,chg1,chg2;
int Label;
RegionLabel=new short [myPHeight*myPWidth];
for(i=0; i<myPHeight; i++) //initialize
{
for (j=0; j<myPWidth; j++)
{
*(RegionLabel+i*myPWidth+j)=0;
}
}
/*********** detect the first skin pixels of a region *************/
int connect=8; //define the connectivity
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) && *(RegionLabel+i*myPWidth+j)==0)
// if unlabeled,then start to label a new region
{
*(RegionLabel+i*myPWidth+j)=Label;
goto labeling;
}
}
NumOfLabel=Label-1;
return;
labeling:
//propogation labeling
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -