velocidad ruta revoluciones para optima gasolina estandar eficiente diesel cuantas conduccion como combustible carro automatico ahorro ahorrar ahorra performance matlab machine-learning classification data-mining

performance - ruta - conduccion eficiente ahorro combustible



Clasificación de velocidad eficiente en Matlab (2)

Tengo una imagen de tamaño como RGB uint8(576,720,3) donde quiero clasificar cada píxel a un conjunto de colores. Me he transformado utilizando rgb2lab de RGB a LAB espacio, y luego rgb2lab la capa L por lo que ahora es un double(576,720,2) consiste en AB.

Ahora, quiero clasificar esto a algunos colores que he entrenado en otra imagen, y calculé sus respectivas representaciones AB como:

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

Ahora, para clasificar / etiquetar cada píxel a un clúster 1-7, actualmente hago lo siguiente (pseudocódigo):

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

Sin embargo, esto es terriblemente lento (52 segundos) a causa de la resolución de la imagen y de que paso manualmente cada x e y.

¿Hay algunas funciones integradas que pueda usar que realicen el mismo trabajo? Debe haber.

Para resumir: necesito un método de clasificación que clasifique imágenes de píxeles en un conjunto de conglomerados ya definidos.


Use pdist2 (Statistics Toolbox) para calcular las distancias de forma vectorializada:

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

Si no tiene Statistics Toolbox, puede reemplazar la tercera línea por

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

Esto da una distancia cuadrada en lugar de distancia, pero con el propósito de minimizarla no importa.


Enfoque # 1

Para una matriz de puntos / píxeles de tamaño N x 2 , puede evitar el permute como sugiere la otra solución de Luis , lo que podría ralentizar un poco las cosas, tener una especie de "permute-unrolled" y también trabajar con bsxfun hacia una matriz 2D lugar de una matriz 3D , que debe ser mejor con el rendimiento.

Por lo tanto, suponiendo que los clústeres se ordenan como una matriz de tamaño N x 2 , puede probar este otro bsxfun basado en bsxfun :

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

Enfoque # 2

Puede probar otro enfoque que aproveche fast matrix multiplication in MATLAB y se base en esta solución inteligente :

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

¿Qué está pasando con el cálculo de la matriz de distancia basada en la multiplicación de matrices?

Consideremos dos matrices A y B entre las cuales queremos calcular la matriz de distancia. En aras de una explicación más sencilla que sigue a continuación, consideremos A como 3 x 2 y B como matrices de 4 x 2 , lo que indica que estamos trabajando con puntos XY. Si tuviéramos A como N x 3 y B como matrices de tamaño M x 3 , esos serían puntos XYZ .

Ahora, si tenemos que calcular manualmente el primer elemento de la matriz del cuadrado de distancia, se vería así:

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

cuál podría ser -

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)

Ahora, de acuerdo con nuestra multiplicación de matrices propuesta, si usted verifica la salida de A_ext y B_ext después de que B_ext el ciclo en el código anterior, se verían como los siguientes:

Por lo tanto, si realiza la multiplicación de la matriz entre A_ext y la transposición de B_ext , el primer elemento del producto sería la suma de la multiplicación por elementos entre las primeras filas de A_ext y B_ext , es decir, la suma de estos:

El resultado sería idéntico al resultado obtenido de la Equation (1) anterior. Esto continuaría para todos los elementos de A contra todos los elementos de B que están en la misma columna que en A Por lo tanto, terminaríamos con la matriz de distancia cuadrada completa. ¡¡Eso es todo lo que hay!!

Variaciones vectorizadas

Las variaciones vectorizadas de los cálculos de la matriz de distancia basada en la multiplicación de la matriz son posibles, aunque no se observaron grandes mejoras de rendimiento con ellas. Dos de estas variaciones se enumeran a continuación.

Variación n. ° 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.'';

Variación # 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.'';

Por lo tanto, estas podrían considerarse como versiones experimentales también.