# Histogram of image intensities

I want to create a histogram of intensities 0.1, 0.2, .... 0.9, 1, from an image rendered using OpenGL and C++. How can I do this? Can I access the pixel intensities in the framebuffer somehow? Also, I'm not using any glsl shaders, and don't intend to.

So far I tried:

unsigned char *framebuffer = frameBuffer = new unsigned char[1920*1080 * 4];

glReadPixels(0, 0, 1920, 1080, GL_RGBA, GL_UNSIGNED_BYTE, frameBuffer);

for (int j = 0; j<1920*1080 * 4; j += 4){
if(frameBuffer[j] == 0.1)
// find pixel with R channel at 0.1: this is where the problem is.
// I know I have surfaces with this intensity but I never enter the if statement
}

• Yes, you can do that. What issue are you having with doing that? What have you tried that hasn't worked? You need to give us more information. Jan 27, 2018 at 22:48

Due the way floating point values work, you probably don't want to do an exact equality check. You probably want something more like this in your loop:

uint32 sums [ 11 ] = { 0 };
for (int j = 0; j < 1920 * 1080 * 4; j += 4) {
size_t bucket = static_cast<size_t>(framebuffer [ j ] * 10.0);
sums [ bucket ]++;
}


Note that there are 11 buckets because the range includes both 0 and 1. If you want only 10 buckets and want to put any pixels that have a value of 1 in them into the top bucket, you could do:

uint32 sums [ 10 ] = { 0 };


and change the bucket index calculation to:

size_t bucket = static_cast<size_t>(framebuffer [ j ] * 10.0);
bucket = std::min(bucket, 9);

• Thanks for the solution. It makes sense! Although I'm testing things out, and I'm suspecting that framebuffer[j] isn't a value between 0 and 1. I'm trying to figure out if it's a value between 0 and 255 instead and hoping there isn't some other subtle transformation in the values. Jan 28, 2018 at 3:01
• @Stackmm, It is a value between 0 and 255. They are 8-bit normalized, meaning the values in the interval 0.0 through 1.0 are mapped to the 8-bit codes 0x00 through 0xFF. The 8-bit value you are looking for that equals 0.1 is: (unsigned char)(0.1 * 255.0 + 0.5) or about 26.
– Wyck
Jan 31, 2018 at 15:57
• Thank you very much! That solved everything. I'm glad I learned about the mapping. Jan 31, 2018 at 22:55
• Ah, I failed to notice that you were using GL_UNSIGNED_BYTE as the type for the call to glReadPixels. You could use GL_FLOAT to get floating point values. (Just make sure to allocate space for them. Your current allocation specifies new unsigned char [].) Feb 1, 2018 at 1:30