double Robert(double *src,double *dst,double *edgedriction,int width,int height){ double RobertMask_x[9]={0,0,0,0,-1,0,0,0,1}; double RobertMask_y[9]={0,0,0,0,0,-1,0,1,0}; double *dst_x=(double *)malloc(sizeof(double)*width*height); double *dst_y=(double *)malloc(sizeof(double)*width*height); RealConvolution(src, dst_x, RobertMask_x, width, height, ROBERT_MASK_SIZE,ROBERT_MASK_SIZE); RealConvolution(src, dst_y, RobertMask_y, width, height, ROBERT_MASK_SIZE,ROBERT_MASK_SIZE); if(edgedriction!=NULL) getEdgeAngle(dst_x, dst_y, edgedriction, width, height); for(int j=0;j<height;j++) for(int i=0;i<width;i++){ dst[j*width+i]=abs(dst_x[j*width+i])+abs(dst_y[j*width+i]); } free(dst_x); free(dst_y); return findMatrixMax(dst,width,height,NULL); }
//DoG完整过程 //生成DoG模板 //卷积 //寻找零交叉 double DoG(double *src,double *dst,int width,int height,int m_width,int m_height,double delta,double threshold){ double *dsttemp=(double *)malloc(sizeof(double)*width*height); double * mask=(double *)malloc(sizeof(double)*m_width*m_height); getDoGMask(mask, m_width,m_height,delta); RealConvolution(src, dsttemp, mask, width, height, m_width, m_height); findCross(dsttemp, dst, width, height,threshold); free(dsttemp); free(mask); return findMatrixMax(dst,width,height,NULL); }
double Scharr(double *src,double *dst,double *edgedriction,int width,int height){ double ScharrMask1[3]={3,10,3}; double ScharrMask2[3]={1,0,-1}; double *dst_x=(double *)malloc(sizeof(double)*width*height); double *dst_y=(double *)malloc(sizeof(double)*width*height); RealConvolution(src, dst_x, ScharrMask1, width, height, 1, 3); RealConvolution(dst_x, dst_x, ScharrMask2, width, height, 3, 1); RealConvolution(src, dst_y, ScharrMask2, width, height, 1, 3); RealConvolution(dst_y, dst_y, ScharrMask1, width, height, 3, 1); for(int i=0;i<width*height;i++) dst_y[i]=-dst_y[i]; if(edgedriction!=NULL) getEdgeAngle(dst_x, dst_y, edgedriction, width, height); for(int j=0;j<height;j++) for(int i=0;i<width;i++){ dst[j*width+i]=abs(dst_x[j*width+i])+abs(dst_y[j*width+i]); } free(dst_x); free(dst_y); return findMatrixMax(dst,width,height,NULL); }
Pixel32 *tileutils_LowPassFilter(Pixel32 *image, uint32 width, uint32 height) { double LP1[]= { 0.11111111, 0.11111111, 0.11111111, 0.11111111, 0.11111111, 0.11111111, 0.11111111, 0.11111111, 0.11111111 }; Pixel32 *filteredImage; if (!RealConvolution(image, width, height, 0, 0, LP1, 3, 3, g_lowPassScale, FALSE, &filteredImage)) { free(image); return filteredImage; } else { return NULL; } }
double Sobel(double *src,double *dst,double *edgedriction,int width,int height,int sobel_size){ //double SobelMask_x[3]={-1,-2,-1,0,0,0,1,2,1}; double *dst_x=(double *)malloc(sizeof(double)*width*height); double *dst_y=(double *)malloc(sizeof(double)*width*height); if(sobel_size==-1){ return Scharr(src, dst, edgedriction, width, height); } else if(sobel_size==3){ double SobelMask1[3]={0.25,0.5,0.25}; double SobelMask2[3]={1,0,-1}; RealConvolution(src, dst_y, SobelMask2, width, height, 1, 3 ); RealConvolution(dst_y, dst_y,SobelMask1, width, height, 3, 1); RealConvolution(src, dst_x, SobelMask1, width, height, 1, 3); RealConvolution(dst_x, dst_x, SobelMask2, width, height, 3, 1); }else if(sobel_size==5){ double SobelMask1[5]={1/16.,4/16.,6/16.,4/16.,1/16.}; double SobelMask2[5]={1/3.,2/3.,0,-2/3.,-1/3.}; RealConvolution(src, dst_x, SobelMask1, width, height, 1, 5); RealConvolution(dst_x, dst_x, SobelMask2, width, height, 5, 1); RealConvolution(src, dst_y, SobelMask2, width, height, 1, 5); RealConvolution(dst_y, dst_y, SobelMask1, width, height, 5, 1); }else if(sobel_size==7){ double SobelMask1[7]={1/64.,6/64.,15/64.,20/64.,15/64.,6/64.,1/64.}; double SobelMask2[7]={0.1,0.4,0.5,0,-0.5,-0.4,-0.1}; RealConvolution(src, dst_x, SobelMask1, width, height, 1, 7); RealConvolution(dst_x, dst_x, SobelMask2, width, height, 7, 1); RealConvolution(src, dst_y, SobelMask2, width, height, 1, 7); RealConvolution(dst_y, dst_y, SobelMask1, width, height, 7, 1); } for(int i=0;i<width*height;i++) dst_y[i]=-dst_y[i]; if(edgedriction!=NULL) getEdgeAngle(dst_x, dst_y, edgedriction, width, height); for(int j=0;j<height;j++) for(int i=0;i<width;i++){ dst[j*width+i]=abs(dst_x[j*width+i])+abs(dst_y[j*width+i]); } free(dst_x); free(dst_y); return findMatrixMax(dst,width,height,NULL); }
void Canny(double *src,double *dst,int width,int height,int sobel_size,double threshold1,double threshold2){ double *temp=(double *)malloc(sizeof(double)*width*height); double *edge_a=(double *)malloc(sizeof(double)*width*height);//边缘幅度 double *edge_d=(double *)malloc(sizeof(double)*width*height);//边缘方向 double *threshold_max=(double *)malloc(sizeof(double)*width*height); double *threshold_min=(double *)malloc(sizeof(double)*width*height); /********************************************************************* *step1:gaussian smooth *********************************************************************/ double gaussianmask[25]={ 2, 4, 5, 4, 2, 4, 9,12, 9, 4, 5,12,15,12, 5, 4, 9,12, 9, 4, 2, 4, 5, 4, 2}; RealConvolution(src, temp, gaussianmask, width, height, 5, 5); matrixMultreal(temp, temp, 1.0/159.0, width, height); /********************************************************************* *step2:sobel *********************************************************************/ if(sobel_size==3) Scharr(temp, edge_a, edge_d, width, height); else if(sobel_size==5||sobel_size==7) Sobel(temp, edge_a, edge_d, width, height,sobel_size); /********************************************************************* *step3:Non_MaxSuppression *********************************************************************/ getEdgeDirection(edge_d, edge_d, width, height); Non_MaxSuppression(edge_a, temp, edge_d, width, height); /********************************************************************* *step4:double threshold *********************************************************************/ Threshold(temp, threshold_max, width, height, threshold1, THRESHOLD_TYPE1); Threshold(temp, threshold_min, width, height, threshold2, THRESHOLD_TYPE1); NonZeroSetOne(threshold_max,threshold_max,width,height); NonZeroSetOne(threshold_min,threshold_min,width,height); for(int j=0;j<height;j++){ for(int i=0;i<width;i++){ if(threshold_max[j*width+i]==1.0&&threshold_min[j*width+i]!=2.0){ Position p; p.x=i; p.y=j; EdgeTrack(threshold_min, width, height, &p); } } } /********************************************************************* *step5:result *********************************************************************/ Zero(dst, width, height); for(int i=0;i<width*height;i++) if(threshold_min[i]==2.0) dst[i]=255.0; free(temp); free(threshold_max); free(threshold_min); free(edge_d); free(edge_a); }