伴隨着模糊集理論的形成、發展和深化,RusPini率先提出模糊划分的概念。以此為起點和基礎,模糊聚類理論和方法迅速蓬勃發展起來。針對不同的應用,人們提出了很多模糊聚類算法,比較典型的有基於相似性關系和模糊關系的方法、基於模糊等價關系的傳遞閉包方法、基於模糊圖論的最大支撐樹方法,以及基於數據集的凸分解、動態規划和難以辨別關系等方法。然而,上述方法均不能適用於大數據量的情況,難以滿足實時性要求較高的場合,因此實際應用並不廣泛。
模糊聚類分析按照聚類過程的不同大致可以分為三大類:
(1)基於模糊關系的分類法:其中包括譜系聚類算法(又稱系統聚類法)、基於等價關系的聚類算法、基於相似關系的聚類算法和圖論聚類算法等等。它是研究比較早的一種方法,但是由於它不能適用於大數據量的情況,所以在實際中的應用並不廣泛。
(2)基於目標函數的模糊聚類算法:該方法把聚類分析歸結成一個帶約束的非線性規划問題,通過優化求解獲得數據集的最優模糊划分和聚類。該方法設計簡單、解決問題的范圍廣,還可以轉化為優化問題而借助經典數學的非線性規划理論求解,並易於計算機實現。因此,隨着計算機的應用和發展,基於目標函數的模糊聚類算法成為新的研究熱點。
(3)基於神經網絡的模糊聚類算法:它是興起比較晚的一種算法,主要是采用競爭學習算法來指導網絡的聚類過程。
在介紹算法之前,先介紹下模糊集合的知識。
HCM聚類算法
首先說明隸屬度函數的概念。隸屬度函數是表示一個對象x 隸屬於集合A 的程度的函數,通常記做μA(x),其自變量范圍是所有可能屬於集合A 的對象(即集合A 所在空間中的所有點),取值范圍是[0,1],即0<=μA(x),μA(x)<=1。μA(x)=1 表示x 完全隸屬於集合A,相當於傳統集合概念上的x∈A。一個定義在空間X={x}上的隸屬度函數就定義了一個模糊集合A,或者叫定義在論域X={x}上的模糊子集A’。對於有限個對象x1,x2,……,xn 模糊集合A’可以表示為:
有了模糊集合的概念,一個元素隸屬於模糊集合就不是硬性的了,在聚類的問題中,可以把聚類生成的簇看成模糊集合,因此,每個樣本點隸屬於簇的隸屬度就是[0,1]區間里面的值。
再接下來要講FCM算法不得不先講一下HCM算法
硬C-均值(HCM)算法是實現數據集J硬C划分的經典算法之一,也是最受歡迎的算法之一。它能夠把數據集X分成C個超橢球結構的聚類。HCM算法把傳統的聚類問題歸結為如下的非線性數學規划問題:
其中U=(uij)cxn為硬C-划分矩陣,V=(v1,v2,,,vc)為C個聚類中心,||·||代碼歐式距離。
HCM算法的具體流程如下:
初始化:指定聚類類別數C,2<=C<=n,n是數據個數,設定迭代停止閾值Ɛ,初始化聚類中心V0,設置迭代計數器b=0;
步驟一:根據下面的公式計算或更新划分矩陣U
步驟二:根據下面公式更新聚類中心V(b+1)
步驟三:如果||Vb – V(b+1)||< Ɛ,則算法停止並輸出划分矩陣和聚類中心V,否則令b=b+1,轉向執行步驟一
FCM聚類算法
Dunn按照RusPini定義的模糊划分的概念,把HCM算法擴展到模糊划分領域。Dunn對每個樣本與每個聚類中心的距離用其隸屬度平方加權,從而把類內誤差平方和目標函數J1擴展為類內加權誤差平方和函數J2:
Bezdek又將Dunn的目標函數推廣為更普遍的形式,給出了基於目標函數的模糊聚類更一般的描述。
其中,m∈[1,+∞)稱為加權指數,又稱作平滑參數。盡管從數學角度看,m的出現不自然,但如果不對隸屬度加權,從HCM算法到FCM算法的推廣將是無效的。
FCM算法的具體流程如下:
初始化:指定聚類類別數C,2<=C<=n,n是數據個數,設定迭代停止閾值Ɛ,初始化聚類中心V0,設置迭代計數器b=0;
步驟一:根據下面的公式計算或更新划分矩陣U
步驟二:根據下面公式更新聚類中心V(b+1)
步驟三:如果||Vb – V(b+1)||< Ɛ,則算法停止並輸出划分矩陣和聚類中心V,否則令b=b+1,轉向執行步驟一
FCM算法流程圖
FCM算法是目前比較流行的一種模糊聚類算法,究其原因大致有以下幾個方面:首先,模糊C—均值泛函Jm仍是傳統硬C一均值泛函J1的自然推廣;硬C一均值泛函J1是一個應用十分廣泛的聚類准則,對其在理論上的研究己經相當完善,這就為Jm的研究提供了良好的條件;數學上看,Jm與RS的希爾伯特空間結構(正交投影和均方逼近理論)有密切的關系,因此比其它泛函有更深厚的數學基礎;最后,也是最重要的是該目標函數不僅在許多領域獲得了非常成功的應用,而且以FCM算法為基礎,人們提出的基於其它原型的模糊聚類算法,形成了一大批FCM類型的算法:如模糊C一線(FCL)、模糊C一面(FCP)等聚類算法,分別實現了對呈線狀、超平面狀結構模式子集(或聚類)的檢測。
FCM算法應用到顏色遷移中
錢小燕等人將聚類算法應用到色彩遷移中,提出了一種基於圖像模糊顏色聚類的自適應色彩遷移算法。該算法首先將源圖像和目標圖像分別轉換到lαβ顏色空間:利用FCM 算法把源圖像和目標圖像划分為具有不同顏色特征的聚類,然后分析圖像中的顏色特征:分別算出每個域的匹配權值,對每個目標圖像的匹配權值,從源圖像中選取一個最接近域作為最佳匹配域;最后根據目標圖像各聚類域與源圖像中的匹配域之間的關系,引入隸屬度因子,兩個域的處理結果分別進行加權平均,獲得色彩遷移結果。使用FCM的思想對圖像進行聚類域划分的思路是:設准備處理圖像I的大小是S×H,即對顏色聚類顏色分析的個數是N,N = S×H,則圖像I可表示成集合,I={p1 ,p2 ...,pn }。圖像被分為c類,每個類的聚類中心為V={v1,v2 ...,vc },用uik表示像素pk隸屬於聚類中心Vi的隸屬度,定義圖像的隸屬度矩陣U。具體算法如下:
步驟一:把源圖像和目標圖像分別從RGB轉換到lαβ空間。
步驟二:確定待處理圖像聚類域個數c,然后初始化聚類中心。假設加權指數m=2,設定處理的最大迭代次數為50。
步驟三:當迭代次數T 小於50 時,根據初始化聚類中心計算隸屬度矩陣。如果pk≠vi,則對於所有的vi ( i=1,2,...,C ),利用下式計算隸屬度矩陣。
其中,i =1,2,...C; j =1,2,...N
如果,pk=vi,,k =1,2,...N則
其中,dik為第k個元素到第i 個聚類中心的距離,定義在lαβ下的歐式距離。
步驟四:對圖像聚類划分。圖像的隸屬度矩陣中,從每列選擇隸屬度最大的點作為相對應點的歸屬域,並重新計算聚類中心。
步驟五:對收斂情況進行檢查。若||Vi – V’i||<Σ,則立即停止迭代;否則一直迭代計算步驟三與步驟四。
步驟六:對聚類域進行匹配。使用FCM 后,對每一個聚類域分別設置一個匹配權值參數w,當目標圖像是灰度圖像時,w為聚類域的亮度均值;當目標圖像為彩色圖像時,w 是聚類域3 個通道標准差的加權平均值。
步驟七:色彩遷移。為了保持通用性,假定目標圖像中元素pi的歸屬域與源圖像中聚類域h 是匹配域,利用下式獲得各個通道的新值:
FCM算法效果圖
- BOOL TranFCM(LPBYTE lpDIBBits, LONG lmageWidth, LONG lmageHeight,LPBYTE lpDIBBits2, LONG lmageWidth2, LONG lmageHeight2,LPBYTE lpDIBBits3)
- {
- int classnum=2;
- int m=2;
- int i,j,k,nindex;
- double l,a,b;
- double* belong=new double[lmageWidth*lmageHeight*classnum];
- double* belong2=new double[lmageWidth2*lmageHeight2*classnum];
- double* center=new double[classnum*3];
- double* center2=new double[classnum*3];
- int* clustermap=new int[classnum];
- double suml,suma,sumb;
- FCMCluster(lpDIBBits,lmageWidth,lmageHeight,belong,center,classnum,m);
- FCMCluster(lpDIBBits2,lmageWidth2,lmageHeight2,belong2,center2,classnum,m);
- double* vl=new double[classnum];
- double* va=new double[classnum];
- double* vb=new double[classnum];
- double* vl2=new double[classnum];
- double* va2=new double[classnum];
- double* vb2=new double[classnum];
- for(i=0;i<classnum;i++)
- {
- BYTE distance=255;
- int map=-1;
- BYTE r,g,b,r2,g2,b2;
- for(j=0;j<classnum;j++)
- {
- LabToRgb(center[i*3+0],center[i*3+1],center[i*3+2],r,g,b);
- LabToRgb(center2[j*3+0],center2[j*3+1],center2[j*3+2],r2,g2,b2);
- BYTE dis=abs(RgbToGray(r,g,b)-RgbToGray(r2,g2,b2));
- if (distance>dis) {distance=dis;map=j;}
- }
- clustermap[i]=map;
- }
- //TranColor(belong,belong2,center,center2);
- //求各聚類域的標准差
- //求結果圖像的lab
- for(j = 0;j <lmageHeight; j++)
- {
- for(i = 0; i <lmageWidth; i++)
- {
- nindex=((lmageHeight-j-1)*lmageWidth+i);
- suml=suma=sumb=0;
- RgbToLab(lpDIBBits[nindex*3+2],lpDIBBits[nindex*3+1],lpDIBBits[nindex*3+0],l,a,b);
- for(k=0;k<classnum;k++)
- {
- suml += belong[lmageWidth*lmageHeight*k+nindex]*center2[clustermap[k]*3+0];
- suma += belong[lmageWidth*lmageHeight*k+nindex]*center2[clustermap[k]*3+1];
- sumb += belong[lmageWidth*lmageHeight*k+nindex]*center2[clustermap[k]*3+2];
- }
- LabToRgb(l,suma,sumb,lpDIBBits3[nindex*3+2],lpDIBBits3[nindex*3+1],lpDIBBits3[nindex*3+0]);
- }
- }
- return TRUE;
- }
- BOOL FCMCluster(LPBYTE lpDIBBits, LONG lmageWidth, LONG lmageHeight,double* belong,double* center,int classnum,int m)
- {
- int i,j,l,nindex;//循環控制變量
- int k=0;
- int LOOP=500;
- double* center2=new double[classnum*3];//聚類中心
- long x,y;//隨機確定聚類中心坐標
- long* num=new long[classnum];//每個類的像素個數
- double* lpImageLab = new double[lmageWidth*lmageHeight*3];
- double sumu,suml,suma,sumb;
- //初始化聚類中心
- for(i=0;i<classnum;i++)
- {
- x=rand()%lmageWidth;
- y=rand()%lmageHeight;
- nindex=((lmageHeight-y-1)*lmageWidth+x);
- RgbToLab(lpDIBBits[nindex*3+2],lpDIBBits[nindex*3+1],lpDIBBits[nindex*3+0],center[i*3+0],center[i*3+1],center[i*3+2]);
- for(j=0;j<i;j++)
- {
- double dis=DistanceLab(center[i*3+0],center[i*3+1],center[i*3+2],center[j*3+0],center[j*3+1],center[j*3+2]);
- if(dis<0.2) {i--;break;}//限值公式 暫取限值為1待優化 對初始化聚類中心的選擇非常關鍵
- }
- }
- //計算隸屬度矩陣、更新聚類中心、直至前后聚類中心距離小於限值e暫定0.1待優化
- while(k!=classnum && LOOP--)//限值公式
- {
- //計算隸屬度矩陣
- for(j = 0;j <lmageHeight; j++)
- {
- for(i = 0; i <lmageWidth; i++)
- {
- nindex=((lmageHeight-j-1)*lmageWidth+i);
- RgbToLab(lpDIBBits[nindex*3+2],lpDIBBits[nindex*3+1],lpDIBBits[nindex*3+0],
- lpImageLab[nindex*3+0],lpImageLab[nindex*3+1],lpImageLab[nindex*3+2]);
- //means_Assign();
- double blg=-1;//隸屬度
- for(k=0;k<classnum;k++)
- {
- sumu=0;
- double dis1=DistanceLab(lpImageLab[nindex*3+0],lpImageLab[nindex*3+1],lpImageLab[nindex*3+2],center[k*3+0],center[k*3+1],center[k*3+2]);
- if (dis1==0) {belong[lmageWidth*lmageHeight*k+nindex]=1;continue;}
- for(l=0;l<classnum;l++)
- {
- double dis2=DistanceLab(lpImageLab[nindex*3+0],lpImageLab[nindex*3+1],lpImageLab[nindex*3+2],center[l*3+0],center[l*3+1],center[l*3+2]);
- if (dis2==0) break;
- sumu+=pow((dis1*dis1)/(dis2*dis2),1.0/(m-1));
- }
- if (l!=classnum) {belong[lmageWidth*lmageHeight*k+nindex]=0;continue;}
- belong[lmageWidth*lmageHeight*k+nindex]=1/sumu;
- }
- }
- }
- //更新聚類中心
- for(k=0;k<classnum;k++)
- {
- suml=suma=sumb=sumu=0;
- for(j = 0;j <lmageHeight; j++)
- {
- for(i = 0; i <lmageWidth; i++)
- {
- nindex=((lmageHeight-j-1)*lmageWidth+i);
- suml+=pow(belong[lmageWidth*lmageHeight*k+nindex],m)*lpImageLab[nindex*3+0];
- suma+=pow(belong[lmageWidth*lmageHeight*k+nindex],m)*lpImageLab[nindex*3+1];
- sumb+=pow(belong[lmageWidth*lmageHeight*k+nindex],m)*lpImageLab[nindex*3+2];
- sumu+=pow(belong[lmageWidth*lmageHeight*k+nindex],m);
- }
- }
- center2[k*3+0]=suml/sumu;
- center2[k*3+1]=suma/sumu;
- center2[k*3+2]=sumb/sumu;
- }
- //判斷循環終止條件
- for(k=0;k<classnum;k++)
- {
- if(DistanceLab(center[k*3+0],center[k*3+1],center[k*3+2],center2[k*3+0],center2[k*3+1],center2[k*3+2])>0.1) break;//限值e暫定0.1待優化
- }
- for(i=0;i<classnum*3;i++)
- {
- center[i]=center2[i];
- }
- }
- return TRUE;
- }
- double DistanceLab(double l1,double a1,double b1,double l2,double a2,double b2)
- {
- double lx=l1-l2;
- double ax=a1-a2;
- double bx=b1-b2;
- if (lx<0) lx=-lx;
- if (ax<0) ax=-ax;
- if (bx<0) bx=-bx;
- return lx+ax+bx;
- }
代碼鏈接