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

📄 segment.cpp

📁 图像处理软件,功能比较基础
💻 CPP
字号:
#include <stdafx.h>
#include <stdio.h>
#include <math.h>

#include "common.h"
#include "basic.h"
#include "label.h"
#include "improc.h"
#include "segment.h"

int Otsu1(unsigned char** Image, int YStart, int XStart, int Row, int Col)
{
   unsigned char **subimg;
   int threshold;
   int i,j;
   subimg = (unsigned char **)fspace_2d(Row,Col,sizeof(unsigned char));
   if(!subimg) return 0;

   for(i=0; i<Row; i++)
   for(j=0; j<Col; j++) subimg[i][j] = Image[i+YStart][j+XStart];
      
   threshold = Otsu_2d(subimg,Row,Col);
   ffree_2d((void **)subimg,Row);
   return threshold;
}

int Otsu_2d(unsigned char **Image,int Row,int Col)
{
  int i,j,GreyValue;
  int OT;   /*  Optimal Threshold       */
  double BCV;  /*  Between Class Variance  */
  long  w0,u0,Ave,Num,Count[MAXGRAYLEVEL+1];
  double Vb;

  for(i=0;i<=MAXGRAYLEVEL;i++)  Count[i] = 0;

  Num = 0;
  for(i=0;i<Row;i++)
    for(j=0;j<Col;j++)
      if(Image[i][j])
      {
         Count[Image[i][j]]++;
         Num++;
      }

  GreyValue = 0;
  while(!Count[GreyValue])  GreyValue++;

  w0 = Count[GreyValue];
  u0 = GreyValue * Count[GreyValue];

  Ave = u0;
  for(i=GreyValue+1;i<=MAXGRAYLEVEL;i++)
    Ave += i * Count[i];

  OT  = 0;
  BCV = 0.0;
//  Num = (long)Row * Col;
  while(w0<Num)
  {
    Vb = ((double)Ave * w0 / Num - u0) * ((double)Ave * w0 / Num - u0) 
			/ w0 / (Num - w0);
    if (Vb>BCV)
    {
      OT  = GreyValue;
      BCV = Vb;
    }
    GreyValue++;
    w0 += Count[GreyValue];
    u0 += GreyValue * Count[GreyValue];
  }

  return(OT);
}
/******************************  Otsu  ******************************/
/*  To get Otsu threshold  */
int Otsu(unsigned char **Image,int Row,int Col)
{
  int i,j,GreyValue;
  int OT;   /*  Optimal Threshold       */
  double BCV;  /*  Between Class Variance  */
  long  w0,u0,Ave,Num,Count[MAXGRAYLEVEL+1];
  double Vb;

  for(i=0;i<=MAXGRAYLEVEL;i++)  Count[i] = 0;

  for(i=0;i<Row;i++)
    for(j=0;j<Col;j++)
      Count[Image[i][j]]++;

  GreyValue = 0;
  while(!Count[GreyValue])  GreyValue++;

  w0 = Count[GreyValue];
  u0 = GreyValue * Count[GreyValue];

  Ave = u0;
  for(i=GreyValue+1;i<=MAXGRAYLEVEL;i++)
    Ave += i * Count[i];

  OT  = 0;
  BCV = 0.0;
  Num = (long)Row * Col;
  while(w0<Num)
  {
    Vb = ((double)Ave * w0 / Num - u0) * ((double)Ave * w0 / Num - u0) 
			/ w0 / (Num - w0);
    if (Vb>BCV)
    {
      OT  = GreyValue;
      BCV = Vb;
    }
    GreyValue++;
    w0 += Count[GreyValue];
    u0 += GreyValue * Count[GreyValue];
  }

  return(OT);
}

/*  Maxium Entrop Methord                */
/**************************  MaxEntropy  ****************************/
int MaxEntropy(unsigned char **Image,int Row,int Col)
{
	int i,j,GrayValue,MaxGrayValue,OT;
	unsigned long  Num,Count[MAXGRAYLEVEL+1],Ps;
	double         H,H1,H2,Hm,Hs;
	double         BV;

	Num = (long)Row * Col;

	for(i=0;i<=MAXGRAYLEVEL;i++)     Count[i] = 0;

	for(i=0;i<Row;i++)
		for(j=0;j<Col;j++)
			Count[Image[i][j]]++;

	GrayValue = 0;
	while(!Count[GrayValue])  GrayValue++;
	MaxGrayValue = MAXGRAYLEVEL;
	while(!Count[MaxGrayValue])   MaxGrayValue--;
 
	Ps = Count[GrayValue];
	Hs = Count[GrayValue] * log((double)Count[GrayValue]/Num);
	H = H1 = H2 = Hm = 0;
	BV = -100000000.0;

	for(i=GrayValue;i<=MaxGrayValue;i++)
	{
		if(Count[i] != 0)
		Hm += Count[i] * log((double)Count[i]/Num);
	}

	while(GrayValue < MaxGrayValue-1)
	{
		GrayValue++;
		Ps += Count[GrayValue];
		if(Count[GrayValue] != 0)
		{
			Hs += Count[GrayValue] * log((double)Count[GrayValue]/Num);
			H1 = log((double)Ps/Num) - Hs/Ps;
			H2 = log(1-(double)Ps/Num) + (Hs-Hm)/(Num-Ps);
			H  = H1+H2;
			if(H>BV)
			{
				BV = H;
				OT = GrayValue;
			}
		}
	}

	return(OT);
}


