我正在尝试使用k-means聚类算法对给定k值的图像进行分割。
我想将距离计算从欧几里德改为马哈拉诺比斯距离但我无法将公式实现到现有代码,因为它具有三维数组。
首先我将RGB图像转换为HSL空间。然后我在距离计算后标记像素。在最后一步中,我将HSL图像转换回RGB空间。
nC = uint8(input('Enter cluster number: '));
iRGB = double(imread('Bird.png'));
tic
iHSL = rgb2hsl(iRGB/255);
[ro co bd ] = size(iHSL);
% Randomly assign cluster positions
Cs = [randi(ro, nC,1) randi(co, nC,1)];
%create array for labels
Ls = zeros(ro, co);
%create another array for comparison of labels
prev_Ls = ones(ro, co);
distances = zeros( 1, nC );
kcenter = zeros(nC, 3);
for k=1:nC
kcenter(k,:) = iHSL(kcenter(k),kcenter(k,2),:);
end
while (true)
prev_Ls = Ls;
for r = 1:ro
for c = 1:co
for k = 1:nC
distances(k) = sqrt(((iHSL(r,c,1) - kcenter(k,1))^2 +...
(iHSL(r,c,2) - kcenter(k,2))^2 +...
(iHSL(r,c,3) - kcenter(k,3))^2));
end
d = find(distances(:) == min(distances));
Ls(r,c) = d(1);
end
end
H = zeros(1,nC);
S = zeros(1,nC);
L = zeros(1,nC);
cnt = zeros(1,nC);
for r = 1:ro
for c = 1:co
H( Ls(r,c) ) = H( Ls(r,c) ) + iHSL(r,c,1);
S( Ls(r,c) ) = S( Ls(r,c) ) + iHSL(r,c,2);
L( Ls(r,c) ) = L( Ls(r,c) ) + iHSL(r,c,3);
cnt( Ls(r,c) ) = cnt( Ls(r,c) ) + 1;
end
end
for k = 1:nC
kcenter(k,1) = H(k) / cnt(k);
kcenter(k,2) = S(k) / cnt(k);
kcenter(k,3) = L(k) / cnt(k);
end
%if prev_labels are equal to current labels break while loop.
if isequal(prev_Ls, Ls)
break;
end
end
for r = 1:ro
for c = 1:co
iHSL(r,c,1) = kcenter(Ls(r,c), 1);
iHSL(r,c,2) = kcenter(Ls(r,c), 2);
iHSL(r,c,3) = kcenter(Ls(r,c), 3);
end
end
result_img = hsl2rgb(iHSL)*255;
toc
figure(1);
subplot(1,2,1);
imshow(uint8(iRGB));
subplot(1,2,2);
imshow(uint8(result_img));
我想用mahalanobis距离计算公式更改此公式。我试过mahal(iHSL(r,c,1),kcenter(k,1))
我得到Nan
结果。
Internet上的所有示例都是针对二维数组的。但我有三维。
我试图改变这一行;
distances(k) = sqrt((iHSL(r,c,1) - kcenter(k,1))^2 +...
(iHSL(r,c,2) - kcenter(k,2))^2 +...
(iHSL(r,c,3) - kcenter(k,3))^2);
到
distances(k) = mahal(kcenter(k,:), iHSL(:,:,1)) + ...
mahal(kcenter(k,:), iHSL(:,:,2)) + ...
mahal(kcenter(k,:), iHSL(:,:,3));
但它给我一个错误说:
使用mahal时出错(第34行)要求输入具有相同的列数。
我不知道如何为我的3d数组制定马哈拉诺比斯距离计算。