📄 atrplant.cpp
字号:
#include <stdio.h>
#include <process.h>
#include <stdlib.h>
#include <math.h>
#include "imgproc.h"
/*
main(int argc,char *argv[])
{unsigned char **InImg,**ReferImg,**IniImg;
FILE *fp;
int i;
int InImgRow,InImgCol,ReferImgRow,ReferImgCol,type;
time_t BeginTime,EndTime;
COORDINATE* Left_Up = (COORDINATE *)calloc(1,sizeof(COORDINATE));
COORDINATE* Right_Down = (COORDINATE*)calloc(1,sizeof(COORDINATE));
if(argc!=5)
{printf("\nError Format");
printf("\n Usage Format:MomRec SegImg ReferImg ResultImg IniImg");
exit(1);
}
fp=wfread1(&InImgRow,&InImgCol,&type,argv[1]);
InImg=(unsigned char**)fspace_2d(InImgRow,InImgCol,sizeof(unsigned char));
for(i=0;i<InImgRow;i++) fread(InImg[i],1,InImgCol,fp);
fclose(fp);
*/
/*fp=wfread1(&ReferImgRow,&ReferImgCol,&type,argv[2]);
ReferImg=(unsigned char**)fspace_2d(ReferImgRow,ReferImgCol,sizeof(unsigned char));
for(i=0;i<ReferImgRow;i++) fread(ReferImg[i],1,ReferImgCol,fp);
fclose(fp);*/
/*
fp=wfread1(&InImgRow,&InImgCol,&type,argv[4]);
IniImg=(unsigned char**)fspace_2d(InImgRow,InImgCol,sizeof(unsigned char));
for(i=0;i<InImgRow;i++) fread(IniImg[i],1,InImgCol,fp);
fclose(fp);
BeginTime=time(NULL);
//Recognition(InImg,InImgRow,InImgCol,ReferImg,ReferImgRow,ReferImgCol,argv[3],IniImg);
ShapeRec( InImgRow,InImgCol,InImg, Left_Up,Right_Down);
EndTime=time(NULL);
printf("\nIt spent %d seconds to recognize",EndTime-BeginTime);
for(i=Left_Up->y;i<Right_Down->y;i++)
{
IniImg[i][Left_Up->x]=255;
IniImg[i][Right_Down->x]=255;
}
for(i=Left_Up->x;i<Right_Down->x;i++)
{
IniImg[Left_Up->y][i]=255;
IniImg[Right_Down->y][i]=255;
}
OutputImageWithName(IniImg,InImgRow,InImgCol,argv[3]);
free(Left_Up);free(Right_Down);
ffree_2d((void **)InImg,InImgRow);
ffree_2d((void **)IniImg,InImgRow);
//ffree_2d((void **)ReferImg,ReferImgRow);
return;
}
*/
void Recognition(unsigned char **InImg,short InImgRow,short InImgCol,
unsigned char **ReferImg,short ReferImgRow,short ReferImgCol,
COORDINATE *RecArea_LeftUp, COORDINATE *RecArea_RightDown)
// /* char ResultImgName[20],unsigned char **IniImg*/)
{COORDINATE Left_Up,Right_Down/*,RecArea_LeftUp,RecArea_RightDown*/;
double AreaB[7],ReferB[7];//the moment of the refer image and the area
double MomDvar,MinMomDvar;
unsigned char Gray,**AreaImg;
short i,j,AreaImgRow,AreaImgCol,LabelNum;
Moment(ReferB,ReferImg,ReferImgRow,ReferImgCol);
LabelNum=Label(InImg,InImgRow,InImgCol,LABELMODE_1,50);
// printf("LabelNum=%d\n",LabelNum);
MinMomDvar=1000.0;
RecArea_LeftUp->x=0;
RecArea_LeftUp->y=0;
RecArea_RightDown->x=InImgCol;
RecArea_RightDown->y=InImgRow;
for(Gray=MAXLEVEL;Gray>(MAXLEVEL-LabelNum);Gray--)
{
Right_Down.x=0;
Right_Down.y=0;
Left_Up.x=InImgCol;
Left_Up.y=InImgRow;
for(i=0;i<InImgRow;i++)
for(j=0;j<InImgCol;j++)
{
if(InImg[i][j]==Gray)
{
if(i<Left_Up.y) Left_Up.y=i;
if(i>Right_Down.y) Right_Down.y=i;
if(j<Left_Up.x) Left_Up.x=j;
if(j>Right_Down.x) Right_Down.x=j;
}
}
AreaImgRow=Right_Down.y-Left_Up.y+1;
AreaImgCol=Right_Down.x-Left_Up.x+1;
AreaImg=(unsigned char**)fspace_2d(AreaImgRow,AreaImgCol,sizeof(unsigned char));
for(i=0;i<AreaImgRow;i++)
for(j=0;j<AreaImgCol;j++)
if(InImg[Left_Up.y+i][Left_Up.x+j]==Gray) AreaImg[i][j]=255;
Moment(AreaB,AreaImg,AreaImgRow,AreaImgCol);
MomDvar=0.0;
for( i=1;i<7;i++)
MomDvar += (AreaB[i]-ReferB[i]);
// printf("MomDvar=",MomDvar);
// printf("MomDvar=%f\n",MomDvar);
if(fabs(MomDvar)<MinMomDvar)
{
MinMomDvar=MomDvar;
RecArea_LeftUp->x=Left_Up.x;
RecArea_LeftUp->y=Left_Up.y;
RecArea_RightDown->x=Right_Down.x;
RecArea_RightDown->y=Right_Down.y;
}
}
/*
for(i=RecArea_LeftUp.y;i<RecArea_RightDown.y;i++)
{IniImg[i][RecArea_LeftUp.x]=255;
IniImg[i][RecArea_RightDown.x]=255;
}
for(i=RecArea_LeftUp.x;i<RecArea_RightDown.x;i++)
{IniImg[RecArea_LeftUp.y][i]=255;
IniImg[RecArea_RightDown.y][i]=255;
}
OutputImageWithName(IniImg,InImgRow,InImgCol,ResultImgName);
*/
ffree_2d((void **)AreaImg,AreaImgRow);
}
void Moment(double B[7],unsigned char **Image,short Row,short Col)
{
double m00,m01,m11,m02,m03,m10,m12,m20,m21,m30;
double u00,u01,u11,u02,u03,u10,u12,u20,u21,u30;
double l1,l2,l3,l4,Bmax;
double M[8];
double XC,YC,t;
short i,j;
/* Computing CenterPoint */
m00=0.0;m10=0.0;m01=0.0;
for(i=0;i<Row;i++)
for(j=0;j<Col;j++)
{t=(double)Image[i][j];
m00=m00+t;
m01=m01+i*t;
m10=m10+j*t;
}
XC=m10/m00; YC=m01/m00;
/*Computing CenterMoment */
m11=0.0;
m10=0.0;m01=0.0;m02=0.0;m20=0.0;
m03=0.0;m30=0.0;m21=0.0;m12=0.0;
for(i=0;i<Row;i++)
for(j=0;j<Col;j++)
{
t=(double)Image[i][j];
m01=m01+(-YC+i)*t;
m10=m10+(-XC+j)*t;
m11=m11+(-XC+j)*(-YC+i)*t;
m02=m02+(-YC+i)*(-YC+i)*t;
m20=m20+(-XC+j)*(-XC+j)*t;
m03=m03+(-YC+i)*(-YC+i)*(-YC+i)*t;
m30=m30+(-XC+j)*(-XC+j)*(-XC+j)*t;
m12=m12+(-XC+j)*(-YC+i)*(-YC+i)*t;
m21=m21+(-XC+j)*(-XC+j)*(-YC+i)*t;
}
/* Computing Hu Normalize Moment */
u00=m00;
u01=m01/sqrt(m00);
u02=m02/sqrt(m00*m00);
u03=m03/sqrt(m00*m00*m00);
u10=m10/sqrt(m00);
u11=m11/sqrt(m00*m00);
u12=m12/sqrt(m00*m00*m00);
u20=m20/sqrt(m00*m00);
u21=m21/sqrt(m00*m00*m00);
u30=m30/sqrt(m00*m00*m00);
l1=u30-3*u12;
l2=u03-3*u21;
l3=u30+u12;
l4=u03+u21;
M[1]=u20+u02;
M[2]=(u20-u02)*(u20-u02)+4*u11*u11;
M[3]=l1*l1+l2*l2;
M[4]=l3*l3+l4*l4;
M[5]=l1*l3*(l3*l3-3*l4*l4)-l2*l4*(3*l3*l3-l4*l4);
M[6]=(u20-u02)*(l3*l3-l4*l4)+4*u11*l3*l4;
M[7]=l2*l3*(3*l4*l4-l3*l3)+l1*l4*(3*l3*l3-l4*l4);
/* Computing Maitra Moment */
B[1]=sqrt(M[2])/M[1];
B[2]=M[3]*u00/(M[1]*M[2]);
B[3]=M[4]/M[3];
B[4]=sqrt(fabs(M[5]))/M[4];
B[5]=M[6]/(M[1]*M[4]);
B[6]=M[7]/M[5];
for(i=0;i<8;i++)
printf("B[%d]=%f ",i,B[i]);
printf("\n");
Bmax=0.0;
for(i=1;i<=6;i++)
if(fabs(B[i])>Bmax) Bmax=fabs(B[i]);
for(i=1;i<=6;i++)
B[i]=B[i]/Bmax;
}
void ShapeRec(short Row, short Col, unsigned char** InputImg, COORDINATE * Left_Up, COORDINATE* Right_Down)
{
short LabelNumber,AreaNumber,i,j,l;
AREA *LabelArea;
COORDINATE *LocalMaxPoint,*LocalMinPoint;
short LocalMaxPointNumber,LocalMinPointNumber;
short Distance1,Distance2,Distance3,Distance4,Mean;
double RecognitCoe,MinRecognitCoe;
Left_Up->y = 0;
Left_Up->x = 0;
Right_Down->y = Row - 1 ;
Right_Down->x = Col - 1;
LabelNumber = Label(InputImg,Row,Col,LABELMODE_1,50);
AreaNumber = LabelNumber;
LabelArea = (AREA*)calloc(AreaNumber,sizeof(AREA));
GetAreaInfo(AreaNumber,InputImg,Row,Col,LabelArea);
LocalMaxPoint = (COORDINATE*)calloc(MAX_POINT_NUMBER,sizeof(COORDINATE));
LocalMinPoint = (COORDINATE*)calloc(MAX_POINT_NUMBER,sizeof(COORDINATE));
MinRecognitCoe = 1000;
for(l=0;l<AreaNumber;l++)
{
LocalMaxPointNumber=LocalMinPointNumber=0;
Find_Peak(l,InputImg,LabelArea[l].Left_Up,LabelArea[l].Right_Down,
LocalMaxPoint,&LocalMaxPointNumber,LocalMinPoint,&LocalMinPointNumber);
if((LocalMaxPointNumber>=3)&&(LocalMinPointNumber>=2))
{
for(i=0;i<LocalMaxPointNumber-2;i++)
for(j=0;j<LocalMinPointNumber-1;j++)
{
if((LocalMinPoint[j].x<LocalMaxPoint[i].x)
&&(LocalMinPoint[j].x>LocalMaxPoint[i+1].x)
&&(LocalMinPoint[j+1].x<LocalMaxPoint[i+1].x)
&&(LocalMinPoint[j+1].x>LocalMaxPoint[i+2].x)
&&(LocalMaxPoint[i].y+1<LocalMinPoint[j].y) //3->1
&&(LocalMaxPoint[i+1].y+1<LocalMinPoint[j].y)
&&(LocalMaxPoint[i+2].y+1<LocalMinPoint[j].y)
&&(LocalMaxPoint[i].y+1<LocalMinPoint[j+1].y)
&&(LocalMaxPoint[i+1].y+1<LocalMinPoint[j+1].y)
&&(LocalMaxPoint[i+2].y+1<LocalMinPoint[j+1].y)
&&(LocalMaxPoint[i+1].y<=LocalMaxPoint[i+2].y))
{
Distance1 = abs(LocalMaxPoint[i].x - LocalMinPoint[j].x);
Distance2 = abs(LocalMaxPoint[i+1].x - LocalMinPoint[j].x);
Distance3 = abs(LocalMaxPoint[i+1].x - LocalMinPoint[j+1].x);
Distance4 = abs(LocalMaxPoint[i+2].x - LocalMinPoint[j+1].x);
Mean = (Distance1 + Distance2 + Distance3 + Distance4) / 4;
RecognitCoe = sqrt(((double)Distance1*Distance1+(double)Distance2*Distance2
+(double)Distance3*Distance3+(double)Distance4*Distance4-4*(double)Mean*Mean)/(4-1.0));
//printf("RecognitCoe = %f",RecognitCoe);
if(RecognitCoe < MinRecognitCoe)
{
MinRecognitCoe = RecognitCoe;
Left_Up->y = (LocalMaxPoint[i].y < LocalMaxPoint[i+1].y)?LocalMaxPoint[i].y:LocalMaxPoint[i+1].y;
Left_Up->y = (Left_Up->y < LocalMaxPoint[i+2].y)?Left_Up->y:LocalMaxPoint[i+2].y ;
if((LocalMaxPoint[i+2].x - Distance3)> 0 ) Left_Up->x = LocalMaxPoint[i+2].x - Distance3;
else Left_Up->x = 0 ;
Right_Down->y = (LocalMinPoint[j].y > LocalMinPoint[j+1].y)? LocalMinPoint[j].y:LocalMinPoint[j+1].y ;
if((LocalMaxPoint[i].x + Distance1)<Col)
Right_Down->x = LocalMaxPoint[i].x + Distance1;
else Right_Down->x = Col-1;
// Left_Up->y = LabelArea[l].Left_Up.y;
// Right_Down->y = LabelArea[l].Right_Down.y;
}
}
}
}
}
free (LabelArea);
free (LocalMaxPoint);
free (LocalMinPoint);
}
void Find_Peak(short AreaNo, unsigned char* * InputImg, COORDINATE StartPoint, COORDINATE EndPoint, COORDINATE * LocalMaxPoint, short * LocalMaxPointNumber, COORDINATE * LocalMinPoint, short * LocalMinPointNumber)
{
short i,j;
//int EqualPointNumber;
short Flag,Direction,OutsideFlag,LocalMaxPointFlag,LocalMinPointFlag;
//Direction is the direction of the last track,align with the
//anticlockwise. Its value is from 0...7;
COORDINATE FirstPoint,ThisPoint,NextPoint;
Flag = 0;
for(j = StartPoint.x;j <= EndPoint.x;j++)
{
for(i = StartPoint.y;i <= EndPoint.y;i++)
{
if(InputImg[i][j] == MAXLEVEL - AreaNo)
{
FirstPoint.y = i;
FirstPoint.x = j;
Flag = 1;
break;
}
}
if(Flag==1) break;
}
LocalMaxPointFlag = 0;
LocalMinPointFlag = 0;
Direction = 0;
ThisPoint = FirstPoint;
do
{
for(i=0;i<8;i++)
{
OutsideFlag = 0;
NextTrackPoint(&OutsideFlag,StartPoint,EndPoint,Direction,ThisPoint,&NextPoint);
if(OutsideFlag == 0)
{
if(InputImg[NextPoint.y][NextPoint.x] != MAXLEVEL - AreaNo)
{
Direction++;
Direction = Direction % DIRECTION_NUMBER;
}
else break;
}
else
{
Direction++;
Direction = Direction % DIRECTION_NUMBER;
}
}
Direction = (Direction + 5) % DIRECTION_NUMBER;//get the direction of this track
//ContourImg[NextPoint.y][NextPoint.x] = 255;
if(LocalMaxPointFlag == 0)
{
if(NextPoint.y < ThisPoint.y) LocalMaxPointFlag = 1;
}
else if(LocalMaxPointFlag == 1)
{
if(NextPoint.y > ThisPoint.y)
{
LocalMaxPointFlag = 0;
LocalMaxPoint[*LocalMaxPointNumber].y = ThisPoint.y;
LocalMaxPoint[*LocalMaxPointNumber].x = ThisPoint.x;
(*LocalMaxPointNumber)++;
//PeakImg1[ThisPoint.y][ThisPoint.x] = 255;
}
}
if(LocalMinPointFlag == 0)
{
if(NextPoint.y > ThisPoint.y) LocalMinPointFlag = 1;
}
else if(LocalMinPointFlag == 1)
{
if(NextPoint.y < ThisPoint.y)
{
LocalMinPointFlag = 0;
LocalMinPoint[*LocalMinPointNumber].y = ThisPoint.y;
LocalMinPoint[*LocalMinPointNumber].x = ThisPoint.x;
(*LocalMinPointNumber)++;
//PeakImg2[ThisPoint.y][ThisPoint.x] = 255;
}
}
ThisPoint = NextPoint;
}while((NextPoint.y != FirstPoint.y)||(NextPoint.x != FirstPoint.x));
}
void GetAreaInfo(short AreaNumber, unsigned char** LabelImg, short Row, short Col, AREA * Area)
{
short i,j,l;
for(l = 0 ;l < AreaNumber;l++)
{
Area[l].Value = MAXLEVEL - l;
Area[l].Right_Down.x=0;
Area[l].Right_Down.y=0;
Area[l].Left_Up.x=Col-1;
Area[l].Left_Up.y=Row-1;
for(i = 0;i < Row;i++)
for(j = 0;j < Col;j++)
{
if(LabelImg[i][j]==Area[l].Value)
{
if(i<Area[l].Left_Up.y) Area[l].Left_Up.y = i;
if(i>Area[l].Right_Down.y) Area[l].Right_Down.y = i;
if(j<Area[l].Left_Up.x) Area[l].Left_Up.x = j;
if(j>Area[l].Right_Down.x) Area[l].Right_Down.x = j;
}
}
Area[l].Height = Area[l].Right_Down.y - Area[l].Left_Up.y + 1;
Area[l].Width = Area[l].Right_Down.x - Area[l].Left_Up.x + 1;
}
}
void NextTrackPoint(short * OutsideFlag, COORDINATE StartPoint, COORDINATE EndPoint, short Direction, COORDINATE ThisPoint, COORDINATE * NextPoint)
{
switch(Direction)
{
case 0:
{
NextPoint->y = ThisPoint.y + 1;
NextPoint->x = ThisPoint.x - 1;
if((NextPoint->y<=EndPoint.y)&&(NextPoint->x>=StartPoint.x)) break;
else
{
*OutsideFlag = 1;
break;
}
}
case 1:
{
NextPoint->y = ThisPoint.y + 1;
NextPoint->x = ThisPoint.x;
if(NextPoint->y<=EndPoint.y) break;
else
{
*OutsideFlag = 1;
break;
}
}
case 2:
{
NextPoint->y = ThisPoint.y + 1;
NextPoint->x = ThisPoint.x + 1;
if((NextPoint->y<=EndPoint.y)&&(NextPoint->x<=EndPoint.x)) break;
else
{
*OutsideFlag = 1;
break;
}
}
case 3:
{
NextPoint->y = ThisPoint.y;
NextPoint->x = ThisPoint.x + 1;
if(NextPoint->x<=EndPoint.x) break;
else
{
*OutsideFlag = 1;
break;
}
}
case 4:
{
NextPoint->y = ThisPoint.y - 1;
NextPoint->x = ThisPoint.x + 1;
if((NextPoint->y>=StartPoint.y)&&(NextPoint->x<=EndPoint.x)) break;
else
{
*OutsideFlag = 1;
break;
}
}
case 5:
{
NextPoint->y = ThisPoint.y - 1;
NextPoint->x = ThisPoint.x;
if(NextPoint->y>=StartPoint.y) break;
else
{
*OutsideFlag = 1;
break;
}
}
case 6:
{
NextPoint->y = ThisPoint.y - 1;
NextPoint->x = ThisPoint.x - 1;
if((NextPoint->y>=StartPoint.y)&&(NextPoint->x>=StartPoint.x)) break;
else
{
*OutsideFlag = 1;
break;
}
}
case 7:
{
NextPoint->y = ThisPoint.y;
NextPoint->x = ThisPoint.x - 1;
if(NextPoint->x>=StartPoint.x) break;
else
{
*OutsideFlag = 1;
break;
}
}
default:break;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -