Matlab中的速度高效分类 [英] Speed-efficient classification in 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
但是,由于图像分辨率的原因,这太慢了(52秒),而且我手动遍历了每个x和y.
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
a>可能会稍微放慢速度,使其具有某种"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
您可以尝试使用
Approach #2
You can try out another approach that leverages fast matrix multiplication in MATLAB
and is based on this smart solution -
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
,我们要在这两个矩阵之间计算距离矩阵.为了便于接下来的解释,让我们将A
视为3 x 2
,将B
视为4 x 2
大小的数组,从而表明我们正在处理X-Y点.如果我们将A
作为N x 3
,将B
作为M x 3
大小的数组,则这些将是X-Y-Z
点.
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_ext
和B_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_ext
和B_ext
的转置之间执行矩阵乘法,则乘积的第一个元素将是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
的所有元素,对于A
的同一列中的所有B
元素,此操作将继续进行.因此,我们将得出完整的平方距离矩阵.就是所有了!
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屋!