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

📄 atrplant.cpp

📁 图像处理软件,功能比较基础
💻 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 + -