📄 imagepr.cpp
字号:
for(label=1;label<=NumOfLabel;label++)
{
if(IntCentdx[label-1]>0)
{
I1[label-1]=(mu20[label-1]+mu02[label-1])
+(LONGLONG)sqrt(pow(mu20[label-1]-mu02[label-1],2)+4*pow(mu11[label-1],2));
I1[label-1]/=2;
I2[label-1]=(mu20[label-1]+mu02[label-1])
-(LONGLONG)sqrt(pow(mu20[label-1]-mu02[label-1],2)+4*pow(mu11[label-1],2));
I2[label-1]/=2;
theta[label-1]=atan2(2*mu11[label-1],mu20[label-1]-mu02[label-1])/2;
a[label-1]=int(2*sqrt(double(I1[label-1]/mu00[label-1])));
b[label-1]=int(2*sqrt(double(I2[label-1]/mu00[label-1])));
}
}
delete []mu00;
delete []mu11;
delete []mu02;
delete []mu20;
delete []I1;
delete []I2;
}
void ImagePr::RegionDescription()
{ //in face , this procedure is not used.
/*
** function name: RegionDescription()
** purpose: to save the memory space, give the non-zero(skin) values
to its corresponding region
** global varible-- myPArray,gFlag,RegionLabel
** input: all the segmented and labeled regions.
** output: every region's pixels' coordinates and every region's label
** call block: MomentDescription()
** founder: Li Xuewei
** date: 2003
** mender: Li Xuewei
** date:
*/
MomentDescription();//to be separated.
REGION *Region;
Region=new REGION[NumOfLabel-g_delregion];// remainded regions.
if(NumOfLabel-g_delregion==0)
{
AfxMessageBox("there is no SKIN candidate regions remained!");
return;
}
int sum,count;
int i,j;
int label;
int lc=0;
for(label=1;label<=NumOfLabel;label++)//orig_label
{
if(IntCentdx[label-1]>0)//this labeled region remainded.
{
Region[lc].sumOfPixels=Rsum[label-1];
Region[lc].Centroidcol=IntCentdx[label-1];
Region[lc].Centroidrow=IntCentdy[label-1];
Region[lc].label=lc;//label;
sum=Rsum[label-1];
Region[lc].col=new int[sum];
Region[lc].row=new int[sum];
count=0;
for(i=1;i<=(int)myPHeight-2;i++)
{
for(j=1;j<=(int)myPWidth-2;j++)
{//&&count<=sum
if(*(RegionLabel+i*myPWidth+j)==label)
{
(Region[lc].col)[count]=j;
(Region[lc].row)[count]=i;
count++;
}
}
}
lc++;
}
}
NumOfLabel=lc;//the number of regions in fact.
//lc=0; //a test number./*
int cl,rw;
for(lc=0;lc<NumOfLabel;lc++)
{
for(i=0;i<Region[lc].sumOfPixels;i++)
{
cl=(Region[lc].col)[i];
rw=(Region[lc].row)[i];
*(myPArray+rw*myPWidth+cl)=RGB(0,0,0);
}
}
delete []RegionLabel;//may be not.
delete []IntCentdx; //allocate in GetCentroid().
delete []IntCentdy; //
delete []Rsum; //
}
void ImagePr::RemoveByMoment()
{
/*********** 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. ***********************/
int label;
int count; ///*
bool condflag1,condflag2,condflag3;
//get every region's edge
short *EdgePixel;
EdgePixel=new short[myPHeight*myPWidth];
int i,j;
for(i=1; i<myPHeight-1; i++)
{
for (j=1; j<myPWidth-1; j++)
{
*(EdgePixel+i*myPWidth+j)=0;
if(*(gFlag+i*myPWidth+j)==true)
{
count=0;
count+=*(gFlag+(i-1)*myPWidth+j-1)+*(gFlag+(i-1)*myPWidth+j)
+*(gFlag+(i-1)*myPWidth+j+1)
+*(gFlag+i*myPWidth+j-1)+*(gFlag+i*myPWidth+j+1)
+*(gFlag+(i+1)*myPWidth+j-1)+*(gFlag+(i+1)*myPWidth+j)
+*(gFlag+(i+1)*myPWidth+j+1);
if(count<8)
{
*(EdgePixel+i*myPWidth+j)=*(RegionLabel+i*myPWidth+j);
}
}
}
}
//judge the above three conditions.
double dis1,dis2,dis0;//
int i0,j0;//centroid coordinate
int il,jl;//(i,j) is one pixel in a region,(il,jl) is a intersect point
double k;//slope of ellipse
g_delregion=0;//record the number of region that deleted.
int maxregion=0;
for(label=1;label<=NumOfLabel;label++)
{
if(maxregion<Rsum[label-1])
maxregion=Rsum[label-1];
}
for(label=1;label<=NumOfLabel;label++)
{
condflag1=false;
condflag2=false;
condflag3=false;
if(IntCentdx[label-1]>0) //this region is remained.
{
//condition 1.Rsum[label-1]<2000 &&
//rectangle degree
if(double(a[label-1])/double(b[label-1]) >4.3
|| (double(maxregion)/double(Rsum[label-1])>5)&&Rsum[label-1]<500
|| double(Rsum[label-1])/double(a[label-1]*b[label-1])<0.6 )
{
condflag1=true;//
}
//condition 2.
count=0;
for(i=1;i<=(int)myPHeight-2;i++)
{
for(j=1;j<=(int)myPWidth-2;j++)
{
if(*(EdgePixel+i*myPWidth+j)==label)
count++; //perimeter
}
}
if(Rsum[label-1]<160|| Rsum[label-1]<800 && 4*PI*Rsum[label-1]/(count*count)<0.3)
{//compute the region's simple scale of shape.
condflag2=true;
}
//condition 3.
count=0;//the number of points that fall into ellipse.
i0=IntCentdy[label-1]; //row centroid
j0=IntCentdx[label-1]; //col centroid
k =atan(theta[label-1]); //slope value
for(i=1;i<=(int)myPHeight-2;i++)
{
for(j=1;j<=(int)myPWidth-2;j++)
{
if(*(RegionLabel+i*myPWidth+j)==label)
{//compute the number of points that lies in the ellipse.
//intersection point between the plumb line passed (i,j) and the slope line passed (i0,j0)
jl=int(k*(i-j/k-i0+k*j0)/(1+k*k));
il=int(k*jl+i0-k*j0);
//get the absolute distance along the ellipse's x and y axis.
dis0=(j-jl)*(j-jl)+(i-il)*(i-il);//y axis
dis2=(j-j0)*(j-j0)+(i-i0)*(i-i0);
dis1=dis2*dis2-dis0*dis0;//x axis
if(dis1/pow(a[label-1],2)+dis0/pow(b[label-1],2)<=1)
count++;
}
}
}
if(Rsum[label-1]<3000 && (double)count/(double)Rsum[label-1]<0.7) //ellipse'area-region's area ratio
{
condflag3=true;//
}
//judgement
if(condflag1||condflag2||condflag3)
{
IntCentdx[label-1]=0;
IntCentdy[label-1]=0;
Rsum[label-1]=0;
g_delregion++;
for(i=1;i<=myPHeight-2;i++)
{
for(j=1;j<=myPWidth-2;j++)
{
if(*(RegionLabel+i*myPWidth+j)==label)//remove this region's label
{
*(gFlag+i*myPWidth+j)=false;
*(RegionLabel+i*myPWidth+j)=0;
}
}
}
}
}
}
delete []EdgePixel;//*/
}
int ImagePr::LabelByPixel(int *RegionL,bool *gFlg)
{
/*****************************************************************
** function name: LabelByPixel(int *RegionL,bool *gFlg)
** purpose: in this method,linklist is used to store the minimum equivalent label,
when find equivalent labels by scanning every pixels,then the great one
will be treat as the index,while the smaller one as the reference label.
i.e. this method find the smaller label's minimum equivalent label to
be the great one's equivalent label.
** global varible-- myPArray,gFlag,RegionLabel
** input: RegionL is the allocated array pointer,gFlg is global varible that
define whether a pixel is a skin pixel.
** output: every region's label, stored in RegionL
** call block: none,but must be execuated after skinclassify()
** founder: Li Xuewei
** date: 5,13, 2003
** mender: Li Xuewei
** date: 5,24, 2003
** note: because the default connectivity=4, in background region
labeling process,the connectivity must equal to 8.
*/
//skinclassify();
int i,j;
typedef struct equlist
{
int label1;//index
int label2;//the equivalence label in fact.
equlist *next;
}EQULIST;
EQULIST *phead=NULL,*p,*s,*pt,*subpt;
//initialize the equivalent table.
phead=new EQULIST[1];
phead->label1=-1;//head node's data is -1;
phead->label2=-1;
phead->next=NULL;
p=phead;//p point to current node.
bool *flag;
flag= new bool [myPHeight*myPWidth];
//RegionLabel=new short [myPHeight*myPWidth];
for(i=0; i<myPHeight; i++) //initialize
{
for (j=0; j<myPWidth; j++)
{
*(RegionL+i*myPWidth+j)=0;
*(flag+i*myPWidth+j)=*(gFlg+i*myPWidth+j);
}
}
for(i=0; i<myPHeight; i++)//the first pixel of every row is zero.
{
*(flag+i*myPWidth)=0;
}
int t_up,t_left,t,tl;//current pixel's up and left label value.
int label=1;
for(i=1; i<myPHeight-1; i++)
{
for(j=1;j<myPWidth-1;j++)
{
if(*(flag+i*myPWidth+j)) //4-connected.
{
t_up=*(RegionL+(i-1)*myPWidth+j);
t_left=*(RegionL+i*myPWidth+j-1);
// one of the two adjacent pixel is labeled.
if(t_up>0&& t_left==0)
{
*(RegionL+i*myPWidth+j)=t_up;
continue;
}
if(t_up==0 && t_left>0)
{
*(RegionL+i*myPWidth+j)=t_left;
continue;
}
//both are labeled,but are differnt,then same labeled with up point
if(t_up>0 && t_left>0 && t_up!=t_left)
{
*(RegionL+i*myPWidth+j)=min(t_up,t_left);//t_left;
//if the pair of label is existed,then jump.
pt=phead->next;
while(pt->next &&pt->label1!=max(t_up,t_left))
{
pt=pt->next;//pt is current node.
}
if(min(t_up,t_left)==1)
pt->label2=1;
else
{
subpt=pt;
s=phead->next;
t=min(t_up,t_left);
//tl=t;
//looking for forward until find the minimum label.
while(s && s!=subpt)
{
if(s->label1==t)
{
if(s->label1==s->label2)
{
tl=s->label2;//minimum label;
break;
}
else
{//this label isn't the minimum,so find again.
subpt=s;
t=s->label2;
s=phead->next;
}
}
else
s=s->next;
}//end-while
if(pt->label2 > min(t_up,t_left))//equivalence label is minimum forever.
{
s=phead->next;
while(s)
{
if(s->label2==pt->label2)
s->label2=tl;//take tl instead of all the pt->label2.
s=s->next;
}
pt->label2=tl;
}
else
{
if(tl>pt->label2)
{
s=phead->next;
while(s)
{
if(s->label2==tl)
s->label2=pt->label2;
s=s->next;
}
}
else
{
s=phead->next;
while(s)
{
if(s->label2==pt->label2)
s->label2=tl;
s=s->next;
}
}
//pt->label2 remains original value.
}
}
}
//both are same labeled.
if(t_up>0 && t_up==t_left)
{
*(RegionL+i*myPWidth+j)=t_up;
continue;
}
//both are not labeled.
if(t_up==0 && t_left==0)
{
*(RegionL+i*myPWidth+j)=label;
s=new equlist[1];
s->label1=label;
s->label2=label;
s->next=p->next;
p->next=s;
p=p->next;// p is the current node.
label++;
}
}
}
}
int NUMLABEL=label-1;
int *total_label;
total_label=new int[NUMLABEL+1];//all label's array,the element's value is this label's equivalence label.
s=phead->next;
i=1;
total_label[0]=0;
while(s)
{
total_label[i]=s->label2;//No.i label's equivalence label.
i++;
s=s->next;
}
int count=0;
s=phead->next;
count=0;
EQULIST *finallabel,*f,*ft,*fp;
f=new equlist[1];
f->next=NULL;
f->label1=f->label2=0;
finallabel=f;
//varibility
bool f2;
while(s)//record the remained labels.
{
fp=finallabel;
f2=false;
while(fp)
{
if(s->label2==fp->label1)
{
f2=true;
}
fp=fp->next;
}
if(!f2)
{
count++;
ft=new equlist[1];
ft->label1=s->label2;
ft->label2=0;
ft->next=f->next;
f->next=ft;
f=ft; //f is current node.
}
s=s->next;
}
int *plabel;
plabel=new int[count];//store the final (factual) label.
fp=finallabel->next;
int number=0;
while(fp)
{
plabel[number]=fp->label1;
fp=fp->next;
number++;
}
//display the result.
int l; //the 2nd scanning.
for(i=0; i<=myPHeight-1; i++)
{
for(j=0;j<=myPWidth-1;j++)
{
if(*(RegionL+i*myPWidth+j)!=0)
{
t=*(RegionL+i*myPWidth+j);//t is the index.
*(RegionL+i*myPWidth+j)=total_label[t];//equivalence minimum label.
}
}
}
//of course,the following codes can be deleted,
//because the region label information are stored in the plabel array.
int *tempLabel;
tempLabel=new int[myPHeight*myPWidth];
for(i=0; i<=myPHeight-1; i++)
{
for(j=0;j<=myPWidth-1;j++)
{
*(tempLabel+i*myPWidth+j)=*(RegionL+i*myPWidth+j);
}
}
/* for(l=0;l<number;l++)//need to be improved
{
for(i=0; i<=myPHeight-1; i++)
{
for(j=0;j<=myPWidth-1;j++)
{
if(*(tempLabel+i*myPWidth+j)==plabel[l])
{
*(RegionL+i*myPWidth+j)=l+1; //factual used label value.
}
}
}
}// /**/
//get the region labeled from index 1,because the original label is discrete.
for(i=0; i<=myPHeight-1; i++)//estimate:save about one half time.
{
for(j=0;j<=myPWidth-1;j++)
{
if(*(tempLabel+i*myPWidth+j)>0)
{
for(l=0;l<number;l++)
if(*(tempLabel+i*myPWidth+j)==plabel[l])
{
*(RegionL+i*myPWidth+j)=l+1; //factual used label value.
break;
}
}
}
}//*/
delete []tempLabel;
delete []flag;
delete phead;
delete finallabel;
delete []plabel;
delete []total_label;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -