Isolating Red and Green in Image

Dear ROOT forum members,

I am faced with a problem of isolating red channel in a jpg image, and making a histogram, and doing the same for green. Making histograms is shown very well by example root.cern.ch/root/html/tutorials … ist.C.html
while access to argb array is shown in another (far less clear) ecample
root.cern.ch/root/html/tutorials … aph.C.html

Basically, if someone could hint me on how this mechanism works in general, as float grey = float(argb[index]&0xff)/256 line is probably the key to solution of my problem… and what are
Float_t GetRed() const { return IsGrayscale() ? GetGrayscale() : fRed; }
Float_t GetGreen() const { return IsGrayscale() ? GetGrayscale() : fGreen; }
Float_t GetBlue() const { return IsGrayscale() ? GetGrayscale() : fBlue; }
as there was no documentation, and I could not figure out how to work with them…

Let us take the image2hist.C as a basis and if someone could help me isolate red component only, I would appreciate it greatly! Thank you,
Eugene.

And what’s your question/problem? Grayscale is a grayscale, it has the same value in R, G and B.
Like 0.1 0.1 0.1 (dark gray) 0.15 0.15 0.15 (a bit lighter) and etc. It’s clear, that it’s enough to take value from red (or green, or blue) channel and return it.
If it’s not a grayscale, you have to extract R component from UInt_t. For a test just create a png file (say, in paint or any other application) filled with red only, open it in TASImage, request argb pixels and check
the required component (bitmask + shit or shit + bitmask, up to you).

If you want, say, red, try this:

void image2hist()
{
   TASImage image("rose512.jpg");
   UInt_t yPixels = image.GetHeight();
   UInt_t xPixels = image.GetWidth();
   UInt_t *argb   = image.GetArgbArray();

   TH2D* h = new TH2D("h","Rose histogram",xPixels,-1,1,yPixels,-1,1);

   for (int row=0; row<xPixels; ++row) {
      for (int col=0; col<yPixels; ++col) {
         const int index = col * xPixels + row;
         const float red = float((argb[index] & 0xff0000) >> 16) / 256;
         h->SetBinContent(row + 1, yPixels - col, red);
      }
   }
   
   gStyle->SetPalette(53);
   h->Draw("colz");
}

OK! Sorry, did not see your code snippet there! Going to try!

Thank you, tpochep,

The only problem is that I have not worked with TASImage before, ever: didn’t need it.
Having said that… The image is color. How exactly would I “…extract R component from UInt_t”?
GetRed(), GetGreen() work with class TColor.

UInt_t color = argb[index] & 0xffffff; // what am I getting here?

float(argb[index]&0xff)/256 // what am I getting here? A fraction of grey?

The documentation to TASImage is something more to be desired, hence are my questions as an absolute newbie in color manipulations… if I understand your suggestions correctly, you are hinting me to look at the static UInt_t color2rgb(TColor *col) in the trans_graph.C example more closely.
Again, your hints are most appreciated!

In the example in my reply I’ve demonstrated how to extract R component from pixel data.
Documentation of TASImage does not really explain anything, that’s why I suggested you to start with completely red image to see, where red is in UInt_t.
pixel & 0xffffff gives you rgb triplet packed in UInt_t (with alpha masked out).

I think the name grey in the image2hist macro is copy & pasted from another macro. Here it’s a blue channel.

Your provided example works wonderfully… I will still think about how exactly, but I think I have it all working now - extracted red and green channels, and divided them! :slight_smile:
Although in your code snippet for red… I think it should read “<< 16” to work… Am I correct?

Thank you, and all the best! your help is really appreciated!
Sincerely,
Eugene.

No, it is >> 16 since you move 0xXX0000 by 4 hex (== 16 binary) digits and as a result you have a number in a range [0-255] which you divide by 255. to map it to [0.-1.] range.

masking + << 16 will give you 0 (if UInt_t is 32 bits).