Matlab 中的高效分类 [英] Speed-efficient classification in Matlab

查看:30
本文介绍了Matlab 中的高效分类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have an image of size as RGB uint8(576,720,3) where I want to classify each pixel to a set of colors. I have transformed using rgb2lab from RGB to LAB space, and then removed the L layer so it is now a double(576,720,2) consisting of AB.

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

Now, I want to classify this to some colors that I have trained on another image, and calculated their respective AB-representations as:

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,我目前执行以下操作(伪代码):

Now, in order to classify/label each pixel to a cluster 1-7, I currently do the following (pseudo-code):

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 秒).

However, this is terribly slow (52 seconds) because of the image resolution and that I manually loop through each x and y.

是否有一些我可以使用的内置函数来执行相同的工作?必须有.

Are there some built-in functions I can use that performs the same job? There must be.

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

推荐答案

方法 #1

对于 N x 2 大小的点/像素数组,您可以按照 Luis 的其他解决方案,它可能会稍微减慢速度,有一种 permute-unrolled" 版本,也让我们 bsxfun 致力于 2D 数组而不是 3D 数组,后者必须具有更好的性能.

Approach #1

For a N x 2 sized points/pixels array, you can avoid permute as suggested in the other solution by Luis, which could slow down things a bit, to have a kind of "permute-unrolled" version of it and also let's bsxfun work towards a 2D array instead of a 3D array, which must be better with performance.

因此,假设将簇排序为 N x 2 大小的数组,您可以尝试其他基于 bsxfun 的方法 -

Thus, assuming clusters to be ordered as a N x 2 sized array, you may try this other bsxfun based approach -

%// 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),[]);

<小时>

方法#2

您可以尝试另一种利用MATLAB 中的快速矩阵乘法,基于这个智能解决方案 -

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

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

让我们考虑两个矩阵 AB 我们要计算它们之间的距离矩阵.为了接下来更容易解释,让我们将 A 视为 3 x 2,将 B 视为 4 x 2 大小的数组,从而表明我们正在处理 XY 点.如果我们有 A 作为 N x 3B 作为 M x 3 大小的数组,那么它们将是 XYZ 点.

What’s going on with the matrix multiplication based distance matrix calculation?

Let us consider two matrices A and B between whom we want to calculate the distance matrix. For the sake of an easier explanation that follows next, let us consider A as 3 x 2 and B as 4 x 2 sized arrays, thus indicating that we are working with X-Y points. If we had A as N x 3 and B as M x 3 sized arrays, then those would be X-Y-Z points.

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

Now, if we have to manually calculate the first element of the square of distance matrix, it would look like this –

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_extB_ext 的输出,它们将如下所示——

Now, according to our proposed matrix multiplication, if you check the output of A_ext and B_ext after the loop in the earlier code ends, they would look like the following –

因此,如果您在 A_extB_ext 的转置之间执行矩阵乘法,则乘积的第一个元素将是 A_ext 的第一行之间元素乘法的总和code>A_ext 和 B_ext,即它们的总和 –

So, if you perform matrix multiplication between A_ext and transpose of B_ext, the first element of the product would be the sum of elementwise multiplication between the first rows of A_ext and B_ext, i.e. sum of these –

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

The result would be identical to the result obtained from Equation (1) earlier. This would continue for all the elements of A against all the elements of B that are in the same column as in A. Thus, we would end up with the complete squared distance matrix. That’s all there is!!

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

Vectorized variations of the matrix multiplication based distance matrix calculations are possible, though there weren't any big performance improvements seen with them. Two such variations are listed next.

变体#1

[nA,dim] = size(A);
nB = size(B,1);

A_ext = ones(nA,dim*3);
A_ext(:,2:3:end) = -2*A;
A_ext(:,3:3:end) = A.^2;

B_ext = ones(nB,dim*3);
B_ext(:,1:3:end) = B.^2;
B_ext(:,2:3:end) = B;

distmat = A_ext * B_ext.';

变体#2

[nA,dim] = size(A);
nB = size(B,1);

A_ext = [ones(nA*dim,1) -2*A(:) A(:).^2];
B_ext = [B(:).^2 B(:) ones(nB*dim,1)];

A_ext = reshape(permute(reshape(A_ext,nA,dim,[]),[1 3 2]),nA,[]);
B_ext = reshape(permute(reshape(B_ext,nB,dim,[]),[1 3 2]),nB,[]);

distmat = A_ext * B_ext.';

因此,这些也可以被视为实验版本.

So, these could be considered as experimental versions too.

这篇关于Matlab 中的高效分类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