How to pick a color value of each pixel on application screen.

Hello,

Currently I am working a project with oF and Kinect.
We basically want to take a video from Kinect to be displayed on oF app.
We have done that, so my app basically like a normal webcam.

Next thing, I want to take a color value of each pixel in the application screen.
For example the application is 800 x 600, then I want to know what color value on each pixel (for example using 2D array to store the color value of each pixel). But I do not have any idea yet how to make that.

Anybody know how to accomplished such that thing?

Thank you.

there are many ways to do that…

first declare an ofColour object to pass the values in

first method :double for loop: and this in:

  
  
  
  
    unsigned char * pixels = cam.getPixels();  
                int index = j*cam.width*3 + i*3;  
                int red = pixels[index];  
                int green = pixels[index+1];  
                int blue = pixels[index+2];  
myofColour.set(red,green,blue);  
  
  

Or …

  
  
	myofColour = cam.getPixelsRef().getColor(x, y);  
  
  
  

x, y = specific pixel

2 Likes

Okay I am sorry but I do not know what is “cam” in your code above?

I want the pixels to refers to the application screen pixels not in to any image or texture. :slight_smile:

I am done with it,

Here is the code:

  
  
ofBackground(100, 100, 100);  
	kinect.update();  
	// pix_color = kinect.getPixels();  
	// cout << pix_color << endl;  
	for(int i = 0; i < WINDOWHEIGHT; i ++){  
        for(int j = 0; j < WINDOWWIDTH; j ++){  
            // pix_color[i][j] = getPixelsRef().getColor(j, i);  
            pix_color = kinect.getPixels();  
            index = j * kinect.width * 3 + i * 3;  
            red = pix_color[index];  
            green = pix_color[index+1];  
            blue = pix_color[index+2];  
            pix[i][j].r = red;  
            pix[i][j].g = green;  
            pix[i][j].b = blue;  
            // cout << pix[0][0] << endl;  
        }  
	}  
	cout << pix[0][0] << endl;  
  

But now I having trouble making big sized array, the application won’t start if I make the screen resolution higher than 320 * 240.

Here take a look to my threat http://forum.openframeworks.cc/t/problem,-array-to-big-program-cannot-be-executed/11198/0

Thank you so much for the guidance :slight_smile: I really appreciate it.

cam is just a random name I picked as the instance of your ofVideoGrabber object. in your case, kinect - it can be anything. Sorry if it wasn’t clear enough the first time…

About your second question, I am not sure what you are doing wrong since you are not posting any code but I would bet
It’s not an oF thing it’s a c++/c syntax problem.

Java/processing allocates memory through object instantiation so in Java arrays are objects by nature… in c++ you are probably creating an array of bytes. Memory management it’s different in general.

so…

Try use stl::vectors, If you get it right it will solve your problems

post some code if you want further help

  
  
#include "testApp.h"  
#include <cmath>  
int _xCellValue; //holds the xCell position of each brush  
int _yCellValue; //holds the yCell position of each brush  
//--------------------------------------------------------------  
void testApp::setup(){  
    // kinect  
    ofSetLogLevel(OF_LOG_VERBOSE);  
    kinect.setRegistration(true);  
    kinect.init();  
    kinect.open();  
    pix_color = kinect.getPixels();  
  
    //initialize the brushes to be drawn  
    for( int i=0; i < BRUSHES; i++) {  
        brushes[i] = new brush( ofRandom(0,ofGetWidth()), ofRandom(0,ofGetHeight()), ofRandom(-10,10), ofRandom(-10,10), brushes, BRUSHES );  
        hairs[i] = new hair( 15, 5);  
        handles[i] = new handle(15, 5);  
    }  
    //initialize the background canvas  
    for( int j=0; j<HEIGHT; j+=CELLSIZE){  
        for( int i=0; i<WIDTH; i+=CELLSIZE){  
            visited[j/CELLSIZE][i/CELLSIZE] = new grid(0,i,j,0,125,255);  
        }  
    }  
  
    //draw a "wooden" picture frame  
    for( int i = 0; i < GRIDH; i++){  
        visited[i][GRIDW-1]->v = 2;  
        visited[i][0]->v = 2;  
    }  
    for(int j=0; j<GRIDW; j++){  
        visited[GRIDH-1][j]->v = 2;  
        visited[0][j]->v = 2;  
    }  
    ofSetFrameRate(10); //define the framerate  
}  
  
