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

📄 vlimageproc.cpp

📁 hough变换的代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    return (-1);		/* failure */
  }

  for (i = 0; i < 256;i++)
	{
		lHistogram[i]=0;
	}
  iMaxGrayValue = 0;
  iMinGrayValue = 255;

  /* temp variables to optimize memory access */
  width = src->width;
  x1 = window->x;
  x2 = x1 + (window->width);
  y1 = window->y;
  y2 = y1 + (window->height);
  input = src->pixel;
  output = dest->pixel;
 
  /* proceed to get the Histogram */
  for (j=y1; j<y2; j++) 
  {
    for (i=x1; i<x2; i++) 
	{
      index = VL_GRAY_PIXEL * (j*width + i);
	  pixel = input[index];
	  lHistogram[pixel]++;

	  if(iMinGrayValue > pixel)
		  iMinGrayValue = pixel;
	  if(iMaxGrayValue < pixel)
		  iMaxGrayValue = pixel;
    }
  }

  //iteration for the iThreshold
  iNewThreshold = (iMinGrayValue + iMaxGrayValue)/2;
  iThreshold = 0;

  for(iIterationTimes = 0; iThreshold != iNewThreshold && iIterationTimes < 100;iIterationTimes ++)
  {
		iThreshold = iNewThreshold;
		lP1 =0;
		lP2 =0;
		lS1 = 0;
		lS2 = 0;

		//get the mean Gray value for the two parts
		for (i = iMinGrayValue;i < iThreshold;i++)
		{
			lP1 += lHistogram[i]*i;
			lS1 += lHistogram[i];
		}

		iMean1GrayValue = (unsigned char)(lP1 / lS1);

		for (i = iThreshold+1;i < iMaxGrayValue;i++)
		{
			lP2 += lHistogram[i]*i;
			lS2 += lHistogram[i];
		}

		iMean2GrayValue = (unsigned char)(lP2 / lS2);

		iNewThreshold =  (iMean1GrayValue + iMean2GrayValue)/2;
  }

  /* depart the image by iThreshold */
  for (j=y1; j<y2; j++) 
  {
    for (i=x1; i<x2; i++) 
	{
      index = VL_GRAY_PIXEL * (j*width + i);
	  if(input[index] > iThreshold)
		  output[index] = 255;
	  else
		  output[index] = 0;
    }
  }

  return (0);			/* success */
}

/*************************************************************************
 *
 * Function Name:
 *   vlEdgedetect()
 *
 * Paremetres:
 *   CvlImage *src    - pointer to src GRAY image
 *   CvlWindow *window       - compute area(a rectangle)
 *   CvlImage *dest      - pointer to dest GRAY image(it can be src GRAY image)
 *
 * return:
 *   int               - sucess 0,else -1.
 *
 * Remarks:
 * This function is used for detecting the edges of a two_GRAY_value image.
 * 
 ************************************************************************/
int CvlImageProc::vlEdgedetect (CvlImage *src, CvlWindow *window, CvlImage *dest)
{
  int i, j;
  int index, width;
  int x1, x2, y1, y2;
  vlPixel *input;
  vlPixel *output;
  vlPixel *temp;//hold the temp results
  int tempindex;
  vlPixel nw,n,ne,w,e,sw,s,se;//8 points around one point

  /* verify parameters */
  if ((!src) || (!window) || (!dest)) {
    MessageBox(NULL,"one of the parameters is NULL\n","warnning",MB_OK);
    return (-1);		/* failure */
  }

  /* make sure we have a RGB picture */
  if (src->format != GRAY) {
	MessageBox(NULL,"src image is not GRAY\n","warnning",MB_OK);    
    return (-1);		/* failure */
  }

  /* temp variables to optimize memory access */
  width = src->width;
  x1 = window->x;
  x2 = x1 + (window->width);
  y1 = window->y;
  y2 = y1 + (window->height);
  input = src->pixel;
  output = dest->pixel;

  temp = new vlPixel [(window->width)*(window->height)];
  tempindex = -1;
 
  /* proceed to conversion */
  for (j=y1; j<y2; j++) 
  {
    for (i=x1; i<x2; i++) 
	{
	  tempindex++;
	  if(i==0||j==0||i==src->width||j==src->width)
		  continue;
      index = VL_GRAY_PIXEL * (j*width + i);

	  nw = input[index+width-1];
	  n = input[index+width];
	  ne = input[index+width+1];
	  w = input[index-1];
	  e = input[index+1];
	  sw = input[index-width-1];
	  s = input[index-width];
	  se = input[index-width+1];

	  if(nw+n+ne+w+e+sw+s+se==0)
		  temp[tempindex]=255;
	  else
		  temp[tempindex]=input[index];
    }
  }

  tempindex = 0;
  for (j=y1; j<y2; j++) 
  {
    for (i=x1; i<x2; i++) 
	{
      index = VL_GRAY_PIXEL * (j*width + i);
      output[index]=temp[tempindex];
	  tempindex++;
    }
  }

  delete [] temp;//release memory.
  return (0);			/* success */
} 

