12 Replies - 1719 Views - Last Post: 17 October 2013 - 01:57 PM Rate Topic: -----

#1 johnnehh  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 13
  • Joined: 02-May 13

Help with average smoothing in c

Posted 15 October 2013 - 08:47 PM

im trying to smooth out the local variation of a grayscale image, the image is stored in an array of structs. when iterating over each pixel of the image , i need to replace the gray level of the pixel with the average of the gray levels of the neighbours and the pixel itself. so for example,
A[3[3]1 2 3 B[3][3] _ _ _
4 5 6 _ _ _
7 8 9 _ _ _
-5 has neighbours 1,2,3,4,6,7,8,9. and need to find the average of them and replace it to position B[1][1].
-1 has 2,4,5. and need to find average of them and replace it to position B[0][0].
this is wat i have atm.
 for(r=1; r<h-1; r++){
		for(c=1; c<w-1; c++){
			tot=0;
                        average=0;
                        howmany=9;
			tot=cpyimage[r-1][c-1].gray_level+cpyimage[r-1][c].gray_level+cpyimage[r-1][c+1].gray_level+cpyimage[r][c-1].gray_level+cpyimage[r][c].gray_level+cpyimage[r]    [c+1].gray_level+cpyimage[r+1][c-1].gray_level+cpyimage[r+1][c].gray_level+cpyimage[r+1][c+1].gray_level;
			average=tot/howmany;
			myimage[r][c].gray_level=average;
		}
	}

but it misses out the edges. im having trouble averaging them because they have less than 8 neighbours , unlike the ones in the middle which have 8 neighbours. how do i o about doing this? can someone help point me in the right direction?

Is This A Good Question/Topic? 0
  • +

Replies To: Help with average smoothing in c

#2 GunnerInc  Icon User is offline

  • "Hurry up and wait"
  • member icon




Reputation: 858
  • View blog
  • Posts: 2,277
  • Joined: 28-March 11

Re: Help with average smoothing in c

Posted 15 October 2013 - 08:56 PM

Quote

can someone help point me in the right direction?

I will start by moving this out of the "Site Questions & Support" forum and over to the C/C++ forum.
Was This Post Helpful? 0
  • +
  • -

#3 Adak  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 331
  • View blog
  • Posts: 1,168
  • Joined: 01-April 11

Re: Help with average smoothing in c

Posted 15 October 2013 - 11:48 PM

In your loops, make one test condition test that the index is not going past the edge.

That means, if r=current row, and c is the current column being tested, that if you are testing on row 0, then r >=0 would be a test condition, for every pixel you test, on row 0.

In addition, you have to test on the corners, to keep the c from going past the edge. c>=0 && c<COLS, where COLS is the define for the number of columns in each row.

Top row, bottom row, left column, and right column, all have to have some constraint to get everything covered with your processing, but not allow the index of r or c, to go past the edge of the array.

Another way to do it is to extend your real array, a bit larger (two rows, and two columns are usually large enough), and fill that new edge row(s) and col(s) with a unique value that will indicate "off the edge".

Then you can use that unique value for all your testing. You will run off your old array by one element, but you won't process that value, and you won't crash your program. Valid array rows will be 1 to ROWS-2 now, and columns will be 1 to COLS-2, as well.
Was This Post Helpful? 0
  • +
  • -

#4 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 3467
  • View blog
  • Posts: 10,687
  • Joined: 05-May 12

Re: Help with average smoothing in c

Posted 16 October 2013 - 05:35 AM

Ahh, but if the OP makes the array a bit larger, what values should be stuck into the border elements? Black? White?
Was This Post Helpful? 0
  • +
  • -

#5 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5777
  • View blog
  • Posts: 12,592
  • Joined: 16-October 07

Re: Help with average smoothing in c

Posted 16 October 2013 - 08:10 AM

So, you have this:
const int howmany = 9;
for(r=1; r<h-1; r++){
	for(c=1; c<w-1; c++) {
		int tot = 
			cpyimage[r-1][c-1].gray_level
			+ cpyimage[r-1][c].gray_level
			+ cpyimage[r-1][c+1].gray_level
			+ cpyimage[r][c-1].gray_level
			+ cpyimage[r][c].gray_level
			+ cpyimage[r][c+1].gray_level
			+ cpyimage[r+1][c-1].gray_level
			+ cpyimage[r+1][c].gray_level
			+ cpyimage[r+1][c+1].gray_level;
		myimage[r][c].gray_level = tot / howmany;
	}
}



So you're avoiding the edges entirely. Well, actually, not so much, since it should probably be: r<h-2.

And, thus, your howmany becomes a constant.

Your howmany should NOT be a constant. Instead:
for(c=0; c<w; c++) {
	int tot = cpyimage[r][c].gray_level;
	int howmany = 1;
	int ro, co;

	ro = r - 1; co = c - 1; if (is_valid(ro, co)) { howmany++; tot += cpyimage[ro][co].gray_level; }
	ro = r - 1; co = c; if (is_valid(ro, co)) { howmany++; tot += cpyimage[ro][co].gray_level; }
	ro = r - 1; co = c + 1; if (is_valid(ro, co)) { howmany++; tot += cpyimage[ro][co].gray_level; }
	/* ... */
	myimage[r][c].gray_level = tot / howmany;



If you would prefer to not do a check each time, then you need to deal with your separate cases separately. Specifically, each corner and each side.
Was This Post Helpful? 0
  • +
  • -

#6 Adak  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 331
  • View blog
  • Posts: 1,168
  • Joined: 01-April 11

Re: Help with average smoothing in c

Posted 16 October 2013 - 10:19 AM

Here's the same problem search problem - showing just two of the 8 directions. In this case, the search had to continue to the edge, despite the starting index for the search.

Defines for the array:
ROWS = maximum number of rows
COLS = maximum number of columns

Idea
#1: Use DIFFERENT indices for your innermost loops! Don't use r and C, because your overall search will go wacko.
Here, I'm using r1 and c1.
   for(r=0;r<ROWS;r++) {
      for(c=0;c<COLS;c++) {

         //check up to 8 directions clockwise, showing two of them

         r1=r; c1=c; i=0;  //12 o'clock
         while(r1>=0]) {
            //do your smoothing for one pixel here
            //then
            --r1;
         }
         //and reset r1 and c1, before the next check loop
           
         r1=r; c1=c; i=0;   //1:30 o'clock
         while(r1>=0 && c1<COLS]) {
            //do your smoothing for one pixel here
            --r1;
            ++c1;
         }
         //reset r1 and c1, and code the next direction loop

      }
   }   



