在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
。令 M
xN
表示原始图像中的像素数。因此原始图像是一个 M
xN
x3
数组。
result_index
是一个 M
xN
数组,每个原始像素包含最接近参考颜色的索引。
result
是一个 M
xN
x3
数组,其中每个像素都被分配了最接近参考颜色的 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));
我想根据像素的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
。令 M
xN
表示原始图像中的像素数。因此原始图像是一个 M
xN
x3
数组。
result_index
是一个 M
xN
数组,每个原始像素包含最接近参考颜色的索引。
result
是一个 M
xN
x3
数组,其中每个像素都被分配了最接近参考颜色的 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));