Learning from app examples

Hi all,

I’m running OF on the latest version of code blocks on a windows xp pro sp3 OS.
I purchased and have been reading the book “Programming Interactivity” by Josh Noble and I’ve completed the spoonfeed N00b youtube tutorial series on c++ , before I began to take a look at the app examples that come with the OF install.

Are there other more explicit resources available to help new users understand the
workings of the classes encountered in OF. I have already looked at the documentation that is provided on this site, but it doesn’t really help explain what’s going on in the example apps.

For instance: I am currently looking at the “moviePlayerExample” app provided with the OF install. It runs fine and I understand the basics of why it runs, how it accesses the movie in the bin file etc., but I must have spent about 3 hours searching Google, looking over the “Programming Interactivity” book as well as the online OF documentation here to determine what is actually going on in the code snippet below from the for loop down (IMHO it is not very intuitive to understand):

fingerMovie.draw(20,20);
ofSetColor(0x000000);
unsigned char * pixels = fingerMovie.getPixels();
// let’s move through the “RGB” char array
// using the red pixel to control the size of a circle.
for (int i = 4; i < 320; i+=8){
for (int j = 4; j < 240; j+=8){
unsigned char r = pixels[(j * 320 + i)*3];
float val = 1 - ((float)r / 255.0f);
ofCircle(400 + i,20+j,10*val);

I do understand that the unsigned char pointer named pixels contains all the pixel information from the loaded movie, but it is not clear how the pixel data is arranged in the pixels variable. I’m not sure what is being accessed in the for loop and the logic therein as well as the part of creating the circle.

I apologize if this is a really low level newbie kind of question. But it seems that
just like cooking, it doesn’t make sense to just follow the recipe without understanding why things are done the way they are.

I know I’m not lacking the aptitude to understand this stuff, but without a more
verbose explanation of why/how things are done, it doesn’t seem reasonable that
I (nor anyone else) should just know what is going on by looking at the code above (given the basic documentation I’ve seen on the getPixels() method).

Maybe I missed a link to some elementary primer that everyone has already read??

You suggestions are welcome and very much appreciated.

Thank you,
Michael

hi Michael,

to answer your questions:

  1. pixel data is arranged in sets of 1, 3, or 4 bytes (unsigned chars) (1 for greyscale images, 3 for RGB images, 4 for RGBA images). if we have a 10x10 pixel image in RGB format, the very first pixel’s data starts at pixels[0], and the very last pixel’s data starts at pixels[(10*10-1)*3]: 10*10 to get to the last pixel, then -1 because the array is 0-based, then *3 because we are RGB therefore have 3 bytes per pixel.

  2. each set of data is either just White (greyscale), or (Red,Green,Blue) in that order for RGB, or (Red,Green,Blue,Alpha) for RGBA. to access the first (0th) pixel’s Red component, we say pixels[(0*3)+0]. to access the 4th pixel’s Red component, we say pixels[(4*3)+0]. to access the 4th pixel’s Green component, we say pixels[(4*3)+2];

  3. with that in mind,
    unsigned char r = pixels[(j * 320 + i)*3];
    will give us the red component of the pixel at row j, column i.

if we wanted the green component instead, we would say
unsigned char g = pixels[(j * 320 + i)*3+1];

  1. from there, we need to get some floating point number for the radius of the circle, and put it in ‘val’. since ‘r’ is in the range 0…255 (the range of an unsigned char), r/255.0f will give us a number in the range 0…1 . so, if the red component of a pixel is 255, val will be 1; if it’s 128, val will be 0.5, etc. taking 1.0f-val just means to flip it on its head.

  2. then, the circle is drawn, with the radius as 10*val.

… damn. having written all that, i found that pixels was documented already in the wiki: http://wiki.openframeworks.cc/index.php-…-ver-pixels i found that by searching for ‘pixels’ in the wiki.

this is fairly elementary stuff, yes, but there isn’t really a single ‘document’ that all of us have already read - it’s just something that you pick up eventually. your confusion is understandable. since oF is still very new, it’s still the case that many of the people involved have come to it through other kinds of graphics-based programming, which means they usually already expect pixel data to be aligned in a certain way in an array like this.

unfortunately, as with most open source projects, almost all of the people working on oF have full time jobs elsewhere – which is where this community here can step in and help. if this helps you, and if you think you understand this concept, perhaps you could write a nice tutorial/help text paragraph (it sounds like your writing skills are very good!), and submit it to one of the developers to be included in the documentation?

hope this helps,
damian

Hello Damian and Thanks so much for the reply,

I really appreciate your time. I apologize for belaboring this point but I want to
make sure I thoroughly understand this. Once I’ve gotten it down, I will be more than happy to format it nicely into a beginner’s tutorial for others.

Please indulge this summary of my understanding and let me know where I am going wrong:

Keeping it very simple, I start with a 2 x 2 pixel image in RGB format.

For each pixel in the image, (in the RGB color space) 3 values determine the final color
that the pixel displays, i.e., one for Red, one for Blue and one for Green.

Given a Bit depth of 8, these values range from 0-255 for each Color component.

A total of 3 bytes are allocated in memory for these 3 values (1 byte for each Color component).

This yields:

12 bytes of pixel data (2 pixels of width x 2 pixels of height x 3 color components for each pixel).

These 12 bytes of pixel data are stored in memory as a bitmap, i.e. a contiguous section of memory addresses where each color component’s value sits next to one another.

The getPixels() method returns this bitmap as an unsigned char array (pointer to the first memory address where the bitmap for the image begins).

The pixel data in the image are “mapped” to the memory addresses, i.e., allocated to the unsigned char array, as follows:

Example

2 x 2 pixel image
unsigned char * pixels = myImage.getPixels();

The array has a total of 12 elements (notated as pixels[11]). The first element is 0 and the last element is 11.

The value of the first color component (Red) of the first pixel of the image (Upper left) is stored in the first position of the array (pixels[0]). And so on:

pixels[0]=the value of the Red color component of the first pixel (Upper left)
pixels[1]=the value of the Green color component of the first pixel (Upper left)
pixels[2]=the value of the Blue color component of the first pixel (Upper left)

pixels[3]=the value of the Red color component of the second pixel (Upper right)
pixels[4]=the value of the Green color component of the second pixel(Upper right)
pixels[5]=the value of the Blue color component of the second pixel (Upper right)

pixels[6]=the value of the Red color component of the third pixel (Lower left)
pixels[7]=the value of the Green color component of the third pixel (Lower left)
pixels[8]=the value of the Blue color component of the third pixel (Lower left)

pixels[9]=the value of the Red color component of the fourth pixel (Lower right)
pixels[10]=the value of the Green color component of the fourth pixel (Lower right)
pixels[11]=the value of the Blue color component of the fourth pixel (Lower right)

I believe this is correct, however, I have a question regarding your reply:

  1. pixel data is arranged in sets of 1, 3, or 4 bytes (unsigned chars) (1 for greyscale images, 3 for RGB images, 4 for RGBA images). if we have a 10x10 pixel image in RGB format, the very first pixel’s data starts at pixels[0], and the very last pixel’s data starts at pixels[(10*10-1)*3]: 10*10 to get to the last pixel, then -1 because the array is 0-based, then *3 because we are RGB therefore have 3 bytes per pixel.

  2. each set of data is either just White (greyscale), or (Red,Green,Blue) in that order for RGB, or (Red,Green,Blue,Alpha) for RGBA. to access the first (0th) pixel’s Red component, we say pixels[(0*3)+0].

I’m with you up to here.

to access the 4th pixel’s Red component, we say pixels[(4*3)+0]. to access the 4th pixel’s Green component, we say pixels[(4*3)+2];

[color=#FF0000]Here I get lost and I hope its just a typo that’s confusing me :slight_smile:

Thank you,

Michael Hussar

To access the 4th pixel’s Red component, Wouldn’t it be pixels[(3*3)+0] which would be pixels [9] according to my chart above?

and to access the 4th pixel’s Green component, wouldn’t it be pixels[(3*3)+1] which would be pixels [10] according to my chart above?

yep, you’re right - that was a typo on my part.

Given 3 color components per pixel this would be equivalent to: 960 bytes (320 pixels x 3 color components) plus 12 bytes (the 4 additional pixels (to get to column 4 on the 4th row) x 3 color components) for a total of 972 bytes or the 972nd element in the unsigned char array, i.e. pixels [971]?

you’re missing a *4 in there: it’d 320 pixels * 3 color components * 4 rows.

Cheers Damian ! — I think I’m sorted out :slight_smile:

Michael

Thanks Damian & Michael!

I had been looking for something this down-to-the-basics for quite a while. It really helped me, and, like Michael, I wish there were more things this thoroughly explained, assuming no prior knowledge (though I do appreciate the full-time-job issue). I believe it would not only help us n00bs but serve as a useful fallback for those debugging.

I was wondering if it would be fair to sum up like the attached diagram?

Thanks again for the useful post! :slight_smile:

Hi I think the -1 is unnecessary.

I attached created a cheat sheet that may help others with the same problem.

1 Like

Thanks underdoeg!

I will now tape that to my wall and burn it to my brain! :slight_smile:

1 Like

Thank you so much for this…I will also be taping this to a wall! :slight_smile:

OF 007 also has some nice color getter/setters built in.

they’re all in ofPixels:

  
  
int getPixelIndex(int x, int y) const;  
ofColor_<PixelType> getColor(int x, int y) const;  
void setColor(int x, int y, ofColor_<PixelType> color);  
  

this means you can do something like:

  
  
ofPixels pixels;  
pixels.setColor(100, 200, ofColor(200, 100, 50));  
  

if you’re working with an ofImage, it also has:

  
  
ofColor_<PixelType> getColor(int x, int y) const;  
void setColor(int x, int y, ofColor_<PixelType> color);  
  

which wrap the ofPixels method.

if you just want getPixelIndex(), you’ll need to get the ofPixels reference from your ofImage:

  
  
ofPixels& pixels = img.getPixelsRef();  
int i = pixels.getPixelIndex(100, 200);