1

I selected some pixels from an RGB image using ginput. Now I need a code to extract RGB value of all of selected pixels in a same time and save them in coordinate matrix of pixels. Any suggestion?

A=imread('AMAR.jpg');
imshow(A)
samp1= ginput(A)

samp1 is <47x5 double>

some results are:

95 92 95 81 99 66 97 66 100 58 105 51 108 42 116 33

chappjc
  • 30,359
  • 6
  • 75
  • 132
  • 1
    Can you give a bit of code that shows how you extract single values? Typically if you have `rgbMatrix(N, N, 3)` you can extract a region `region = rgbMatrix(5:10, 6:12, :);` to get a rectangular region. Adapt for your needs... – Floris Feb 11 '14 at 20:46
  • ` A=imread('AMAR.jpg'); imshow(A) samp1= ginput(A)` and these are coordinates of some pixels: samp1 = 95 92 95 81 99 66 97 66 100 58 105 51 108 42 116 33 124 25 133 18 141 14 151 10 164 9 173 9 186 10 200 14 – user3298890 Feb 11 '14 at 20:49
  • The input argument to `ginput(N)` is the number of points to acquire from the currently displayed image. Are you wanting RGB values for arbitrary clicked points (as in my answer), or rectangular regions? – chappjc Feb 11 '14 at 21:03
  • @chappjc yes. clicked points – user3298890 Feb 11 '14 at 21:10

2 Answers2

1

Say you click on N points in an RGB image:

N=4;
imagesc(img)
[x,y]=ginput(N);

The x,y values can be used to lookup the RGB vector for each location:

x = round(x(:)); y = round(y(:));
locs = sub2ind(size(img),repmat(y,3,1),repmat(x,3,1),kron(1:3,ones(1,N)).'); %'
RGBvals = reshape(img(locs),N,3)

That gives you an N-by-3 array of RGB values for each point. Use the interactive tool impixelregion to visually verify the color values.

Note: See here for a bit about kron that should hopefully deflate any mystery about its use here.

Community
  • 1
  • 1
chappjc
  • 30,359
  • 6
  • 75
  • 132
1

@chappjc's answer would work; I would like to offer a small change that is a bit more "readable":

First - call ginput without any arguments. It will keep accumulating points clicked until you hit "enter". A little more user friendly.

Second - there's a time and a place for vectorization. When you have just a handful of points (namely, one point per click) it is unlikely that the speedup of vectorized code is worth the pain of sub2ind, repmat, kron...). That leaves us with the following:

imshow(A);
disp( 'Click points in the image; press return when finished' );
[xf, yf] = ginput;

xi = round(xf);
yi = round(yf);

N = numel(xi);
rgbValues = zeros(N, 3);

for ii = 1:numel(xi)
  rgbValues(ii,:) = reshape(A(yi(ii), xi(ii), :), 1, 3);
end

This will put the values you want into rgbValues.

Do check that the values of xi and yi are returned in the order shown; I think this is right, but if I'm wrong you would have to use the order A(xi(ii), yi(ii), :) when you read the image).

Floris
  • 45,857
  • 6
  • 70
  • 122
  • Good points, plus one. But once you get used to the kinds of tricks in my answer, they come with minimal pain. Conversely, these three letters make my fingers ache: `f`-`o`-`r`. :) – chappjc Feb 11 '14 at 23:09
  • 1
    @chappjc - there is a time and a place for everything. I actually just ran a benchmark, comparing the two codes. Quite apart from the fact that either of them is blazingly fast compared to the time taken by the user inputting data, when I sum over 10,000 runs my form of code is 3x faster for 10 clicked points - breakeven happens around 100 points clicked. At 500 points "clicked", your code is 3.5x faster. This shows that eliminating `for` loops is not _always_ worth it... – Floris Feb 11 '14 at 23:37
  • 1
    I quite agree. I was merely being facetious, and a little self deprecating over my unfounded aversion to loops. – chappjc Feb 11 '14 at 23:39
  • Nothing wrong with a little self-deprecation. It beats waiting for others to do it. – Floris Feb 11 '14 at 23:40