//连续轮廓搜索函数
int searchedge(vlPixel * input, vlPixel * output, int x1, int x2, int y1, int y2, int j,int i,int Width,int K)
{
	int Top=1;
loop:
	CPoint *Stack=new CPoint[10000];//I think it's enough
	if(Stack==NULL)
		goto loop;
	Stack->x=j;
	Stack->y=i;
	int Res=1;//
	int I,J;
	while(Top!=0)
	{
		Top--;
		I=(Stack+Top)->y;
		J=(Stack+Top)->x;
		*(output+I*Width+J)=K;
		*(input+I*Width+J)=255;
		if(I>=y1&&I<y2&&J-1>=x1&&J-1<x2&&*(input+I*Width+J-1)==0)
		{
			(Stack+Top)->y=I;
			(Stack+Top)->x=J-1;
			*(input+I*Width+J-1)=255;
			*(output+I*Width+J-1)=K;
			Res++;
			Top++;
		}
		if(I>=y1&&I<y2&&J+1>=x1&&J+1<x2&&*(input+I*Width+J+1)==0)
		{
			(Stack+Top)->y=I;
			(Stack+Top)->x=J+1;
			*(input+I*Width+J+1)=255;
			*(output+I*Width+J+1)=K;
			Res++;
			Top++;
		}
		if(I-1>=y1&&I-1<y2&&J>=x1&&J<x2&&*(input+(I-1)*Width+J)==0)
		{
			(Stack+Top)->y=I-1;
			(Stack+Top)->x=J;
			*(input+(I-1)*Width+J)=255;
			*(output+(I-1)*Width+J)=K;
			Res++;
			Top++;
		}
		if(I+1>=y1&&I+1<y2&&J>=x1&&J<x2&&*(input+(I+1)*Width+J)==0)
		{
			(Stack+Top)->y=I+1;
			(Stack+Top)->x=J;
			*(input+(I+1)*Width+J)=255;
			*(output+(I+1)*Width+J)=K;
			Res++;
			Top++;
		}
		if(I-1>=y1&&I-1<y2&&J-1>=x1&&J-1<x2&&*(input+(I-1)*Width+J-1)==0)
		{
			(Stack+Top)->y=I-1;
			(Stack+Top)->x=J-1;
			*(input+(I-1)*Width+J-1)=255;
			*(output+(I-1)*Width+J-1)=K;
			Res++;
			Top++;
		}
		if(I-1>=y1&&I-1<y2&&J+1>=x1&&J+1<x2&&*(input+(I-1)*Width+J+1)==0)
		{
			(Stack+Top)->y=I-1;
			(Stack+Top)->x=J+1;
			*(input+(I-1)*Width+J+1)=255;
			*(output+(I-1)*Width+J+1)=K;
			Res++;
			Top++;
		}
		if(I+1>=y1&&I+1<y2&&J-1>=x1&&J-1<x2&&*(input+(I+1)*Width+J-1)==0)
		{
			(Stack+Top)->y=I+1;
			(Stack+Top)->x=J-1;
			*(input+(I+1)*Width+J-1)=255;
			*(output+(I+1)*Width+J-1)=K;
			Res++;
			Top++;
		}
		if(I+1>=y1&&I+1<y2&&J+1>=x1&&J+1<x2&&*(input+(I+1)*Width+J+1)==0)
		{
			(Stack+Top)->y=I+1;
			(Stack+Top)->x=J+1;
			*(input+(I+1)*Width+J+1)=255;
			*(output+(I+1)*Width+J+1)=K;
			Res++;
			Top++;
		}
	}
	delete []Stack;
	return Res;
}


