<p>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:</p>

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

<p>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:</p>

<pre><code>uint32 sums [ 10 ] = { 0 };
</code></pre>

<p>and change the bucket index calculation to:</p>

<pre><code>size_t bucket = static_cast&lt;size_t&gt;(framebuffer [ j ] * 10.0);
bucket = std::min(bucket, 9);
</code></pre>

CC BY-SA 3.0
2018-01-28T03:01:36.930Z
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
CC BY-SA 3.0
2018-01-31T15:57:17.780Z
@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
CC BY-SA 3.0
2018-01-31T22:55:37.343Z
Thank you very much! That solved everything. I'm glad I learned about the mapping.
Stackmm
CC BY-SA 3.0
2018-02-01T01:30:05.267Z
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
CC BY-SA 3.0
2018-01-27T23:35:46.803Z
2018-01-27T23:35:46.803Z
user1118321
<p>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.</p>

<p>So far I tried:</p>

<pre><code>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&lt;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
}
</code></pre>

CC BY-SA 3.0
2018-01-27T22:48:00.177Z
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
<opengl><image-processing><c++>
Histogram of image intensities
Stackmm
# Histogram of image intensities

(Asked by: username_0 on 2018-01-27)

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
}

```

**Tags:** opengl, image-processing, c++

> **Comments:**
> **username_1**: 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.  

---

## 1 answers

### Answer by username_1 on 2018-01-27. Score: 2 | Accepted answer

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);

```

> **Comments:**
> **username_0**: 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.  
> **username_2**: @username_0, 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.  
> **username_0**: Thank you very much! That solved everything. I'm glad I learned about the mapping.  
> **username_1**: 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 []`.)  

---