void Motsu(int Row, int Col, unsigned char** OriginalImg, 
		   unsigned char ** SegmentImg,double EntropyThreshold )
{
  COORDINATE    Left_Up,Right_Down;
  unsigned char **MidImg;
  int         Threshold;
  int         LabelNum,AreaRow,AreaCol,i,j;
  static int  LastArea[20],CorrentArea[20];
  int         Number;
  double        LocalEntropy;//,EntropyThreshold;
  int         Time=0, Flag=1;
  double        AreaThreshold;

  MidImg=(unsigned char**)fspace_2d(Row,Col,sizeof(unsigned char));

  //EntropyThreshold=1.5;

  Threshold=NonlineOtsu(OriginalImg,0,0,Row,Col,(double)0.1);

  for(i=0;i<20;i++)
    {LastArea[i]=2000000;
     CorrentArea[i]=2000000;}

  for(i=0;i<Row;i++)
    for(j=0;j<Col;j++)
      {if(OriginalImg[i][j]>=Threshold)  SegmentImg[i][j]=255;
      else SegmentImg[i][j]=0;}


  while((Flag==1)&&(Time<10))
  {Time++;
   Flag=0;
   LabelNum=Label(SegmentImg,Row,Col,LABELMODE_1,50);

   for(i=0;i<Row;i++)
    for(j=0;j<Col;j++)
     MidImg[i][j]=0;


    for(Number=0;Number<LabelNum;Number++)
       {Right_Down.x=0;
	Right_Down.y=0;
	Left_Up.x=Col-1;
	Left_Up.y=Row-1;

	for(i=0;i<Row;i++)
	 for(j=0;j<Col;j++)
	  {
	   if(SegmentImg[i][j]==(MAXLEVEL-Number))
	   {
	    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;
	    }
	  }

	AreaRow=Right_Down.y-Left_Up.y+1;
	AreaCol=Right_Down.x-Left_Up.x+1;

	LastArea[Number]=CorrentArea[Number];
	CorrentArea[Number]=AreaRow*AreaCol;
	AreaThreshold=(double)CorrentArea[Number]/LastArea[Number];


	LocalEntropy=Entropy(OriginalImg,Left_Up.y,Left_Up.x,AreaRow,AreaCol);

	if((LocalEntropy>EntropyThreshold)&&((AreaThreshold<0.99)||(AreaThreshold>1.01)))
	  {
	   Threshold=NonlineOtsu(OriginalImg,Left_Up.y,Left_Up.x,AreaRow,AreaCol,(double)0.1);
	   //printf("Threshold=%d\n",Threshold);
	   Flag=1;
	   for(i=Left_Up.y;i<Left_Up.y+AreaRow;i++)
	     for(j=Left_Up.x;j<Left_Up.x+AreaCol;j++)
	       if(OriginalImg[i][j]>Threshold)  MidImg[i][j]=255;
	   }
	  else{
		for(i=Left_Up.y;i<Left_Up.y+AreaRow;i++)
		  for(j=Left_Up.x;j<Left_Up.x+AreaCol;j++)
		     MidImg[i][j]=SegmentImg[i][j];
	       }
      }
   for(i=0;i<Row;i++)
    for(j=0;j<Col;j++)
     SegmentImg[i][j]=MidImg[i][j];
   }
  ffree_2d((void **)MidImg,Row);

 }

int NonlineOtsu(unsigned char** Image, int YStart, int XStart, int Row, int Col, double C)
{
  int   i,j,GreyValue;
  int   OT;   /*  Optimal Threshold       */
  double BCV;  /*  Between Class Variance  */
  long  w0,u0,Ave,Num,Count[MAXLEVEL+1];
  double Vb;

  for(i=0;i<=MAXLEVEL;i++)  Count[i] = 0;

  for(i=YStart;i<YStart+Row;i++)
    for(j=XStart;j<XStart+Col;j++)
	Count[Image[i][j]]++;

  GreyValue = 0;
  while(!Count[GreyValue])  GreyValue++;

  w0 = Count[GreyValue];
  u0 = GreyValue * Count[GreyValue];

  Ave = u0;
  for(i=GreyValue+1;i<=MAXLEVEL;i++)
    Ave += i * Count[i];

  if (Ave==u0)  return(-1);

  OT = 0;
  BCV = 0.0;
  Num = (long)Row * Col;
  while(w0<Num)
  {
    Vb = ((double)Ave * w0 / Num - u0) * ((double)Ave * w0 / Num - u0) / w0 / (Num - w0);
    Vb /= ((double)u0 / w0 + C);
    if (Vb>BCV)
    {
      OT  = GreyValue;
      BCV = Vb;
    }
    GreyValue++;
    w0 += Count[GreyValue];
    u0 += GreyValue * Count[GreyValue];
  }

  return(OT);
}

