一個朋友讓幫忙做圖像分類,用FCM聚類算法,網上查了一下,FCM基本都是對一幅圖像進行像素的分類,跟他說的任務不太一樣,所要做的是將一個文件夾里的一千多幅圖像進行分類。圖像大概是這個樣子的(是25*25的小圖像):

自己寫太麻煩,我花了些時間在GitHub上找了FCM的算法,有一個比較合適的算法,鏈接如下:https://github.com/HosseinAbedi/FCM ,這個代碼本來是用FCM處理鳶尾花分類的,輸入是鳶尾花的四個特征,輸出是三個預測類別。因為圖像就是矩陣,矩陣也是多維向量,每一個像素值可以看做一個特征,那么完全可以把圖像的所有像素當作特征值輸入到程序中,而且他給的數據集里的圖像是25*25的小圖像而且是灰度圖像。因此,我把圖像文件夾里的圖像轉成了大矩陣,每一行代表一張圖像。本身的鳶尾花數據是存為一個iris.mat的,是一個150*5的double矩陣,運行程序的時候先加載這個mat。我也依樣畫葫蘆,將圖像存為了一個1330*25的double矩陣,代碼如下:
clear all;
clc;
pt = '.\training2\';
ext = '*.bmp';
dis = dir([pt ext]);
nms = {dis.name};
Images=[];
for k = 1:length(nms)
nm = [pt nms{k}];
A = imread(nm);
B = reshape(double(A.'),1,25);
Images=[Images;B];
% 對圖像image進行相關操作
end
save Data.mat Images;
然后就可以直接調用主FCM程序了。除了輸入輸出,其他基本沒變。直接把原來的輸出結果prediction向量改為輸出三個分類,原來的向量是第一個圖像是第幾類,第二個圖像是第幾類這樣的。改了之后是第一類有哪些圖像,第二類有哪些圖像等等。后來他說要分成20類,基本是一樣的,寫的比較簡單,直接用向量來保存每一個類。代碼如下:
number=1300; %圖像的數量
%把分類存到下面的向量中,向量中的每個值代表第幾幅圖像,3代表‘m3.bmp’.
a=[];b=[];c=[];d=[];e=[];f=[];g=[];h=[];i=[];j=[];
k=[];l=[];m=[];n=[];o=[];p=[];q=[];r=[];s=[];t=[];
for x = 1:number
switch(prediction(x))
case 1
a=[a,x];
case 2
b=[b,x];
case 3
c=[c,x];
case 4
d=[d,x];
case 5
e=[e,x];
case 6
f=[f,x];
case 7
g=[g,x];
case 8
h=[h,x];
case 9
i=[i,x];
case 10
j=[j,x];
case 11
k=[k,x];
case 12
l=[l,x];
case 13
m=[m,x];
case 14
n=[n,x];
case 15
o=[o,x];
case 16
p=[p,x];
case 17
q=[q,x];
case 18
r=[r,x];
case 19
s=[s,x];
case 20
t=[t,x];
end
end
save .\result\A.mat a;save .\result\B.mat b;save .\result\C.mat c;save .\result\D.mat d;
save .\result\E.mat e;save .\result\F.mat f;save .\result\G.mat g;save .\result\H.mat h;
save .\result\I.mat i;save .\result\J.mat j;save .\result\K.mat k;save .\result\L.mat l;
save .\result\M.mat m;save .\result\N.mat n;save .\result\O.mat o;save .\result\P.mat p;
save .\result\Q.mat q;save .\result\R.mat r;save .\result\S.mat s;save .\result\T.mat t;
分類最后的結果是這個樣子的:

哦,中途還出了一個問題,錯誤提示是:fcm輸入的參數太多,想了很久才想通,原來matlab有個自帶的fcm函數,它的參數只有兩個,難怪會提示輸入的參數太多。把主函數fcm的文件名改為myfcm就可以了。
后來感覺還是有點不對,她說存成mat矩陣不好調用,還是直接把原來的數據集分類之后用文件保存起來,一個文件代表一個分類結果比較好,然后我直接把原圖像文件夾的文件分成了20個子文件夾結果。其實還挺麻煩的,要先把源文件夾的圖片讀取出來,然后看看屬於哪一類,再分到新的結果文件夾中。代碼如下:
number=1300; %圖像的數量
for x = 1:number
switch(prediction(x))
case 1
filename=strcat('.\training2\','m',num2str(x),'.bmp');
A=imread(filename); %讀取第一類的圖片
mkdir('result2\image1');
newfile=strcat('.\result2\image1\m',num2str(x),'.bmp');
imwrite(A,newfile); %將第一類圖片保存到result2中
case 2
filename=strcat('.\training2\','m',num2str(x),'.bmp');
A=imread(filename);
mkdir('result2\image2');
newfile=strcat('.\result2\image2\m',num2str(x),'.bmp');
imwrite(A,newfile);
case 3
filename=strcat('.\training2\','m',num2str(x),'.bmp');
A=imread(filename);
mkdir('result2\image3');
newfile=strcat('.\result2\image3\m',num2str(x),'.bmp');
imwrite(A,newfile);
case 4
filename=strcat('.\training2\','m',num2str(x),'.bmp');
A=imread(filename);
mkdir('result2\image4');
newfile=strcat('.\result2\image4\m',num2str(x),'.bmp');
imwrite(A,newfile);
case 5
filename=strcat('.\training2\','m',num2str(x),'.bmp');
A=imread(filename);
mkdir('result2\image5');
newfile=strcat('.\result2\image5\m',num2str(x),'.bmp');
imwrite(A,newfile);
case 6
filename=strcat('.\training2\','m',num2str(x),'.bmp');
A=imread(filename);
mkdir('result2\image6');
newfile=strcat('.\result2\image6\m',num2str(x),'.bmp');
imwrite(A,newfile);
case 7
filename=strcat('.\training2\','m',num2str(x),'.bmp');
A=imread(filename);
mkdir('result2\image7');
newfile=strcat('.\result2\image7\m',num2str(x),'.bmp');
imwrite(A,newfile);
case 8
filename=strcat('.\training2\','m',num2str(x),'.bmp');
A=imread(filename);
mkdir('result2\image8');
newfile=strcat('.\result2\image8\m',num2str(x),'.bmp');
imwrite(A,newfile);
case 9
filename=strcat('.\training2\','m',num2str(x),'.bmp');
A=imread(filename);
mkdir('result2\image9');
newfile=strcat('.\result2\image9\m',num2str(x),'.bmp');
imwrite(A,newfile);
case 10
filename=strcat('.\training2\','m',num2str(x),'.bmp');
A=imread(filename);
mkdir('result2\image10');
newfile=strcat('.\result2\image10\m',num2str(x),'.bmp');
imwrite(A,newfile);
case 11
filename=strcat('.\training2\','m',num2str(x),'.bmp');
A=imread(filename);
mkdir('result2\image11');
newfile=strcat('.\result2\image11\m',num2str(x),'.bmp');
imwrite(A,newfile);
case 12
filename=strcat('.\training2\','m',num2str(x),'.bmp');
A=imread(filename);
mkdir('result2\image12');
newfile=strcat('.\result2\image12\m',num2str(x),'.bmp');
imwrite(A,newfile);
case 13
filename=strcat('.\training2\','m',num2str(x),'.bmp');
A=imread(filename);
mkdir('result2\image13');
newfile=strcat('.\result2\image13\m',num2str(x),'.bmp');
imwrite(A,newfile);
case 14
filename=strcat('.\training2\','m',num2str(x),'.bmp');
A=imread(filename);
mkdir('result2\image14');
newfile=strcat('.\result2\image14\m',num2str(x),'.bmp');
imwrite(A,newfile);
case 15
filename=strcat('.\training2\','m',num2str(x),'.bmp');
A=imread(filename);
mkdir('result2\image15');
newfile=strcat('.\result2\image15\m',num2str(x),'.bmp');
imwrite(A,newfile);
case 16
filename=strcat('.\training2\','m',num2str(x),'.bmp');
A=imread(filename);
mkdir('result2\image16');
newfile=strcat('.\result2\image16\m',num2str(x),'.bmp');
imwrite(A,newfile);
case 17
filename=strcat('.\training2\','m',num2str(x),'.bmp');
A=imread(filename);
mkdir('result2\image17');
newfile=strcat('.\result2\image17\m',num2str(x),'.bmp');
imwrite(A,newfile);
case 18
filename=strcat('.\training2\','m',num2str(x),'.bmp');
A=imread(filename);
mkdir('result2\image18');
newfile=strcat('.\result2\image18\m',num2str(x),'.bmp');
imwrite(A,newfile);
case 19
filename=strcat('.\training2\','m',num2str(x),'.bmp');
A=imread(filename);
mkdir('result2\image19');
newfile=strcat('.\result2\image19\m',num2str(x),'.bmp');
imwrite(A,newfile);
case 20
filename=strcat('.\training2\','m',num2str(x),'.bmp');
A=imread(filename);
mkdir('result2\image20');
newfile=strcat('.\result2\image20\m',num2str(x),'.bmp');
imwrite(A,newfile);
end
end
最后的結果基本達到要求了,完整的敘述一下這個任務就是:把一個文件夾里的圖像數據(25*25)用FCM聚類算法進行分類,然后分類的結果保存到新的子文件夾中,每一個文件夾存儲一類結果。最后的結果如下:

