static void averageColorOf8x8_Blocks(unsigned char* img, int width, int height, long avgc[8][8]) {
// validate arguments
assert(img);
assert(width);
assert(height);
// calculate block size(block width x block height)
int blck_w= width/8, blck_h=height/8;
// compute average of each block(to get 64 color values)
for(int y=0;y<height;y+=blck_h) { // for each vertical block
for(int x=0;x<width;x+=blck_w) { // for each horizontal block
for(int z=0;z<blck_h;++z) { // for each block entry
for(int w=0;w<blck_w;++w) {
avgc[y/blck_h][x/blck_w] += (long)img[(y+z)*width +x+w ];
}
}
avgc[y/blck_h][x/blck_w] *= 1/(blck_w*blck_h); // average
}
}
}
[Solved]help my code
Hi guys,
I'm trying to compute average color values of an grayscale image blocks. My grayscale image is divided into 64 blocks(think of it like placing a 8x8 grid on the image, hence each block size is image width/8 and image height/8. Here is my source code,
But when I try it on some images that are not multiple of 8, it crashes. Can somebody explain me what I'm doing wrong ?
[Edited by - Great_White on November 21, 2008 1:17:51 AM]
This won't break on every size that's not a multiple of 8, but it will on many of them, and it'll go into infinite-loop world on sizes < 8. For instance all sizes 8-16 will work just fine. Anyway let's examine why.
Let's go through a test situation. Imagine a simple greyscale image that is 17x17. You get your blck_w and blck_h, and naturally they are both "2" (as 17/8 = 2.125 or something... in integer world that's 2).
Alright great... recap the vars:
width = 17 height = 17 blck_w = 2 blck_h = 2
Now let's look at the for loops. If you were to set a breakpoint in here, you would end up starting your "y" loop, "x" loop, "z" loop, and "w" loop, you would eventually make it through the "z" and "w" loops successfully. You would start the next "x" loop, with x = 2 now. This will go on until x == 14. We go through the "z" and "w" loops like usual, but let's zoom in and see what happens next.
The for loop says "Well, 'x' == 14. I need to add 'blck_w' to it. That's 2. Cool, so now 'x' == 16. Is that less than 'width'? 'width' is 17... sooo... yup 16 is certainly less than 17, let's move on."
And the "z" loop and "w" loop start. Since the "z" loop and "w" loop both iterate "blck_w" times, you are going past your image width and height of 17, as if it was 18x18. This is why it crashes.
Solution?
Decide what to do with the "extra" pixels when it's not evenly divisible by 8. Throw them away, or determine a way to only include what's there.
Cheers
-Scott
Let's go through a test situation. Imagine a simple greyscale image that is 17x17. You get your blck_w and blck_h, and naturally they are both "2" (as 17/8 = 2.125 or something... in integer world that's 2).
Alright great... recap the vars:
width = 17 height = 17 blck_w = 2 blck_h = 2
Now let's look at the for loops. If you were to set a breakpoint in here, you would end up starting your "y" loop, "x" loop, "z" loop, and "w" loop, you would eventually make it through the "z" and "w" loops successfully. You would start the next "x" loop, with x = 2 now. This will go on until x == 14. We go through the "z" and "w" loops like usual, but let's zoom in and see what happens next.
The for loop says "Well, 'x' == 14. I need to add 'blck_w' to it. That's 2. Cool, so now 'x' == 16. Is that less than 'width'? 'width' is 17... sooo... yup 16 is certainly less than 17, let's move on."
And the "z" loop and "w" loop start. Since the "z" loop and "w" loop both iterate "blck_w" times, you are going past your image width and height of 17, as if it was 18x18. This is why it crashes.
Solution?
Decide what to do with the "extra" pixels when it's not evenly divisible by 8. Throw them away, or determine a way to only include what's there.
Cheers
-Scott
ok discarding them is a good idea. How can I do this? BTW, my logic is correct right? I trying to copy calculated average block color values to a 8x8 array.
Here's a hint: Try iterating through each pixel of the image and finding out which cell of avgc it should go in. Also, it may be helpful to know that the average is the sum of all elements then divided by how many elements possible.
Does this give you any ideas?
Does this give you any ideas?
Oh, wait. What's this in my back pocket? Some sample code?
</inside_joke>
[Edited by - _fastcall on November 19, 2008 9:31:33 PM]
</inside_joke>
static void averageColorOf8x8_Blocks(unsigned char* img, int width, int height, /* unsigned */ long avgc[8][8]) { assert( width > 8 ); assert( height > 8 ); int block_w = width / 8; int block_h = height / 8; // I'll be assuming that argvc is initialized to 0 // Calculate the sum: int x, y; for ( y = 0; y < height; ++y ) // For each row for ( x = 0; x < width; ++x ) // For each column: avgc[y*8/height][x*8/width] += img[ width * y + x ]; // y * 8 / height is equivalent to y / (height / 8) is equivalent to y / block_h. // The difference is, is that you're operating on integer operations. // Therefore, if the height is 15 (making block_h = 15 / 8 = 1) // and y was 14, you'd be accessing avgc[15], which is not cool. // Then calculate the average: int k = block_w * block_h; for ( y = 0; y < 8; ++y ) for ( x = 0; x < 8; ++x ) avgc[y][x] /= k;}
[Edited by - _fastcall on November 19, 2008 9:31:33 PM]
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement