📄 imagepr.cpp
字号:
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 + -