#2:
You could make one function to handle all 8 direction checks, but I recommend doing it this way, if you are having trouble with errors.

This post has been edited by Adak: 16 October 2013 - 10:21 AM

Was This Post Helpful? 0
  • +
  • -

#7 CTphpnwb  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2890
  • View blog
  • Posts: 10,019
  • Joined: 08-August 08

Re: Help with average smoothing in c

Posted 16 October 2013 - 10:44 AM

Maybe something like this untested code:
for(row = 0; row < HEIGHT; row++) {
	startrow = row - 1;
	if(startrow < 0) startrow = 0;
	endrow = row + 1;
	if(endrow >= HEIGHT) endrow = HEIGHT - 1;
	for(col = 0; col < WIDTH; col++) {
		startcol = col -1;
		if(startcol < 0) startcol = 0;
		endcol = col+1;
		if(endcol >= WIDTH) endcol = WIDTH - 1;
		tot = 0;
		howmany = 0;
		for(subrow = startrow; subrow <= endrow; subrow++) {
			for(subcol = startcol; subcol <= endcol; subco++) {
				tot += cpyimage[subrow][subcol].gray_level;
				howmany++;
			}
		}
		myimage[row][col].gray_level = tot/howmany;
	}
}

Was This Post Helpful? 0
  • +
  • -

#8 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5777
  • View blog
  • Posts: 12,592
  • Joined: 16-October 07

Re: Help with average smoothing in c

Posted 16 October 2013 - 12:13 PM

Aw, hell. If it's throw out answer time. :P

for(c=0; c<w; c++) {
	int ro, co, tot = 0, howmany = 0;
	for(ro=r-1; ro<=r+1; ro++) {
		if (ro>=0 && ro<h) {
			for(co=c-1; co<=c+1; co++) {
				if (co>=0 && co<h) {
					tot += cpyimage[ro][co].gray_level;
					howmany++; 
				}
			}
		}
	}
	myimage[r][c].gray_level = tot / howmany;
}



I think this eliminates the most checks while maintaining the most simplicity.
Was This Post Helpful? 0
  • +
  • -

#9 CTphpnwb  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2890
  • View blog
  • Posts: 10,019
  • Joined: 08-August 08

Re: Help with average smoothing in c

Posted 17 October 2013 - 06:25 AM

I think you're missing a loop: r

I also don't think that would average the edges.
Was This Post Helpful? 0
  • +
  • -

#10 CTphpnwb  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2890
  • View blog
  • Posts: 10,019
  • Joined: 08-August 08

Re: Help with average smoothing in c

Posted 17 October 2013 - 07:19 AM

One more thing:

I don't think you really want a simple average of a point and the points around it. I'd think that you'd want some sort of weighted average that gave a heavy weight to the point itself and the same lower weight for all the points around it.
Was This Post Helpful? 0
  • +
  • -

#11 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5777
  • View blog
  • Posts: 12,592
  • Joined: 16-October 07

Re: Help with average smoothing in c

Posted 17 October 2013 - 12:43 PM

View PostCTphpnwb, on 17 October 2013 - 10:19 AM, said:

I don't think you really want a simple average of a point


Don't know. You made me curious enough, so I ran a test.

Code used to generate
Spoiler

Attached image(s)

  • Attached Image

This post has been edited by baavgai: 17 October 2013 - 12:44 PM

Was This Post Helpful? 0
  • +
  • -

#12 CTphpnwb  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2890
  • View blog
  • Posts: 10,019
  • Joined: 08-August 08

Re: Help with average smoothing in c

Posted 17 October 2013 - 01:32 PM

Well, I suppose the results are in the eye of the beholder and also dependent on the image being processed. I was just thinking that high contrast images with horizontal and vertical segments might appear fuzzier than you'd like. To my eye that appears to be the case in the smoothed image but I guess if the resolution is high enough it won't matter.
Was This Post Helpful? 0
  • +
  • -

#13 snoopy11  Icon User is offline

  • Engineering ● Software
  • member icon

Reputation: 762
  • View blog
  • Posts: 2,218
  • Joined: 20-March 10

Re: Help with average smoothing in c

Posted 17 October 2013 - 01:57 PM

What baavgai has implemented is called a Median Filter in image processing.

Which is fine for image smoothing.

What CTphpnweb is describing is called a Kuwahara Filter in image processing.

Which again is fine for image smoothing.

So you are both right.

The difference between the two algorithmns is the Kuwahara filter smooths the image
without altering the sharpness of the image. You will note that using a Median Filter generally leads
to a less sharp image.

But well done to both especially to baavgai image processing can be difficult.

Snoopy.
Was This Post Helpful? 3
  • +
  • -

Page 1 of 1