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

📄 cannyedge.c

📁 Canny Edge sample good luck
💻 C
📖 第 1 页 / 共 3 页
字号:
                  if((-deltaX[t] + deltaY[t]) >= 0){  // direction 5 (NWW)                     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 6 (NNW)                     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];                  }               }            }            // non-maximal suppression            // compare mag1, mag2 and mag[t]            // if mag[t] is smaller than one of the neighbours then suppress it            if((mag[t] < mag1) || (mag[t] < mag2))               nms[t] = SUPPRESSED;            else{               if(mag[t] > 255) nms[t] = 255;               else nms[t] = (unsigned char)mag[t];            }         } // END OF ELSE (mag != 0)      } // END OF FOR(j)   } // END OF FOR(i)}///////////////////////////////////////////////////////////////////////////////// hysteresis thresholding// Remove weak edges and connect splitted edges// To connect edges, starting at a pixel which is greater than tHigh and search// all 8 neighbours. If the neighbour is greater than tLow, then it will also// become a edge.// The range of threshold is 0 < tLow < tHigh < 1.///////////////////////////////////////////////////////////////////////////////void hysteresis(unsigned char *nms, int x, int y, float tLow, float tHigh,                unsigned char *out){   int i, j, t;   unsigned short histo[256] = {0};   int sum, highCount;   int lowTrigger, highTrigger;   const unsigned char EDGE = 255;   // clear out buffer(set all to 0)   for(i = t = 0; i < y; i++)      for(j = 0; j < x; j++, t++)         out[t] = 0;   // compute histogram to get high & low level trigger   histogram(nms, x, y, histo, NULL, NULL);   // find pixel count where tHigh(percentage) of pixels   highCount = (x*y) * tHigh + 0.5;   // compute low & high level trigger(threshold)   i = 255;       // max value in unsigned char   sum = x * y;   // total sum of histogram array   while(sum > highCount){      sum -= histo[i];      i--;   }   highTrigger = ++i;   lowTrigger = highTrigger * tLow + 0.5;#if 1   printf("HighTreshold: %4.2f,  LowTreshold: %4.2f\n", tHigh, tLow);   printf("HighTrigger: %d,  LowTrigger: %d\n", highTrigger, lowTrigger);#endif   // search a pixel which is greater than high level trigger   // then mark it as an edge and start to trace edges using low trigger   // If the neighbors are greater than low trigger, they become edges   // NOTE: Use general thresholding method for faster computation, but   //       hysteresis thresholding can eliminates noise pixels.   t = x + 1;  // skip boundaries   for(i = 1; i < y-1; i++, t+=2)      for(j = 1; j < x-1; j++, t++)      {         if(nms[t] >= highTrigger){            out[t] = EDGE;            traceEdge(nms, t, x, lowTrigger, out);         }      }}///////////////////////////////////////////////////////////////////////////////// search 8 neighbour pixels and trace edge if they are greater than threshold// This is recursive routine.///////////////////////////////////////////////////////////////////////////////void  traceEdge(unsigned char *nms, int t, int numCols, int threshold,                unsigned char *out){   int i, j, ptr;   const unsigned char EDGE = 255;   const unsigned char NOEDGE = 0;   // check 8-connectivity of buf[t]   for(i = -1; i <= 1; i++)      for(j = -1; j <= 1; j++)      {         ptr = t + (i*numCols) + j;    // get neighbour's pointer      //printf("ptr: %d, nms[ptr]: %d\n", ptr, nms[t]);         if(ptr == t) continue;        // skip itself         if(out[ptr] == EDGE) continue;         if(nms[ptr] >= threshold){            out[ptr] = EDGE;           // found edge            // re-trace edges from at current point            traceEdge(nms, ptr, numCols, threshold, out);         }else            out[ptr] = NOEDGE;      }}///////////////////////////////////////////////////////////////////////////////// generate histogram of the image (input buffer is unsigned char, 1-Byte long)///////////////////////////////////////////////////////////////////////////////void histogram(unsigned char *buf, int x, int y, unsigned short *histo,               int *min, int *max){   int bufLength = x * y;   *min = *max = buf[0];   for(int i = 0; i < bufLength; i++)   {      histo[buf[i]]++;      if(buf[i] < *min) *min = buf[i];      if(buf[i] > *max) *max = buf[i];   }}///////////////////////////////////////////////////////////////////////////////// generate histogram of the image (input buffer is short, 2-byte long)///////////////////////////////////////////////////////////////////////////////void histogram(unsigned short *buf, int x, int y, unsigned int *histo,               int *min, int *max){   unsigned int i;   unsigned int bufLength = x * y;      *min = *max = buf[0];   for(i = 0; i < bufLength; i++)   {      histo[buf[i]]++;      if(buf[i] < *min) *min = buf[i];      if(buf[i] > *max) *max = buf[i];   }}///////////////////////////////////////////////////////////////////////////////// Linear Interpolation of two points P1 & P2 where weight t// the range of weight(t) is 0 < t < 1.// Ohter than this range will be extrapolation.///////////////////////////////////////////////////////////////////////////////float linearInterp(float p1, float p2, float t){   float result;   if(t <= 0)      result = p1;   else if(t > 0 && t < 1)      result = (1 - t) * p1 + (t * p2);   else if(t >= 1)      result = p2;   return result;}///////////////////////////////////////////////////////////////////////////////// Bi-Linear interpolation (2D)// interpolation on 2-D plane with 4 points// the range of weight(tx, ty) is 0 < tx(ty) < 1///////////////////////////////////////////////////////////////////////////////float bilinearInterp(float p1, float p2, float p3, float p4, float tx, float ty){   float x1, x2;  // result of x(herizontal) drection   float result;   // interpolate X(horizontal) direction first   if(tx <= 0){      x1 = p1;      x2 = p3;   }   else if(tx > 0 && tx < 1){      x1 = (1 - tx) * p1 + (tx * p2);   // point 1 & 2      x2 = (1 - tx) * p3 + (tx * p4);   // point 3 & 4   }   else if(ty >= 1){      x1 = p2;      x2 = p4;   }   // interploate x1 & x2 in Y(vertical) direction   if(ty <= 0)      result = x1;   else if(ty > 0 && ty < 1)      result = (1 - ty) * x1 + (ty * x2);   // point x1 & x2   else if(ty >= 1)      result = x2;   return result;}///////////////////////////////////////////////////////////////////////////////// thresholding using percent threshold parameter(0 ~ 1)// If pixel is under threshold(percent), set to zero.///////////////////////////////////////////////////////////////////////////////void threshold(unsigned char *buf, int x, int y, float p){   int i, j, t;   int min, max;   float level;   // compute max and min value of image   t = 0;   min = max = buf[t];   for(i = 0; i < y; i++){      for(j = 0; j < x; j++, t++)      {         if(buf[t] < min) min = buf[t];         if(buf[t] > max) max = buf[t];      }   }   // compute threshold level   level = p*(max-min)+ min;   // thresholding   t = 0;   for(i = 0; i < y; i++){      for(j = 0; j < x; j++, t++)      {         if(buf[t] < level)            buf[t] = 0;         else            buf[t] = 255;      }   }    }//=============================================================================// CALLBACKS//=============================================================================void displayCB(void){   glutSetWindow(mainWin);   glClear(GL_COLOR_BUFFER_BIT); // clear canvas   //glutSwapBuffers();   // specify current paster position(coordinate)   glRasterPos2i(0, SIZE_Y);  // upper-left corner in openGL coordinates   glPixelZoom(1.0, -1.0);   // draw source image   glDrawPixels(imgData->x, imgData->y, imgData->format,                imgData->type, inBuf);   //glColor3f(0,0,1);   //drawString("Original Image", fontWidth, SIZE_Y-fontHeight, (void*)font);   //glFlush();   glutSwapBuffers();}void displaySubWin1CB(void){   glutSetWindow(subWin1);   glClear(GL_COLOR_BUFFER_BIT); // clear canvas   // specify current paster position(coordinate)   glRasterPos2i(0, SIZE_Y);  // upper-left corner in openGL coordinates   glPixelZoom(1.0, -1.0);   // draw the processed image pixels   glDrawPixels(imgData->x, imgData->y, imgData->format,                imgData->type, outBuf);   //glColor3f(1,0,0);   //drawString("Gaussian Smooth", fontWidth, SIZE_Y-fontHeight, (void*)font);   glutSwapBuffers();}void reshapeCB(int w, int h){   glViewport(0, 0, (GLsizei)w, (GLsizei)h);   // main-window   glutSetWindow(mainWin);   //glutPositionWindow(100,100);   //glutReshapeWindow(2*SIZE_X, SIZE_Y);   //glViewport(0, 0, SIZE_X, SIZE_Y);   glMatrixMode(GL_PROJECTION);   glLoadIdentity();   gluOrtho2D(0, SIZE_X, 0, SIZE_Y);   // right sub-window   glutSetWindow(subWin1);    glutPositionWindow(SIZE_X, 0);   glutReshapeWindow(SIZE_X, SIZE_Y);   glViewport(0, 0, SIZE_X, SIZE_Y);   glMatrixMode(GL_PROJECTION);   glLoadIdentity();   gluOrtho2D(0, SIZE_X, 0, SIZE_Y);   glMatrixMode(GL_MODELVIEW);   glLoadIdentity();}void keyboardHandlerCB(unsigned char key, int x, int y){   switch(key)   {      case 27: // ESCAPE         free(imgData);         free(inBuf);         free(outBuf);         glutDestroyWindow(subWin1);         glutDestroyWindow(mainWin);         exit(0);         break;      case 'r':      case 'R':         imgData->buf = (GLvoid*)inBuf;         break;   }   // because this keyboard handler is shared,   // redraw all windows whenever keyevents received   glutSetWindow(mainWin);   glutPostRedisplay();   glutSetWindow(subWin1);   glutPostRedisplay();}

⌨️ 快捷键说明

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