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

📄 cannyedge.c

📁 Canny Edge sample good luck
💻 C
📖 第 1 页 / 共 3 页
字号:
         result = 0;          // reset      }   // smoothing vertical direction (Y)   t = 0;   for(j= 0; j < x; j++, t=j)       // columns      for(i = 0; i < y; i++, t+=x)  // rows      {         for(k = -center; k <= center; k++)            if(((i+k) >= 0) && ((i+k) < y))               result += out[t+(k*x)] * kernel[k+center] + 0.5;            else               result += out[t] * kernel[k+center] + 0.5;                 out[t] = result;         result = 0;          // reset      }}///////////////////////////////////////////////////////////////////////////////// smooth image with Gaussian filter///////////////////////////////////////////////////////////////////////////////void gaussian(unsigned char *inBuf, int x, int y, float sigma,              unsigned char *outBuf){   int kernelSize;   float *kernel;   // determine size of kernel (odd #)   // 0.0 <= sigma < 0.5 : 3   // 0.5 <= sigma < 1.0 : 5   // 1.0 <= sigma < 1.5 : 7   // 1.5 <= sigma < 2.0 : 9   // 2.0 <= sigma < 2.5 : 11   // 2.5 <= sigma < 3.0 : 13 ...   kernelSize = 2 * int(2*sigma) + 3;     // allocate memory space for kernel   kernel = (float *)malloc(kernelSize*sizeof(float));   if(kernel == NULL){      printf("ERROR: Memory Allocation Failed..\n");      exit(-1);   }   // generate 1-D gaussian kernel   makeGaussianKernel(sigma, kernel, kernelSize);   // smoothing image with Gaussian filter   // it is convolution of image array and kernel   // Use 1D convolution because Gaussian Filter is seperable   convolve(inBuf, x, y, kernel, kernelSize, outBuf);   // free up memory space for kernel   free(kernel);#if 1   printf("sigma: %3.2f,  Kernel Size: %d\n", sigma, kernelSize);#endif}   ///////////////////////////////////////////////////////////////////////////////// generate 1D Gaussian kernel// kernel size should be odd number (3, 5, 7, 9, ...)///////////////////////////////////////////////////////////////////////////////void makeGaussianKernel(float sigma, float *kernel, int kernelSize){   //const double PI = 3.14159265;       // PI      int i, center;   float sum = 0;                      // used for normalization   double result = 0;                  // result of gaussian func   // compute kernel elements normal distribution equation(Gaussian)   // do only half(positive area) and mirror to negative side   // because Gaussian is even function, symmetric to Y-axis.   center = kernelSize / 2;   // center value of n-array(0 ~ n-1)   if(sigma == 0){      for(i = 0; i <= center; i++)         kernel[center+i] = kernel[center-i] = 0;      kernel[center] = 1.0;   }   else{      for(i = 0; i <= center; i++){         //result = exp(-(i*i)/(double)(2*sigma*sigma)) / (sqrt(2*PI)*sigma);         // dividing (sqrt(2*PI)*sigma) is not needed because normalizing result later         result = exp(-(i*i)/(double)(2*sigma*sigma));         kernel[center+i] = kernel[center-i] = (float)result;         sum += (float)result;         if(i != 0) sum += (float)result;      }      // normalize kernel      // make sum of all elements in kernel to 1      for(i = 0; i <= center; i++)         kernel[center+i] = kernel[center-i] /= sum;   }#if 0 // print result for debug   printf("1-D Gaussian Kernel\n");   printf("===================\n");   sum = 0;   for(i = 0; i < kernelSize; i++){      printf("%3d: %10.9f\n", i, kernel[i]);      sum += kernel[i];   }   printf("KERNEL SUM: %f\n", sum);#endif}      ///////////////////////////////////////////////////////////////////////////////// compute gradient (first order derivative x and y)///////////////////////////////////////////////////////////////////////////////void gradient(unsigned char *pix, int x, int y, short *deltaX, short *deltaY){   int i, j;   int t;   // compute delta X ***************************   // deltaX = f(x+1) - f(x-1)   for(i = 0; i < y; i++)   {      t = i * x;  // current position X per line       // gradient at the first pixel of each line      // note: the edge,pix[t-1] is NOT exsit      deltaX[t] = pix[t+1] - pix[t];      // gradients where NOT edge      for(j = 1; j < x-1; j++){         t++;         deltaX[t] = pix[t+1] - pix[t-1];      //printf("%d", deltaX[t]);      }      // gradient at the last pixel of each line      t++;      deltaX[t] = pix[t] - pix[t-1];      //printf("%d", deltaX[t]);   }   // compute delta Y ***************************   // deltaY = f(y+1) - f(y-1)   for(j = 0; j < x; j++)   {      t = j;   // current Y position per column      // gradient at the first pixel      deltaY[t] = pix[t+x] - pix[t];      // gradients for NOT edge pixels      for(i = 1; i < y-1; i++){         t += x;         deltaY[t] = pix[t+x] - pix[t-x];      }      // gradient at the last pixel of each column      t += x;      deltaY[t] = pix[t] - pix[t-x];   }}///////////////////////////////////////////////////////////////////////////////// compute magnitude of gradient(deltaX & deltaY) per pixel///////////////////////////////////////////////////////////////////////////////void magnitude(short *deltaX, short *deltaY, int x, int y, unsigned short *mag){   int i, j, t;#if 1 // accurate computation (SLOW)   t = 0;   for(i = 0; i < y; i++)      for(j = 0; j < x; j++, t++)      {         mag[t] = (unsigned short)(sqrt((double)deltaX[t]*deltaX[t] +                                (double)deltaY[t]*deltaY[t]) + 0.5) ;      }#endif#if 0 // faster routine (use absolute value)   t = 0;   for(i = 0; i < y; i++)      for(j = 0; j < x; j++, t++)         mag[t] = (unsigned short)(abs(deltaX[t]) + abs(deltaY[t]));#endif}///////////////////////////////////////////////////////////////////////////////// compute direction of edges for each pixel (angle of 1st derivative of image)// quantize the normal directions into 16 plus 0(dx=dy=0)///////////////////////////////////////////////////////////////////////////////void direction(short *deltaX, short *deltaY, int x, int y, unsigned char *orient){   int i, j, t;#if 1   // compute direction into 16 ways plus 0(dx=dy=0)   // it is symmetry on origin where theta > 180    // 0 : no direction, when dx = dy = 0   // 1 :       theta = 0,   when  dy = 0   // 2 :   0 < theta < 45,  when  dx > dy > 0   // 3 :       theta = 45,  when  dx = dy > 0   // 4 :  45 < theta < 90,  when  dy > dx > 0    // 5 :       theta = 90,  when  dx = 0, dy > 0   // 6 :  90 < theta < 135, when  dy > -dx > 0   // 7 :       theta = 135, when  dy = -dx > 0   // 8 : 135 < theta < 180, when -dx > dy > 0   // 9 :       theta = 180, when  dy = 0, dx > 0   //10 : 180 < theta < 225, when  -dx > -dy > 0   //11 :       theta = 225, when  dx = dy < 0   //12 : 225 < theta < 270, when  dy < dx < 0   //13 :       theta = 270, when  dx = 0, dy < 0   //14 : 270 < theta < 315, when -dy > dx > 0   //15 :       theta = 315, when  dx = -dy > 0   //16 : 315 < theta < 360, when  dx > -dy > 0   t = 0;   for(j = 0; j < y; j++)      for(i = 0; i < x; i++)      {         if(deltaX[t] == 0) // all axis directions            if(deltaY[t] == 0) orient[t] = 0;            else if(deltaY[t] > 0) orient[t] = 5;            else orient[t] = 13;         else if(deltaX[t] > 0)            if(deltaY[t] == 0) orient[t] = 1;            else if(deltaY[t] > 0)               if(deltaX[t] - deltaY[t] == 0) orient[t] = 3;               else if(deltaX[t] - deltaY[t] > 0) orient[t] = 2;               else orient[t] = 4;            else               if(deltaX[t] + deltaY[t] == 0) orient[t] = 15;               else if(deltaX[t] + deltaY[t] > 0) orient[t] = 16;               else orient[t] = 14;         else            if(deltaY[t] == 0) orient[t] = 9;            else if(deltaY[t] > 0)               if(deltaY[t] + deltaX[t] == 0) orient[t] = 7;               else if(deltaY[t] + deltaX[t] > 0) orient[t] = 6;               else orient[t] = 8;            else               if(deltaY[t] - deltaX[t] == 0) orient[t] = 11;               else if(deltaY[t] - deltaX[t] > 0) orient[t] = 10;               else orient[t] = 12;         //if(orient[t] == 16) printf("%d,%d, %d    ", deltaX[t], deltaY[t],orient[t]);         t++;      }#endif#if (0)   t = 0;   for(j = 0; j < y; j++)      for(i = 0; i < x; i++)      {         if(deltaX[t] == 0 && deltaY[t] == 0)            orient[t] = 0;         else if(deltaX[t] == 0         else if(deltaX[t] >= 0 && deltaY[t] >= 0) // quadrant I            deltaX[t] - deltaY[t] >= 0 ? orient[t] = 1 : orient[t] = 2;         else if(deltaX[t] < 0 && deltaY[t] >= 0) // quadrant II            deltaY[t] + deltaX[t] >= 0 ? orient[t] = 3 : orient[t] = 4;         else if(deltaX[t] < 0 && deltaY[t] < 0) // quadrant III            deltaY[t] - deltaX[t] >= 0 ? orient[t] = 1 : orient[t] = 2;         else if(deltaX[t] >= 0 && deltaY[t] < 0) // quadrant IV            deltaX[t] + deltaY[t] >= 0 ? orient[t] = 4 : orient[t] = 3;         printf("%d, %d %d    ", deltaX[t], deltaY[t],orient[t]);         t++; // next pixel      }#endif}///////////////////////////////////////////////////////////////////////////////// Non Maximal Suppression// If the centre pixel is not greater than neighboured pixels in the direction,// then the center pixel is set to zero.// This process results in one pixel wide ridges.///////////////////////////////////////////////////////////////////////////////void nonMaxSupp(unsigned short *mag, short *deltaX, short *deltaY, int x, int y,                unsigned char *nms){   int i, j, t;   float alpha;   float mag1, mag2;   const unsigned char SUPPRESSED = 0;   // put zero all boundaries of image   // TOP edge line of the image   for(j = 0; j < x; j++)      nms[j] = 0;   // BOTTOM edge line of image   t = (y-1)*x;   for(j = 0; j < x; j++, t++)      nms[t] = 0;   // LEFT & RIGHT edge line   t = x;   for(i = 1; i < y; i++, t+=x){      nms[t] = 0;      nms[t+x-1] = 0;   }   t = x + 1;  // skip boundaries of image   // start and stop 1 pixel inner pixels from boundaries   for(i = 1; i < y-1; i++, t+=2){      for(j = 1; j < x-1; j++, t++){         // if magnitude = 0, no edge         if(mag[t] == 0) nms[t] = SUPPRESSED;         else{            // looking for 8 directions (clockwise)            // NOTE: positive dy means down(south) direction on screen(image)            // because dy is defined as f(x,y+1)-f(x,y-1).            // 1: dy/dx <= 1,  dx > 0, dy > 0            // 2: dy/dx > 1,   dx > 0, dy > 0            // 3: dy/dx >= -1, dx < 0, dy > 0            // 4: dy/dx < -1,  dx < 0, dy > 0            // 5: dy/dx <= 1,  dx < 0, dy < 0            // 6: dy/dx > 1,   dx < 0, dy < 0            // 7: dy/dx <= -1, dx > 0, dy < 0            // 8: dy/dx > -1,  dx > 0, dy < 0            // After determine direction,            // compute magnitudes of nieghbour pixels using linear interpolation            if(deltaX[t] >= 0){               if(deltaY[t] >= 0){  // dx >= 0, dy >= 0                  if((deltaX - deltaY[t]) >= 0){      // direction 1 (SEE, South-East-East)                     alpha = (float)deltaY[t] / deltaX[t];                     mag1 = (1-alpha)*mag[t+1] + alpha*mag[t+x+1];                     mag2 = (1-alpha)*mag[t-1] + alpha*mag[t-x-1];                  }else{                              // direction 2 (SSE)                     alpha = (float)deltaX[t] / deltaY[t];                     mag1 = (1-alpha)*mag[t+x] + alpha*mag[t+x+1];                     mag2 = (1-alpha)*mag[t-x] + alpha*mag[t-x-1];                  }                     }else{ // dx >= 0, dy < 0                  if((deltaX[t] + deltaY[t]) >= 0){   // direction 8 (NEE)                     alpha = (float)-deltaY[t] / deltaX[t];                     mag1 = (1-alpha)*mag[t+1] + alpha*mag[t-x+1];                     mag2 = (1-alpha)*mag[t-1] + alpha*mag[t+x-1];                  }else{                              // direction 7 (NNE)                     alpha = (float)deltaX[t] / -deltaY[t];                     mag1 = (1-alpha)*mag[t+x] + alpha*mag[t+x-1];                     mag2 = (1-alpha)*mag[t-x] + alpha*mag[t-x+1];                  }               }            }else{               if(deltaY[t] >= 0){ // dx < 0, dy >= 0                  if((deltaX[t] + deltaY[t]) >= 0){   // direction 3 (SSW)                     alpha = (float)-deltaX[t] / deltaY[t];                     mag1 = (1-alpha)*mag[t+x] + alpha*mag[t+x-1];                     mag2 = (1-alpha)*mag[t-x] + alpha*mag[t-x+1];                  }else{                              // direction 4 (SWW)                     alpha = (float)deltaY[t] / -deltaX[t];                     mag1 = (1-alpha)*mag[t-1] + alpha*mag[t+x-1];                     mag2 = (1-alpha)*mag[t+1] + alpha*mag[t-x+1];                  }               }else{ // dx < 0, dy < 0

⌨️ 快捷键说明

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