matlab - Calculate Euclidean distance between RGB vectors in a large matrix -



matlab - Calculate Euclidean distance between RGB vectors in a large matrix -

i have rgb matrix of set of different pixels. (n pixels => n rows, rgb => 3 columns). have calculate minimum rgb distance between 2 pixels matrix. tried loop approach, because set big (let's n=24000), looks take forever programme finish. there approach? read pdist, rgb euclidean distance cannot used it.

k=1; = 1:n j = 1:n if (i~=j) dist_vect(k)=rgb_dist(u(i,1),u(j,1),u(i,2),u(j,2),u(i,3),u(j,3)) k=k+1; end end end

euclidean distance between 2 pixels: so, pdist syntax this: d=pdist2(u,u,@calc_distance());, u obtained this:

rgbimage = imread('peppers.png'); rgb_columns = reshape(rgbimage, [], 3) [u, m, n] = unique(rgb_columns, 'rows','stable');

but if pdist2 loops itself, how should come in parameters function?

function[distance]=rgb_dist(r1, r2, g1, g2, b1, b2),

where r1,g1,b1,r2,g2,b2 components of each pixel.

i made new function this:

function[distance]=rgb_dist(x,y) distance=sqrt(sum(((x-y)*[3;4;2]).^2,2)); end

and called d=pdist(u,u,@rgb_dist); , got 'error using pdist (line 132) 'distance' argument must string or function.'

testing rgb_dist new function alone, these input set

x=[62,29,64; 63,31,62; 65,29,60; 63,29,62; 63,31,62;]; d=rgb_dist(x,x); disp(d);

outputs values of 0.

contrary post says, can utilize euclidean distance part of pdist. have specify flag when phone call pdist.

the loop have described above can computed by:

dist_vect = pdist(u, 'euclidean');

this should compute l2 norm between each unique pair of rows. seeing matrix has rgb pixel per row, , each column represents single channel, pdist should totally fine application.

if want display distance matrix, row i , column j corresponds distance between pixel in row i , row j of matrix u, can utilize squareform.

dist_matrix = squareform(dist_vect);

as additional bonus, if want find 2 pixels in matrix share smallest distance, can find search on lower triangular half of dist_matrix. diagonals of dist_matrix going zero vector distance should 0. in addition, matrix symmetric , upper triangular half should equal lower triangular half. therefore, can set diagonal , upper triangular half inf, search minimum elements remaining. in other words:

indices_to_set = true(size(dist_matrix)); indices_to_set = triu(indices_to_set); dist_matrix(indices_to_set) = inf; [v1,v2] = find(dist_matrix == min(dist_matrix(:)), 1);

v1 , v2 contain rows of u rgb pixels contained smallest euclidean distance. note specify sec parameter 1 want find 1 match, post has stated requirement. if wish find all vectors match same distance, remove sec parameter 1.

edit - june 25th, 2014

seeing how want weight each component of euclidean distance, can define own custom function calculate distances between 2 rgb pixels. such, instead of specifying euclidean, can specify your own function can calculate distances between 2 vectors within matrix calling pdist so:

pdist(x, @(xi,xj) ...);

@(xi,xj)... anonymous function takes in vector xi , matrix xj. pdist need create sure custom distance function takes in xi 1 x n vector single row of pixels. xj m x n matrix contains multiple rows of pixels. such, function needs homecoming m x 1 vector of distances. therefore, can accomplish weighted euclidean distance so:

weights = [3;4;2]; weuc = @(xi, xj, w) sqrt(bsxfun(@minus, xi, xj).^2 * w); dist_matrix = pdist(double(u), @(xi, xj) weuc(xi, xj, weights));

bsxfun can handle nicely replicate xi many rows need to, , should compute single vector every single element in xj subtracting. square each of differences, weight weights, take square root , sum. note didn't utilize sum(x,2), used vector algebra compute sum. if recall, computing dot product between square distance of each component weight. in other words, x^{t}y x square distance of each component , y weights each component. sum(x,2) if like, find more elegant , easy read... plus it's less code!

now know how you're obtaining u, type uint8 need cast image double before anything. should accomplish weighted euclidean distance talked about.

as check, let's set in matrix in example, run through pdist squareform

x=[62,29,64; 63,31,62; 65,29,60; 63,29,62; 63,31,62]; weights = [3;4;2]; weuc = @(xi, xj, w) sqrt(bsxfun(@minus,xi,xj).^2 * w); %// create sure cast double, image uint8 %// don't have here x double, %// remind so! dist_vector = pdist(double(x), @(xi, xj) weuc(xi, xj, weights)); dist_matrix = squareform(dist_vector) dist_matrix = 0 5.1962 7.6811 3.3166 5.1962 5.1962 0 6.0000 4.0000 0 7.6811 6.0000 0 4.4721 6.0000 3.3166 4.0000 4.4721 0 4.0000 5.1962 0 6.0000 4.0000 0

as can see, distance between pixels 1 , 2 5.1962. check, sqrt(3*(63-62)^2 + 4*(31-29)^2 + 2*(64-62)^2) = sqrt(3 + 16 + 8) = sqrt(27) = 5.1962. can similar checks among elements within matrix. can tell distance between pixels 5 , 2 0 have made these rows of pixels same. also, distance between each of 0 (along diagonal). cool!

matlab image-processing matrix rgb euclidean-distance

Comments

Popular posts from this blog

php - Android app custom user registration and login with cookie using facebook sdk -

django - Access session in user model .save() -

php - .htaccess Multiple Rewrite Rules / Prioritizing -