作者:gnuhpc
出处:http://www.cnblogs.com/gnuhpc/
#include "cv.h" #include "highgui.h" #include <stdio.h> #include "SamFL.h" #define DIF_NEG 0 #define DIF_POS 1 #define NOT_EDGE 0 #define EDGE 1 double edge_maxima[] = { 0 ,255 }; double edge_thresh; int trackbar_value=20; IplImage* grnt; IplImage* edge; double isEdge(double x , double *val) { double GrayDifNeg[8]; double GrayDifPos[8]; double Edge[2]; double Q[8]; double r[8]; int i; for(i =0; i<8;i++){ Q[i]=val[i]-x;//算出Gray_Dif(i) /* 计算出Membership Function */ GrayDifNeg[i]=sfl_fuzzyfier_s(Q[i], -255.0,edge_thresh); GrayDifPos[i]=sfl_fuzzyfier_s(Q[i], edge_thresh, 255.0); } // Rules r[0]=sfl_and(sfl_and(sfl_and(GrayDifNeg[0],GrayDifNeg[1]),GrayDifNeg[7]),sfl_and(sfl_and(GrayDifPos[3],GrayDifPos[4]),GrayDifPos[5])); r[1]=sfl_and(sfl_and(sfl_and(GrayDifPos[0],GrayDifPos[1]),GrayDifPos[7]),sfl_and(sfl_and(GrayDifNeg[3],GrayDifNeg[4]),GrayDifNeg[5])); r[2]=sfl_and(sfl_and(sfl_and(GrayDifNeg[1],GrayDifNeg[2]),GrayDifNeg[3]),sfl_and(sfl_and(GrayDifPos[5],GrayDifPos[6]),GrayDifPos[7])); r[3]=sfl_and(sfl_and(sfl_and(GrayDifPos[1],GrayDifPos[2]),GrayDifPos[3]),sfl_and(sfl_and(GrayDifNeg[5],GrayDifNeg[6]),GrayDifNeg[7])); r[4]=sfl_and(sfl_and(sfl_and(GrayDifNeg[2],GrayDifNeg[3]),GrayDifNeg[4]),sfl_and(sfl_and(GrayDifPos[0],GrayDifPos[7]),GrayDifPos[6])); r[5]=sfl_and(sfl_and(sfl_and(GrayDifPos[2],GrayDifPos[3]),GrayDifPos[4]),sfl_and(sfl_and(GrayDifNeg[0],GrayDifNeg[7]),GrayDifNeg[6])); r[6]=sfl_and(sfl_and(sfl_and(GrayDifNeg[0],GrayDifNeg[1]),GrayDifNeg[2]),sfl_and(sfl_and(GrayDifPos[4],GrayDifPos[5]),GrayDifPos[6])); r[7]=sfl_and(sfl_and(sfl_and(GrayDifPos[0],GrayDifPos[1]),GrayDifPos[2]),sfl_and(sfl_and(GrayDifNeg[4],GrayDifNeg[5]),GrayDifNeg[6])); /* 计算边界 */ Edge[EDGE]=sfl_or(r[0],sfl_or(r[1],sfl_or(r[2],sfl_or(r[3],sfl_or(r[4],sfl_or(r[5],sfl_or(r[6],r[7]))))))); Edge[NOT_EDGE]=sfl_not(Edge[EDGE]); /* 解模糊 */ return sfl_defuzzyfier_coa(2,Edge,edge_maxima); } IplImage* FuzzyEdge(IplImage* image, float thresh ) { IplImage *gray, *edge; gray = cvCreateImage(cvSize(image->width,image->height), IPL_DEPTH_8U, 1); edge = cvCreateImage(cvSize(image->width,image->height), IPL_DEPTH_8U, 1); cvCvtColor(image, gray, CV_BGR2GRAY);//将图像转化为灰度图像 cvZero(edge); cvNot( gray, edge ); uchar *data= (uchar *)gray->imageData; uchar *Edata= (uchar *)edge->imageData; int height = gray->height; int width = gray->width; int step = gray->widthStep; double in[8]; edge_thresh=thresh; int i,j; for(i=1;i<height-1;i++){ for(j=1;j<width-1;j++){ /* 取出Q点的周围的八个点的灰度值 */ in[0]=data[(i-1)*step+(j+1)];//点7 in[1]=data[(i-1)*step+(j)];//点8 in[2]=data[(i-1)*step+(j-1)];//点1 in[3]=data[(i)*step+(j-1)];//点2 in[4]=data[(i+1)*step+(j-1)];//点3 in[5]=data[(i+1)*step+(j)];//点4 in[6]=data[(i+1)*step+(j+1)];//点5 in[7]=data[(i)*step+(j+1)];//点6 /* 然后有isEdge算出是否为边缘,传入参数第一个是Q点的灰度值, * 第二个是周围八个点的灰度值*/ Edata[i*step+j]=isEdge(data[(i)*step+(j)],in); } } cvReleaseImage( &gray ); return edge; } void on_trackbar(int pos) { edge=FuzzyEdge(grnt,trackbar_value-20); /* FuzzyEdge是主要处理函数 */ cvShowImage("Fuzzy Edge", edge); cvReleaseImage( &edge ); } int main() { char Buf[512]; /* 先取得图片名称 */ puts("Enter Image File Name :"); gets(Buf); /* 装载图片 */ grnt = cvLoadImage(Buf,1); if(grnt){ cvNamedWindow("Orginal Image", 0); cvShowImage("Orginal Image", grnt); cvNamedWindow("Fuzzy Edge", 0); cvCreateTrackbar( "Threshold", "Fuzzy Edge", &trackbar_value, 40, on_trackbar ); on_trackbar(0); cvWaitKey(0); cvDestroyWindow( "Orginal Image" ); cvReleaseImage( &grnt ); cvDestroyWindow( "Fuzzy Edge" ); return 0; } else{ puts("I can not open Image File !!! :( "); cvWaitKey(0); return -1; } } 该程序使用的模糊逻辑库SamFl和源程序,以及依据理论的paper在如下地址: http://blogimg.chinaunix.net/blog/upfile2/090113090453.gz