- Visual C++数字图像模式识别典型案例详解
- 冯伟兴 梁洪 王臣业编著
- 697字
- 2025-03-16 03:50:43
4.4.3 模糊聚类
编程实现
[1] 在类CCluster中添加函数FuzzyCluster(),进行有关图像的模糊聚类。具体实现代码如代码4-4所示。
代码4-4 FuzzyCluster()函数
void CCluster::FuzzyCluster() { GetFeature(); //获得所有样品特征 double *dis, *tempdis; double dismax; int i,j; int distype; dismax=0; dis=new double [patternnum*patternnum]; //模糊系数矩阵 tempdis=new double [patternnum*patternnum]; return; distype=julizl; //此处为声明模糊距离的总类 //得到初始模糊距离 for ( i=0; i<patternnum; i++) for (j=0; j<patternnum; j++) { dis[i*patternnum+j]=GetFuzzyDistance(m_pattern[i],m_pattern[j], distype);//distype } //构造等价类 bool flag; flag=true; while (flag) { flag=false; for ( i=0; i<patternnum; i++) for ( j=0; j<patternnum; j++) if (i==j)//对角线为1 tempdis[i*patternnum+j]=1; else tempdis[i*patternnum+j]=GetDistance(dis,i,j); for ( i=0; i<patternnum; i++) { for ( j=0; j<patternnum; j++) if ((tempdis[i*patternnum+j]-dis[i*patternnum+j])*(tempdis [i*patternnum+j]-dis[i*patternnum+j])>0.000001)//(tdis[i][j]!=dis[i][j]) { flag=true; break; } if (flag) break; } for ( i=0; i<patternnum*patternnum; i++) dis[i]=tempdis[i]; } //输出模糊矩阵 CString ts,sout; //第一行标号1,2, …, patternnum sout.Insert(sout.GetLength()," \t"); for (i=1; i<=patternnum; i++) { ts.Format("%d \t",i); sout.Insert(sout.GetLength(),ts); } sout.Insert(sout.GetLength(),"\n\n"); for (i=0; i<patternnum; i++) { //每列开头标号 ts.Format("%d \t",i+1); sout.Insert(sout.GetLength(),ts); //输出模糊系数矩阵 for(j=0; j<patternnum; j++) { ts.Format("%0.3f\t",dis[i*patternnum+j]); sout.Insert(sout.GetLength(),ts); if ((j+1)%patternnum==0) sout.Insert(sout.GetLength(),"\n\n\n"); } } MessageBox(NULL, sout, "模糊矩阵", MB_OK); delete []tempdis; double *xishu=new double [patternnum*patternnum]; for(i=0; i<patternnum*patternnum; i++) xishu[i]=-1; int pointer=0; //记录模糊系数矩阵中不同的系数 for ( i=0; i<patternnum; i++) for ( j=i; j<patternnum; j++) { bool done=false; for (int k=0; k<pointer; k++) { if ((xishu[k]-dis[i*patternnum+j])*(xishu[k]-dis[i*patternnum+j])<0.000001) { done=true; break; } } if (!done) { xishu[pointer]=dis[i*patternnum+j]; pointer++; } } for(i=0; i<pointer-1; i++)//对阈值由小到大排序 for (j=0; j<pointer-i-1; j++) { if (xishu[j]>xishu[j+1]) { double temp=xishu[j]; xishu[j]=xishu[j+1]; xishu[j+1]=temp; } } CString s,str; for (i=0; i<pointer; i++) { s.Format("%0.4f ",xishu[i]); str.Insert(str.GetLength(),s); } delete []xishu; //用户输入聚类阈值 double yz; DLGmohu1 mohu; mohu.m_Mohuxishu=str; if (mohu.DoModal()==IDOK) { yz=mohu.m_Mohuyuzhi; } else return; int *result; //根据阈值输出聚类结果 result=new int [patternnum*patternnum]; for (i=0; i<patternnum*patternnum; i++) if (dis[i]>=yz) result[i]=1; else result[i]=0; //分类后输出 //第一行标号 sout=""; sout.Insert(-1, "每行中\"1\"对应的列为同一类"); sout.Insert(sout.GetLength(),"\n\n"); sout.Insert(sout.GetLength()," \t"); for (i=1; i<=patternnum; i++) { ts.Format("%d \t",i); sout.Insert(sout.GetLength(),ts); } sout.Insert(sout.GetLength(),"\n\n"); for (i=0; i<patternnum; i++) { //每列开头标号 ts.Format("%d \t",i+1); sout.Insert(sout.GetLength(),ts); for(j=0; j<patternnum; j++)//首行为原模糊系数 { ts.Format("%0.3f\t",dis[i*patternnum+j]); sout.Insert(sout.GetLength(),ts); if ((j+1)%patternnum==0) sout.Insert(sout.GetLength(),"\n"); } sout.Insert(sout.GetLength()," \t"); for(j=0; j<patternnum; j++)//次行为根据阈值修改后的系数“1”或“0” { ts.Format("%d\t",result[i*patternnum+j]); sout.Insert(sout.GetLength(),ts); if ((j+1)%patternnum==0) sout.Insert(sout.GetLength(),"\n\n"); } } MessageBox(NULL, sout, "分类前后的矩阵对照", MB_OK); centernum=0; for (i=0; i<patternnum; i++)//按照阈值分类 for (j=i; j<patternnum; j++) { if (result[i*patternnum+j]==1) { if (m_pattern[i].category!=0) m_pattern[j].category=m_pattern[i].category; else if (m_pattern[j].category!=0) m_pattern[i].category=m_pattern[j].category; else { centernum++; m_pattern[j].category=centernum; m_pattern[i].category=centernum; } } } delete []dis; delete []result; } void CCluster::huasz(int p,int q,int t) { int tmp;tmp=p; p=q;q=tmp;/////////////////////////////////////////////// int i,j; for(i=0;i<16;i++) for(j=0;j<16;j++) *(m_pData+(height-(i+p))*wide+j+q)=sz[t][(15-i)*16+j]*255; }
[2] 上述代码中,GetDistance ()函数用于返回模糊距离数组中第i行第j列的模糊积,该函数的实现代码如代码4-5所示。
代码4-5 GetDistance ()函数
double CCluster::GetDistance(double *dis, int i, int j) { double result; result=0; for(int t=0;t<patternnum;t++) { double td=dis[i*patternnum+t]<dis[t*patternnum+j]? dis[i*patternnum+t]:dis[t*patternnum+j]; if (result<td) result=td; } return result; }