Matlab中的速度有效分类

时间:2014-11-18 12:25:53

标签: performance matlab machine-learning classification data-mining

我有一个大小为RGB uint8(576,720,3)的图像,我想将每个像素分类为一组颜色。我已经使用rgb2lab从RGB转换为LAB空间,然后删除了L层,因此它现在是由{AB}组成的double(576,720,2)

现在,我想将此分类为我在另一张图像上训练过的一些颜色,并将它们各自的AB表示计算为:

Cluster 1: -17.7903  -13.1170
Cluster 2: -30.1957   40.3520
Cluster 3:  -4.4608   47.2543
Cluster 4:  46.3738   36.5225
Cluster 5:  43.3134  -17.6443
Cluster 6:  -0.9003    1.4042
Cluster 7:   7.3884   11.5584

现在,为了将每个像素分类/标记为1-7簇,我现在执行以下操作(伪代码):

clusters;
for each x
  for each y
    ab = im(x,y,2:3);
    dist = norm(ab - clusters); // norm of dist between ab and each cluster
    [~, idx] = min(dist);
  end
end

然而,由于图像分辨率和我手动遍历每个x和y,这非常慢(52秒)。

我可以使用哪些内置函数执行相同的工作?必须有。

总结:我需要一种分类方法,将像素图像分类为已定义的一组聚类。

2 个答案:

答案 0 :(得分:11)

方法#1

对于N x 2大小的点/像素数组,您可以避免other solution by Luis中建议的permute,这可能会使某些事情变慢,有{{1}它的版本以及让"permute-unrolled"bsxfun数组而不是2D数组工作,这对于性能必须更好。

因此,假设要将集群排序为3D大小的数组,您可以尝试使用其他基于N x 2的方法 -

bsxfun

方法#2

您可以尝试另一种利用fast matrix multiplication in MATLAB并基于this smart solution的方法 -

%// Get a's and b's
im_a = im(:,:,2);
im_b = im(:,:,3);

%// Get the minimum indices that correspond to the cluster IDs
[~,idx]  = min(bsxfun(@minus,im_a(:),clusters(:,1).').^2 + ...
    bsxfun(@minus,im_b(:),clusters(:,2).').^2,[],2);
idx = reshape(idx,size(im,1),[]);

基于矩阵乘法的距离矩阵计算是怎么回事?

让我们考虑两个矩阵d = 2; %// dimension of the problem size im23 = reshape(im(:,:,2:3),[],2); numA = size(im23,1); numB = size(clusters,1); A_ext = zeros(numA,3*d); B_ext = zeros(numB,3*d); for id = 1:d A_ext(:,3*id-2:3*id) = [ones(numA,1), -2*im23(:,id), im23(:,id).^2 ]; B_ext(:,3*id-2:3*id) = [clusters(:,id).^2 , clusters(:,id), ones(numB,1)]; end [~, idx] = min(A_ext * B_ext',[],2); %//' idx = reshape(idx, size(im,1),[]); %// Desired IDs A我们想要计算距离矩阵。为了便于下面的简单解释,我们将B视为A3 x 2作为B大小的数组,从而表明我们正在使用X-Y点。如果我们将4 x 2作为AN x 3作为B大小的数组,则那些将是M x 3个点。

现在,如果我们必须手动计算距离矩阵的平方的第一个元素,它将看起来像这样 -

X-Y-Z

将是 -

first_element = ( A(1,1) – B(1,1) )^2 + ( A(1,2) – B(1,2) )^2         

现在,根据我们提出的矩阵乘法,如果在早期代码中的循环结束后检查first_element = A(1,1)^2 + B(1,1)^2 -2*A(1,1)* B(1,1) + ... A(1,2)^2 + B(1,2)^2 -2*A(1,2)* B(1,2) … Equation (1) A_ext的输出,它们将如下所示 -

enter image description here

enter image description here

因此,如果在B_extA_ext的转置之间执行矩阵乘法,则乘积的第一个元素将是B_ext和{的第一行之间的元素乘法的总和。 {1}},即这些的总和 -

enter image description here

结果与先前从A_ext获得的结果相同。 B_ext的所有元素都会针对Equation (1)中与A位于同一列中的所有元素继续这样做。因此,我们最终会得到完整的平方距离矩阵。这就是全部!!

矢量化变体

基于矩阵乘法的距离矩阵计算的矢量化变体是可能的,尽管它们没有看到任何大的性能改进。接下来列出了两个这样的变化。

变体#1

B

变体#2

A

所以,这些也可以被视为实验版本。

答案 1 :(得分:4)

使用pdist2(统计工具箱)以矢量化方式计算距离:

ab = im(:,:,2:3);                              % // get A, B components
ab = reshape(ab, [size(im,1)*size(im,2) 2]);   % // reshape into 2-column
dist = pdist2(clusters, ab);                   % // compute distances
[~, idx] = min(dist);                          % // find minimizer for each pixel
idx = reshape(idx, size(im,1), size(im,2));    % // reshape result

如果您没有统计工具箱,则可以用

替换第三行
dist = squeeze(sum(bsxfun(@minus, clusters, permute(ab, [3 2 1])).^2, 2));

这给出了平方距离而不是距离,但是为了最小化它并不重要。