How do i get the average red, green and blue from an ofVideoPlayer?


#1

Im using this:

ofPixels & pixels = movie.getPixels();
    
    int vidWidth = pixels.getWidth();
    int vidHeight = pixels.getHeight();
    int nChannels = pixels.getNumChannels();
    int allRed = 0;
    int allGreen = 0;
    int allBlue = 0;
    
    for(int i = 0; i<vidWidth; i++){
        for(int j = 0; j<vidHeight; j++){
            allRed = allRed + pixels[(j*vidWidth+i)*nChannels];
            allGreen = allGreen + pixels[(j*vidWidth+i)*nChannels+1];
            allBlue = allBlue + pixels[(j*vidWidth+i)*nChannels+2];
    }
    }
    int avgRed = allRed/(vidHeight*vidWidth);
    int avgGreen = allGreen/(vidHeight*vidWidth);
    int avgBlue = allBlue/(vidHeight*vidWidth);

Still not getting the expected values


#2

Hi, is maybe the int overflowing? Here are the limits.

What about switching to long (or unsigned long)?


#3

Already tried that, still not getting any values. Thank you, in advance


#4

Hi,
What do you get ?
Because this code works for me, I get the average color from a webcam.

NB: A nicer and more convenient way to loop over the pixels is:

for( auto & p : pixels.getConstPixelsIter() )
{
	allRed += p[ 0 ];
	allGreen += p[ 1 ];
	allBlue += p[ 2 ];
}

(I haven’t done any perfs comparison)


#5

long it’s usually the same as int, try uint64_t instead. Also when dividing by w*h at the end you should cast to float otherwise you are doing an integer division.

if that’s not enough (i think it should) you can try to average each line first then average all the lines as in:

std::vector<uint64_t> linesAvgR{pixels.getHeight());
std::vector<uint64_t> linesAvgG{pixels.getHeight());
std::vector<uint64_t> linesAvgB{pixels.getHeight());
for(auto line: pixels.getLines()){
    uint64_t avgR = 0;
    uint64_t avgG = 0;
    uint64_t avgB = 0;
    for(auto pixel:  line}{
        avgR += p[0];
        avgG += p[1];
        avgB += p[2];
    }
    lineAvgR[line.getLineNum()] = avgR / float(pixels.getWidth());
    lineAvgG[line.getLineNum()] = avgG / float(pixels.getWidth());
    lineAvgB[line.getLineNum()] = avgB / float(pixels.getWidth());
}

#6

Solved. The problem was in the code before thar. Thank you anyway