/*************************************************************************
 *
 * Function Name:
 *   vlCircleHough()
 *
 * Paremetres:
 *   CvlImage *src    - pointer to src GRAY image
 *   CvlWindow *window       - compute area(a rectangle)
 *   CvlImage *dest      - pointer to dest GRAY image(it can be src GRAY image)
 *
 * return:
 *   int               - sucess 0,else -1.
 *
 * Remarks:
 * This function is used for Circle detection with Hough translation.
 * 
 ************************************************************************/
int CvlImageProc::vlCircleHough(CvlImage *src, CvlWindow *window, CvlImage *dest, int dmin, int dmax)
{
  int i, j;
  int index, width;
  int x1, x2, y1, y2;
  vlPixel *input;
  vlPixel *output;
  int linepoints[30];//Please filt the noise first to make sure the apart lines less then 30

  for(i=0; i<30; i++)
	  linepoints[i]=0;

  /* verify parameters */
  if ((!src) || (!window) || (!dest)) {
    MessageBox(NULL,"one of the parameters is NULL\n","warnning",MB_OK);
    return (-1);		/* failure */
  }

  /* make sure we have a RGB picture */
  if (src->format != GRAY) {
	MessageBox(NULL,"src image is not GRAY\n","warnning",MB_OK);    
    return (-1);		/* failure */
  }

  /* temp variables to optimize memory access */
  width = src->width;
  x1 = window->x;
  x2 = x1 + (window->width);
  y1 = window->y;
  y2 = y1 + (window->height);
  input = src->pixel;
  output = dest->pixel;
 
  /* find the different connected lines and the number of their points */
  int linenum=0;
  for (j=y1; j<y2; j++) 
  {
    for (i=x1; i<x2; i++) 
	{
      index = VL_GRAY_PIXEL * (j*width + i);
	  if(input[index]==0)
	  {
		  linepoints[linenum]=searchedge(input,output,x1,x2,y1,y2,i,j,width,linenum);
	      linenum++;
	  }
    }
  }

  //do fast hough translation on the selected lines, find the real objects and their number

  int fixstep,count=5;//step--departure among 3 points; count--round times
  int step;

  int x_K,y_K,x_L,y_L,x_M,y_M;//three points on the line(circle)

  int *a,*b;//the centre of the circle

  int *r;//the radius of the circle

  int *C;//count different (a,b,r)

  int at,bt,rt;//temp (a,b,r)

  double k_KL,k_LM,d_KL,d_LM;//slopes and intercepts

  int N;//number of different (a,b,r)

  int MAX;//the most likely number of (a,b,r)

  int TH;//the threshold to judge whether the Circle is a real one

  int found=0;//found the same (a,b,r)?

  objectnum = 0;

  int k,l;
  int stack[700];//enough for a circle with the diameter less than 200 pixels
  for (k=0; k<linenum; k++)
  {
	  if(linepoints[k]<(int)(4*dmax)&&linepoints[k]>(int)(3.14*dmin))
	  {
		  //find the first point of line[k]
		  for(j=y1; j<y2; j++) 
			  for(i=x1; i<x2; i++)
			  {
				  index = VL_GRAY_PIXEL * (j*width + i);
				  if(output[index]==k)
				  {
					  i=x2;
					  j=y2;
				  }//force it to escape from the circulation
			  }
		  stack[0]=index;

		  //search withershins to push all the points into the stack
		  for(i=1;i<linepoints[k];i++)
		  {
			  int before;//the point before
			  if(i==1)
				  before=stack[0];
			  else 
				  before=stack[i-2];
			  if (output[stack[i-1]+1]==k && stack[i-1]+1 != before)//e
			  {
				  stack[i]=stack[i-1]+1;
				  if(stack[i]==index)
					  break;
				  continue;
			  }
			  if (output[stack[i-1]+width+1]==k && stack[i-1]+width+1 != before)//ne
			  {
				  stack[i]=stack[i-1]+width+1;
				  if(stack[i]==index)
					  break;
				  continue;
			  }
			  if (output[stack[i-1]+width]==k && stack[i-1]+width != before)//n
			  {
				  stack[i]=stack[i-1]+width;
				  if(stack[i]==index)
					  break;
				  continue;
			  }
			  if (output[stack[i-1]+width-1]==k && stack[i-1]+width-1 != before)//nw
			  {
				  stack[i]=stack[i-1]+width-1;
				  if(stack[i]==index)
					  break;
				  continue;
			  }
			  if (output[stack[i-1]-1]==k && stack[i-1]-1 != before)//w
			  {
				  stack[i]=stack[i-1]-1;
				  if(stack[i]==index)
					  break;
				  continue;
			  }
			  if (output[stack[i-1]-width-1]==k && stack[i-1]-width-1 != before)//sw
			  {
				  stack[i]=stack[i-1]-width-1;
				  if(stack[i]==index)
					  break;
				  continue;
			  }
			  if (output[stack[i-1]-width]==k && stack[i-1]-width != before)//s
			  {
				  stack[i]=stack[i-1]-width;
				  if(stack[i]==index)
					  break;
				  continue;
			  }
			  if (output[stack[i-1]-width+1]==k && stack[i-1]-width+1 != before)//se
			  {
				  stack[i]=stack[i-1]-width+1;
				  if(stack[i]==index)
					  break;
				  continue;
			  }
			  break;

		  }//now the variable i is the points' number around

		  //do the fast hough translation based on the 3 points departed by fixed steps
		  a = new int [i*count/3];
          b = new int [i*count/3];
          r = new int [i*count/3];
		  C = new int [i*count/3];
		  N = 0;

		  fixstep=i/8;
          for (step=fixstep; step<fixstep+count; step++)
			  for(j=0; j<i-step*2; j++)
			  {
				  x_K = stack[j]%width;
				  y_K = stack[j]/width;
				  x_L = stack[j+step]%width;
				  y_L = stack[j+step]/width;
				  x_M = stack[j+step*2]%width;
				  y_M = stack[j+step*2]/width;

				  k_KL= -(double)(x_K-x_L)/(double)(y_K-y_L);
				  d_KL= (double)(y_K+y_L - (x_K+x_L)*k_KL)/2;
				  k_LM= -(double)(x_L-x_M)/(double)(y_L-y_M);
				  d_LM= (double)(y_L+y_M - (x_L+x_M)*k_LM)/2;

				  at = (int)((d_LM-d_KL)/(k_KL-k_LM));
				  bt = (int)(k_KL*at+d_KL);
				  rt = (int)sqrt((x_L-at)*(x_L-at) + (y_L-bt)*(y_L-bt));

				  if(N==0)
				  {
					  a[N]=at;
					  b[N]=bt;
					  r[N]=rt;
					  C[N]=1;
					  N++;
				  }
				  else
				  {
					  for (l=0; l<N; l++)
					  {
					      if(at==a[l]&&bt==b[l]&&rt==r[l])
						  {
					    	  C[l]++;
							  found=1;
					    	  break;
						  }
				    	  else
							  found=0;
					  }
					  if(found==0)
					  {
				    	  a[N]=at;
					      b[N]=bt;
					      r[N]=rt;
					      C[N]=1;
					      N++;
					  }
				  }

				  if(j%step==step-1)
					  j+=step*2;
			  }

		  //select the most likely circle
		  MAX = 0;
		  for (l=0; l<N; l++)
			  if(C[MAX]<C[l])
				  MAX=l;

		  TH = (i*count/3)/20;
          if (C[MAX]>TH&&r[MAX]>10&&r[MAX]<30)
		  {
			  objectcoordinates[objectnum][0] = a[MAX];
			  objectcoordinates[objectnum][1] = b[MAX];
			  objectr[objectnum] = r[MAX];
			  objectnum++;
		  }

		  if (objectnum==12)
			  break;

		  delete [] a;
		  delete [] b;
		  delete [] r;
		  delete [] C;
	  }
  }

  return (0);			/* success */
} 

⌨️ 快捷键说明

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