2

RGB consists of three channels - red, green, blue. How do I get lets say brown channel out of rgb?

I need it to be able to recognize brown (rusted) objects in a photo, so it would be nice to convert the photo into a "brown channel".

EDIT:

Here is the photo from which the brown colour should be recognized:

http://dl.dropbox.com/u/4571/section.jpg

Oldrich Svec
  • 4,191
  • 2
  • 28
  • 54
  • Here's a related question that shows techniques to detect a color in an image: [How can I convert an RGB image to grayscale but keep one color?](http://stackoverflow.com/q/4063965/52738) – gnovice Mar 14 '12 at 15:43

4 Answers4

2

One could think of brown-ness in literally two dimensions, but a brown channel would be only one dimensional. Ergo, you cannot define a brown channel quite as easily as you may wish.

Even the red channel does not truly define the redness of a color, so you will need to define what you mean by brown channel before anyone could help you. There are many ways one could false color an image to reflect brown-ness of any given pixel. Perhaps you might choose the Euclidean distance in L*a*b* units (often called delta E) from some nominal brown color. Of course, this will give you the same brownness if you are red, or green, or blue (all by the same amount) from that given color. And suppose we move directly out from the neutral axis by k units, as opposed to moving directly into the neutral axis by k units. Surely moving away from neutral would create a color that is MORE brown, but the above definition (in terms of delta E) would say that is not true.

You might think about some path through color space as defining brown. Thus consider the path from white to the point you will define as "brown". (Pick that point carefully. Is it on the gamut boundary? If not, what happens as you move further in that direction?) Now brown-ness is essentially the distance from white along your path. For any color not on that path, project the point orthogonally down onto the path to determine its essential brown-ness. Note that it will help if your definition of the path is a straight line in your color space, as otherwise this orthogonal projection becomes a bit nasty.

Given some time, I might be able to come up with another way to define brown, but this is your question, not mine. Only YOU can define what you mean.

Edit: Given the picture shown in the revised question, I'd suggest a simple scheme. The "brown" spots appear to be composed of dark brown colors, and a lighter, almost yellowish "tan", but not really much in between those two alternatives. So, convert your image into a color space like CIE Lab. Each pixel will now be represented in terms of the corresponding coordinates in Lab space, instead of RGB. Now, choose a nominal brown color, and a nominal yellow, and compute the Euclidean distance in Lab from these two points. If the pixel is within some specified tolerance, then call it brown, or yellow. This is a common solution for your problem.

  • Thanks for the explanation. I will try to go with the path. I have updated my question with a link to the picture of brown spots which I would like to recognize. – Oldrich Svec Mar 13 '12 at 15:01
1

You can try to use a euclidean distance to measure the distance between the pixels color and your targeted color. Then you would probably add a thresholding technique on top of this to select only the pixels that are within a defined range of your targeted color.

The euclidean distance in the RGB space is simply: distance=sqrt((Rt-Rp)^2+(Rt-Rp)^2+(Rt-Rp)^2)

With Xt and Xp being the RGB components of the targeted color and the image pixels.

You can normalize this by the maximum possible distance, that is the distance between black and white (I am not definitive about that last part, you could try alternate normalization).

Here is an example in Matlab:

% Load image in RGB encoding
file='rust.jpg';
img=imread(file);
% Target
brown=[165 42 42];
imgd=double(img);
% Compute the euclidean distance so that 255 is exactly this color and 0 the maximum possible distance (between black and white)
browndistance=uint8(255-255*sqrt((brown(1)-imgd(:,:,1)).^2+(brown(2)-imgd(:,:,2)).^2+(brown(3)-imgd(:,:,3)).^2)/sqrt(255^2+255^2+255^2));
figure;
imshow(browndistance,[0 255]);

Only tested that it can work, maybe it will not be accurate enough for your needs.

Aabaz
  • 3,106
  • 2
  • 21
  • 26
0

You can try AForge.NET, I think AForge.Imaging.Filters.ExtractChannel is what you want. If not, there are some other methods in there related to RGB channels.

user247702
  • 23,641
  • 15
  • 110
  • 157
0

I would go through the photo in search for my brown color

My rusty brown would be "165;42;42" in RGB.

color palette
http://web.njit.edu/~kevin/rgb.txt.html#Brown

I would iterate through each pixel and check if there are any similar values. If one of channels is close enough to the benchmark(let's say +/- 5), I'd save the coordinates of such pixcel in separate list.

That also would give me a control of the sensitivity - I would be able to decide how accurate the solution should be...

And with a list of saved pixcels, you could simply recolor them i.e. as yellow, to show what your application has found to the user.

This solution may be slow, though... and if there are any build-in solutions i'm not aware of, it might be wiser to use them.

  • Thanks for the suggestions. If nothing else comes then I will use this method. But I would prefer something more "advanced". – Oldrich Svec Mar 13 '12 at 11:16