# 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. – user1118321 Jan 27 '18 at 22:48
• I added more information above, does it help? Thanks. – Stackmm Jan 27 '18 at 23:21

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. – Stackmm Jan 28 '18 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 '18 at 15:57
• Thank you very much! That solved everything. I'm glad I learned about the mapping. – Stackmm Jan 31 '18 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 [].) – user1118321 Feb 1 '18 at 1:30