//--------------------------------------------------------------  
void testApp::update(){  
    kinect.update();  
  
    //for all brushes on the canvas  
    for( int i=0; i < BRUSHES; i++) {  
        brushes[i]->update(); //update the brushes allowing them to move  
  
        //calculate on which cell each brush is on  
        _xCellValue = abs(ceil((brushes[i]->x)/CELLSIZE));  
        _yCellValue = abs(ceil((brushes[i]->y)/CELLSIZE));  
  
        //correction to allow a border - to play the role as  
        //picture frame  
        if(_xCellValue==GRIDW){  
            _xCellValue = GRIDW-1;  
        } else if(_xCellValue==0){  
            _xCellValue = 1;  
        }  
        if(_yCellValue==GRIDH){  
            _yCellValue = GRIDH-1;  
        } else if(_yCellValue==0){  
            _yCellValue = 1;  
        }  
        //cout<< _xCellValue << " " << _yCellValue << endl;  
  
        //if the cell the brush is on, is not painted yet...  
        if(visited[_yCellValue][_xCellValue]->v==0){  
            /*index = (brushes[i]->x) * kinect.width * 3 + (brushes[i]->y) * 3;  
            red = pix_color[index];  
            green = pix_color[index + 1];  
            blue = pix_color[index + 2];  
            pix.r = red;  
            pix.g = green;  
            pix.b = blue;*/  
  
            visited[_yCellValue][_xCellValue]->r = red;  
            visited[_yCellValue][_xCellValue]->g = green;  
            visited[_yCellValue][_xCellValue]->b = blue;  
            visited[_yCellValue][_xCellValue]->v=1; //paint it the desired color  
        }  
    }  
}  
  
//--------------------------------------------------------------  
void testApp::draw(){  
  
    // kinect  
    ofBackground(100, 100, 100);  
  
    // kinect  
    ofSetColor(255, 255, 255);  
    kinect.draw(0, 0, 800, 800);  
  
    //draw the background grid - which will play the role  
    //of a canvas on which get painted on  
    for( int j=0; j<HEIGHT; j+=CELLSIZE){  
        for( int i=0; i<WIDTH; i+=CELLSIZE){  
            visited[j/CELLSIZE][i/CELLSIZE]->draw();  
        }  
    }  
    //draw all brushes  
    for( int i=0; i < BRUSHES; i++) {  
        ofSetLineWidth(2); //predefine the line width  
        glPushMatrix(); //push the current matrix on the stack  
        brushes[i]->draw(); //draw the superclass  
        handles[i]->draw(); //draw the handle subclass  
        hairs[i]->draw(); //draw the hair subclass  
        glPopMatrix(); //pop the current matrix of the stack  
  
        index = brushes[i]->x * kinect.width * 3 + brushes[i]->y * 3;  
        red = pix_color[index];  
        green = pix_color[index + 1];  
        blue = pix_color[index + 2];  
    }  
}  
  
//--------------------------------------------------------------  
//if a key is pressed give all brushes a random direction  
void testApp::keyPressed(int key){  
    for( int i=0; i < BRUSHES; i++) {  
        brushes[i]->randomSpeed();  
    }  
}  
  
void testApp::exit(){  
    kinect.setCameraTiltAngle(0);  
    kinect.close();  
}  
  
  

Here is the code I don’t know where the problem is but it always close itself somwhen after my program opens.

I am afraid I can’t run that code, I don’t have the classes hair brush handle. I can only speculate what your error is
so your code runs on 240x320 but crashes on bigger resolution??
your code runs without the get colour loop but it crashes when you get the colour??

what error does it give you?

…anyways thought

I see you have arrays of classes so
try replacing your arrays with vectors:
They handle objects better.
in your header file

replace your

brush brushes[BRUSHES]; etc…

with:

  
 vector<brush> brushes;  
    vector<hair>hairs;  
    vector<handle>handles;  
  

in your cpp code THIS:

  
handles[i] = new handle(15, 5);  

becomes:

  
          handles.push_back(handle(15, 5));  
  

So overall something like:

  
  
 for( int i=0; i < BRUSHES; i++) {  
      
          brushes.push_back(brush(ofRandom(0,ofGetWidth()), ofRandom(0,ofGetHeight()), ofRandom(-10,10), ofRandom(-10,10), brushes, BRUSHES ));  
          hairs.push_back(hair( 15, 5));  
          handles.push_back(handle(15, 5));  
  
            
          }  
  
  

there are many ways to instantiate vectors.

now for the rest of your code I see you have a pointer of a twodimentional array

I don’t know what is grid but if grid was an int
like : int *visited[][]; ???
this is how you declare it:

vector< vector > *visited;