void MotsuWithStd(int Row, int Col, unsigned char** OriginalImg, 
		   unsigned char ** SegmentImg,double EntropyThreshold )
{
  COORDINATE    Left_Up,Right_Down;
  unsigned char **MidImg;
  int         Threshold;
  int         LabelNum,AreaRow,AreaCol,i,j;
  static int  LastArea[20],CorrentArea[20];
  int         Number;
  double        LocalEntropy;//,EntropyThreshold;
  int         Time=0, Flag=1;
  double        AreaThreshold;
  double        Avg;

  MidImg=(unsigned char**)fspace_2d(Row,Col,sizeof(unsigned char));

  //EntropyThreshold=1.5;

  Threshold=NonlineOtsu(OriginalImg,0,0,Row,Col,(double)0.1);

  for(i=0;i<20;i++)
    {LastArea[i]=2000000;
     CorrentArea[i]=2000000;}

  for(i=0;i<Row;i++)
    for(j=0;j<Col;j++)
      {if(OriginalImg[i][j]>=Threshold)  SegmentImg[i][j]=255;
      else SegmentImg[i][j]=0;}


  while((Flag==1)&&(Time<10))
  {Time++;
   Flag=0;
   LabelNum=Label(SegmentImg,Row,Col,LABELMODE_1,50);

   for(i=0;i<Row;i++)
    for(j=0;j<Col;j++)
     MidImg[i][j]=0;


    for(Number=0;Number<LabelNum;Number++)
       {Right_Down.x=0;
	Right_Down.y=0;
	Left_Up.x=Col-1;
	Left_Up.y=Row-1;

	for(i=0;i<Row;i++)
	 for(j=0;j<Col;j++)
	  {
	   if(SegmentImg[i][j]==(MAXLEVEL-Number))
	   {
	    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;
	    }
	  }

	AreaRow=Right_Down.y-Left_Up.y+1;
	AreaCol=Right_Down.x-Left_Up.x+1;

	LastArea[Number]=CorrentArea[Number];
	CorrentArea[Number]=AreaRow*AreaCol;
	AreaThreshold=(double)CorrentArea[Number]/LastArea[Number];

    Avg = ucAverage(OriginalImg,Left_Up.y,Left_Up.x,AreaRow,AreaCol,0);
    LocalEntropy = ucDeviation(OriginalImg,Left_Up.y,Left_Up.x,AreaRow,AreaCol,Avg,0);
//	LocalEntropy=Entropy(OriginalImg,Left_Up.y,Left_Up.x,AreaRow,AreaCol);

	if((LocalEntropy>EntropyThreshold)&&((AreaThreshold<0.99)||(AreaThreshold>1.01)))
	  {
	   Threshold=NonlineOtsu(OriginalImg,Left_Up.y,Left_Up.x,AreaRow,AreaCol,(double)0.1);
	   //printf("Threshold=%d\n",Threshold);
	   Flag=1;
	   for(i=Left_Up.y;i<Left_Up.y+AreaRow;i++)
	     for(j=Left_Up.x;j<Left_Up.x+AreaCol;j++)
	       if(OriginalImg[i][j]>Threshold)  MidImg[i][j]=255;
	   }
	  else{
		for(i=Left_Up.y;i<Left_Up.y+AreaRow;i++)
		  for(j=Left_Up.x;j<Left_Up.x+AreaCol;j++)
		     MidImg[i][j]=SegmentImg[i][j];
	       }
      }
   for(i=0;i<Row;i++)
    for(j=0;j<Col;j++)
     SegmentImg[i][j]=MidImg[i][j];
   }
  ffree_2d((void **)MidImg,Row);

 }

int GrdientSeg(unsigned char **oriimg,int YStart,int XStart,int Row,int Col)
{
   double **g,**d;
   double aver,dev,gthreshold;
   double ratio;
   double total;
   int count,i,j;
   
   g = (double **)fspace_2d(Row,Col,sizeof(double));
   d = (double **)fspace_2d(Row,Col,sizeof(double));
   if(!g||!d) return 0;

   Sobel(oriimg,YStart,XStart,Row,Col,g,d,1);

   aver = fAverage(g,0,0,Row,Col,0);
   dev = fDeviation(g,0,0,Row,Col,aver,0);
   ratio = 2;
   gthreshold = aver + ratio * dev;

   total = 0;
   count = 0;
   for(i=0; i<Row; i++)
   for(j=0; j<Col; j++)
   {
      if(g[i][j]>gthreshold)
      {
         total += oriimg[i+YStart][j+XStart];
         count++;
      }
   }
   return((int)(total/count));
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -