I have a 384*512*3 RGB matrix. There are only 512 unique colors which repeat themselves with different weights. From them, I have to select half, and the other half must be replaced with the closest elements from the first one.
I thought of looping through the image, and search the closest color for the current one. After finding it, I replace one with the other.
But I have 3 loops 1:384, 1:512, 1:256. With the first two I loop through the RGB matrix, the third is used to loop to the matrix containing the final colors. This takes some time to compute.
What can be done to speed it up?
The loops look like this:
dim=size(RGB); for i=1:dim(1) for j=1:dim(2) aux=[RGB(i,j,1) RGB(i,j,2) RGB(i,j,3)]; minim=RGB_dist(uint8(V_colors_K(1,1:3)),aux); index=1; for k=1:K %index=1; if (minim>RGB_dist(uint8(V_colors_K(k,1:3)),aux)) minim=RGB_dist(uint8(V_colors_K(k,1:3)),aux); index=k end RGB(i,j,1)=V_colors_K(index,1); RGB(i,j,2)=V_colors_K(index,2); RGB(i,j,3)=V_colors_K(index,3); end end end V_colors_K represent the half colors selected to be the final ones.
There is some minor improvement I could think about. The minimum distance is not needed if the color is in the good half.
Here's the algorithm to be more precise:
Definition 1. Function D(c1,c2) is the distance between two color vectors c1 and c2, such as Euclidean distance.
Definition 2. Function P(c) is the pixel number of color c. Definition 3. Base-color cbase of an initial color set Q is the color that satisfies the equation

Definition 4. A weighted product of color c, V(c), is defined as

where wp is the weight of the number of pixels, and wd is the weight of a color distance.
Given the first color cbase, our method calculates the weighted products of other colors and selects the first K-1 largest product. The corresponding K-1 colors with the base-color are used to form an initial palette. The left N–K colors are merged with the closest colors in the initial palette to produce the final palette.
RGB_dist function:
function[distance]=RGB_dist(x,y) distance=sqrt(sum((double(x-y)).^2*[3;4;2],2)); end I do have a function that works on a whole matrix, it calculates the distance between all pairs.
function[D]=RGB_dist_full_2(x) I = nchoosek(1:size(x,1),2); D = squareform(RGB_dist(x(I(:,1),:), x(I(:,2),:))) end Then, I would need to get the minimum on each column.