在matlab中计算到三个定义像素的像素距离

Calculate the pixel distance to three defined pixel in matlab

我想根据像素的RGB颜色对一张tiff图像的像素进行分类。输入是一张图像和水 (r0,g0,b0)、森林 (r1,g1,b1) 和建筑物 (r2,g2,c2) 的三种预定义颜色。分类基于图像像素与这三种颜色之间的距离。如果像素最靠近水,则该像素为水并将其更改为水 RGB。距离计算为(一个样本)sqrt((x-r0)^2+(y-g0)^2+(z0-b0)^2)

示例实现是:

a=imread(..);
[row col dim] = size(a);   % dim =3 
for i=1:row
   for j=1:col
       dis1=sqrtCal(a(i,j,:)-water) 
       dis2=sqrtCal(a(i,j,:)-forest) 
       dis3=sqrtCal(a(i,j,:)-build)
       a(i,j,:) = water;
       if  dis2< dis1
           dis1 = dis2
           a(i,j,:) = forest
       end
       dis3=sqrt(a(i,j,:)-build)
       if dis3<dis1
          a(i,j,:) = build
       end
   end
end

此实现应该有效。问题是两个for循环不是一个好的选择。

那么Matlab有什么好的替代品吗?这 D = pdist(X,distance) 似乎不适用于我的情况。

我想这就是你想要的。参考颜色的数量是任意的(在您的示例中为 3)。每个参考颜色被定义为矩阵的一行ref_colors。令 MxN 表示原始图像中的像素数。因此原始图像是一个 MxNx3 数组。

result_index 是一个 MxN 数组,每个原始像素包含最接近参考颜色的索引。

result 是一个 MxNx3 数组,其中每个像素都被分配了最接近参考颜色的 RBG 值。

im = rand(10,12,3);          %// example image
ref_colors = [ .1 .1 .8; ... %// water
               .3 .9 .2; ... %// forest
               .6 .6 .6 ];   %// build: example reference colors
dist = sum(bsxfun(@minus, im, permute(ref_colors, [3 4 2 1])).^2, 3);
    %// 4D array containing the distance from each pixel to each reference color.
    %// Dimensions are: 1st: pixel row, 2nd: pixel col, 3rd: not used,
    %// 4th: index of reference color
[~, result_index] = min(dist, [], 4); %// compute arg min along 4th dimension
result = reshape(ref_colors(result_index,:), size(im,1), size(im,2), 3);

这是另一个基于 bsxfun 的解决方案,但仍保留在 3D 中并且可能更有效 -

%// Concatenate water, forest, build as a 2D array for easy processing
wfb = cat(2,water(:),forest(:),build(:))

%// Calculate square root of squared distances & indices corresponding to min vals
[~,idx] = min(sum(bsxfun(@minus,reshape(a,[],3),permute(wfb,[3 1 2])).^2,2),[],3)

%// Get the output with the minimum from the set of water, forest & build
a_out = reshape(wfb(:,idx).',size(a))

如果您安装了统计工具箱,则可以使用基于 knnsearch 的此版本,该版本适用于大量颜色。

result_index = knnsearch(ref_colors, reshape(im,[],3));
result = reshape(ref_colors(result_index,:), size(im));