Search 3D RGB array for the closest match?

2 visualizaciones (últimos 30 días)
Roger Breton
Roger Breton el 24 de Feb. de 2022
Comentada: Roger Breton el 25 de Feb. de 2022
In my humble script, I managed to capture the 3D location on a scatter3 graph (see my previous question) out of a pushbutton uicontrol. Now, in the callback function, I have to find a way to locate the closest x,y coordinates corresponding this 3D data point :
Granted, there are many possibilities here, to approach the problem.
This is my call back function so far :
function plot2D(src,event)
global clickedCIE_L clickedCIE_a clickedCIE_b;
figure(1);
Clicked_Pixel_RGB = lab2rgb([clickedCIE_L clickedCIE_a clickedCIE_b], 'WhitePoint','d50');
plot(x,y);
end
So I convert CIE Lab to RGB values (double). I still have to contend with negative RGB values and RGB values greater than 1.0. If you have any suggestions for this too, I'm all ears.
This is my original RGB data :
img = imread(RGBimage);
img_double = double(img)./255;
img2Lab = rgb2lab(img_double, 'WhitePoint','d50');
So, I think I either have to search the img_double array or the img array? But how? Could I use something like this :
row = find(img(:)~= Clicked_Pixel_RGB ); % Assume I multiplied Clicked_Pixel_RGB by 255
But it's not working... I have the intution that I have to search the whol array. That's why I use img(:). But I am not sure that's the right syntax.
  2 comentarios
Walter Roberson
Walter Roberson el 24 de Feb. de 2022
Side point:
img_double = double(img)./255;
instead you should use
img_double = im2double(img);
Roger Breton
Roger Breton el 25 de Feb. de 2022
Thank you!

Iniciar sesión para comentar.

Respuesta aceptada

Roger Breton
Roger Breton el 25 de Feb. de 2022
I think I found a solution (I'm sure there are other approaches, surely more efficient, but here goes). It involves using DeltaE Eucledian color distance function to find the difference between two sets of colors. Here's some experimental code :
img = imread('image10cx8r.png');
SizeImg = size (img); % Initial Width and Height setting
Width = SizeImg(2); % 10
Height = SizeImg(1); % 8
Rows = Width; % 10
Cols = Height; % 8
% double!
Red = double(img(5,4,1)/ 255) %R = 5th Row, 4th Column = 255
Green = double(img(5,4,2)/255) %G = 5th Row, 4th Column = 0
Blue = double(img(5,4,3)/255) %B = 5th Row, 4th Column = 0
TargetRGB = zeros(Cols, Rows) % 10 x 8 x 3
TargetRGB(:,:,1)= Red;
TargetRGB(:,:,2)= Green;
TargetRGB(:,:,3)= Blue;
Rtest = TargetRGB(4,5,1);
Gtest = TargetRGB(4,5,2);
Btest = TargetRGB(4,5,3);
dE = deltaE(img,TargetRGB) % 8 rows x 10 cols
minValue = min(min(dE));
[RowIndex, ColIndex] = find(dE==minValue); % 5 4
I sure hope this helps someone because, while not rocket science, it requires 'thinking'. I started experimenting on my actual images which are 300 x 200, typically, that are already downsized from their original 'Photoshop' highres sizes. Wrong! I could not trace through execution with such image sizes? So, I created a tiny test image (see attached), an image of 10 columns by 8 rows, in which one pixel was made pure red (RGB = 255,0,0) so that I could have a known reference point.
I used that red as my search color. I first made sure my code was successfullly extracting that exact pixel color, indexing by row and column, out of the the entire image.
Then, once that was confirmed, I created a matrix the same size as the original PNG image and filled with the exact RGB value I was looking for, 255, 0, 0. So I had en entire new matrix of 'red', if you want.
Then, I tested various DeltaE formulations until I got it right.
My reasoning was resting on finding the lowest DeltaE between the TargetRGB matrix, which came from the user clicking with the mouse on the 3D scatter, and the entire PNG image matrix.
Once this was done (took me a while to get the logic right), then it was a matter of retrieving the lowest DeltaE value out of the dE matrix and use that for retriving 2D pixel row/col position.
At that point, I have all I need to plot a big marker on my 2D image :-)
Note that I wasn't aware that, all along, the two sets of values I was feeding to the DeltE computation were of different type -- yikes! It took me a while to figure that one out...
I have to give credits to the Matlab staff for the min() code statement, found in some other posts.

Más respuestas (0)

Categorías

Más información sobre Matrix Indexing en Help Center y File Exchange.

Productos


Versión

R2020b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by