模式识别 之 初学
一. 模糊距离
1. 欧氏距离
1) 欧氏距离 平方根((x1 - x2)*(x1-x2) + (y1 - y2)*(y1-y2))
for (int i=0; i<N*N; i++)
result+=(pattern1.feature[i]-pattern2.feature[i])*(pattern1.feature[i]-pattern2.feature[i]);
2) 夹角余弦 xy/平方根(xx*yy);
double a,b1,b2;
a=0;
b1=0;
b2=0;
for (int i=0; i<N*N; i++)
{
a +=pattern1.feature[i]*pattern2.feature[i];
b1+=pattern1.feature[i]*pattern1.feature[i];
b2+=pattern2.feature[i]*pattern2.feature[i];
}
if (b2*b1!=0)
result=a/sqrt(b1*b2);
else
{
return -1;
}
return (1-result);
3) 二值夹解余弦
int *t1,*t2;
int a,b1,b2;
a=0;b1=0;b2=0;
t1=new int [N*N];
t2=new int [N*N];
for(int i=0; i<N*N; i++)
{
t1[i]=pattern1.feature[i]>0.2? 1:0;
t2[i]=pattern2.feature[i]>0.2? 1:0;
}
for ( i=0; i<N*N; i++)
{
a+=t1[i]*t2[i];
b1+=t1[i]*t1[i];
b2+=t2[i]*t2[i];
}
delete []t1;
delete []t2;
if (b2*b1!=0)
result=(double)(a/sqrt(b1*b2));
4) 二值特征的Tanimoto测度
int *t1,*t2;
int a,b1,b2;
a=0;b1=0;b2=0;
t1=new int [N*N];
t2=new int [N*N];
for(int i=0; i<N*N; i++)
{
t1[i]=pattern1.feature[i]>0.2? 1:0;
t2[i]=pattern2.feature[i]>0.2? 1:0;
}
for ( i=0; i<N*N; i++)
{
a+=t1[i]*t2[i];
b1+=t1[i]*t1[i];
b2+=t2[i]*t2[i];
}
delete []t1;
delete []t2;
if ((b2*b1-a)!=0)
result=(double)(a/(b1+b2-a));
else
{
return -1;
}
return (1-result);
2. 数量积
double temp,max;
max=0;
for (int i=0; i<patternnum-1; i++)
for (int j=0; j<patternnum; j++)
{
temp=0;
for (int k=0; k<N*N; k++)
{
temp+=m_pattern[i].feature[k]*m_pattern[j].feature[k];
}
if (max<temp)
max=temp;
}
temp=0;
for ( i=0; i<N*N; i++)
{
temp+=pattern1.feature[i]*pattern2.feature[i];
}
return (temp/max);
3. 相关系数
{
double ap1,ap2;
ap1=0;ap2=0;
for (int i=0; i<N*N; i++)
{
ap1+=pattern1.feature[i];
ap2+=pattern2.feature[i];
}
ap1/=N;
ap1/=N;
double a,b1,b2;
a=0;b1=0;b2=0;
for (i=0; i<N*N; i++)
{
a+=(pattern1.feature[i]-ap1)*(pattern2.feature[i]-ap2);
b1+=(pattern1.feature[i]-ap1)*(pattern1.feature[i]-ap1);
b2+=(pattern2.feature[i]-ap2)*(pattern2.feature[i]-ap2);
}
if (b2*b1!=0)
return (a/sqrt(b1*b2));
}
4. 最大最小法
{
double min ,max;
min=0; max=0;
for (int i=0; i<N*N; i++)
{
min+=pattern1.feature[i]<pattern2.feature[i]? pattern1.feature[i]:pattern2.feature[i];
max+=pattern1.feature[i]<pattern2.feature[i]? pattern2.feature[i]:pattern1.feature[i];
}
if (max!=0)
return (min/max);
}
5. 算数平均
{
double min ,max;
min=0; max=0;
for (int i=0; i<N*N; i++)
{
min+=pattern1.feature[i]<pattern2.feature[i]? pattern1.feature[i]:pattern2.feature[i];
max+=pattern1.feature[i]+pattern2.feature[i];
}
if (max!=0)
return (2*min/max);
}
6. 几何平均最小法
{
double min ,max;
min=0; max=0;
for (int i=0; i<N*N; i++)
{
min+=pattern1.feature[i]<pattern2.feature[i]? pattern1.feature[i]:pattern2.feature[i];
max+=sqrt(pattern1.feature[i]*pattern2.feature[i]);
}
if (max!=0)
return (min/max);
}
下面弄个实例: 书上的,先照做,再修改..
二. 模糊聚类
1. 计算,特征间距离
int patternnum = SubImgIndex;
double *dis = new double[patternnum*patternnum];
double max = 0;
for (int i=0; i<(patternnum - 1); i++)
{
for (int j=i+1; j<patternnum; j++)
{
double tmp = GetDistance(&pSubImgList[i], &pSubImgList[j],1);
if (tmp > max)
{
max = tmp;
}
}
}
//初始模糊距离
for (int i=0; i<patternnum; i++)
{
for (int j=0; j<patternnum; j++)
{
dis[i*patternnum + j] = (max - GetDistance(&pSubImgList[i], &pSubImgList[j],1) ) / max;
}
}
double *TmpDis = new double[patternnum*patternnum];
2. //构靠等价矩阵
bool bflag = true;
while (bflag)
{
bflag = false;
for (int i=0; i<patternnum; i++)
{
for (int j=0; j<patternnum; j++)
{
if (i==j)
{
TmpDis[i*patternnum + j] = 1.0;
}
else
{
TmpDis[i*patternnum + j] = GetDistance(dis,i,j, patternnum);
}
}
}
for (int i=0; i<patternnum; i++)
{
for (int j=0; j<patternnum; j++)
{
if (abs(TmpDis[i*patternnum + j] - TmpDis[i*patternnum + j]) > 0.001 )
{
bflag = true;
break;
}
}
if (bflag == true)
{
break;
}
}
for (int i=0; i<patternnum*patternnum; i++)
{
dis[i] = TmpDis[i];
}
}
3. 稀疏矩阵
//////////////////////////////////////////////////////////
//
double *xishu = new double[patternnum*patternnum];
for (int i = 0; i<patternnum*patternnum; i++)
{
xishu[i] = -1;
}
int point = 0;
for (int i=0; i<patternnum; i++)
{
for (int j=0; j<patternnum; j++)
{
bool done = false;
for (int k=0; k<point; k++)
{
if (abs(xishu[k] - dis[i*patternnum+j])<0.001)
{
done = true;
break;
}
}
if (!done)
{
xishu[point] = dis[i*patternnum + j];
point++;
}
}
}
for (int i=0; i<point - 1; i++)
{
for (int j=0; j<point - i - 1; j++)
{
if (xishu[j]>xishu[j+1])
{
double tmp = xishu[j];
xishu[j] = xishu[j+1];
xishu[j+1] = tmp;
}
}
}
4. 根据阀值计算...
int *res = new int[patternnum*patternnum];
for (int i=0; i<patternnum*patternnum; i++)
{
if (dis[i] >=0.5)
{
res[i] = 1;
}
else
{
res[i] = 0;
}
}
最后结果:
哈,还不错,虽然模糊聚类过程中不明白,但过程算是了解了!