# [Solved]help my code

This topic is 3676 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

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,

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
}
}
}


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]

##### Share on other sites
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

##### Share on other sites
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.

##### Share on other sites
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?

##### Share on other sites
a code sample will be better for me to understand

##### Share on other sites
Oh, wait. What's this in my back pocket? Some sample code?
</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]

##### Share on other sites
Thanks for the sample code. But it does not give the correct results, I checked with Matlab. I think my for logic is not correct.

1. 1
2. 2
Rutin
16
3. 3
4. 4
5. 5

• 26
• 11
• 9
• 9
• 11
• ### Forum Statistics

• Total Topics
633709
• Total Posts
3013478
×