Jump to content
  • Advertisement
Sign in to follow this  
ff8

kerenl matrix problem =\

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello everyone , i am tring to make some image's filtering effects on 1byte datatype 0-255 i tried many filers but i get weird effects most of time i get colored-nosie all over the image i tried mean filtering it worked just this filter only =\ can anyone check my code and tell me what is the problem ...
struct Pixel{
	unsigned char r,g,b;
};
float kernel[9]={-1,-1,-1,
			     -1,+9,-1,
			     -1,-1,-1};
unsigned char FtoC(float a,unsigned char b){
	return (unsigned char)((b*a>255)?255:(a*b));
}
void Filter(Pixel *image,int x,int y){
	for(int i=1;i<y;i++){
		for(int j=1;j<x;j++){
			image[MAP(j,i,x)].r=FtoC(kernel[0],image[MAP(j-1,i+1,x)].r)+FtoC(kernel[1],image[MAP(j,i+1,x)].r)+FtoC(kernel[2],image[MAP(j+1,i+1,x)].r)+
								FtoC(kernel[3],image[MAP(j-1,i,x)].r)	 +FtoC(kernel[4],image[MAP(j,i,x)].r)  +FtoC(kernel[5],image[MAP(j+1,i,x)].r)  +
								FtoC(kernel[6],image[MAP(j-1,i-1,x)].r)+FtoC(kernel[7],image[MAP(j,i-1,x)].r)+FtoC(kernel[8],image[MAP(j+1,i-1,x)].r);

			image[MAP(j,i,x)].g=FtoC(kernel[0],image[MAP(j-1,i+1,x)].g)+FtoC(kernel[1],image[MAP(j,i+1,x)].g)+FtoC(kernel[2],image[MAP(j+1,i+1,x)].g)+
								FtoC(kernel[3],image[MAP(j-1,i,x)].g)	 +FtoC(kernel[4],image[MAP(j,i,x)].g)  +FtoC(kernel[5],image[MAP(j+1,i,x)].g)  +
								FtoC(kernel[6],image[MAP(j-1,i-1,x)].g)+FtoC(kernel[7],image[MAP(j,i-1,x)].g)+FtoC(kernel[8],image[MAP(j+1,i-1,x)].g);

			image[MAP(j,i,x)].b=FtoC(kernel[0],image[MAP(j-1,i+1,x)].b)+FtoC(kernel[1],image[MAP(j,i+1,x)].b)+FtoC(kernel[2],image[MAP(j+1,i+1,x)].b)+
								FtoC(kernel[3],image[MAP(j-1,i,x)].b)	 +FtoC(kernel[4],image[MAP(j,i,x)].b)  +FtoC(kernel[5],image[MAP(j+1,i,x)].b)  +
								FtoC(kernel[6],image[MAP(j-1,i-1,x)].b)+FtoC(kernel[7],image[MAP(j,i-1,x)].b)+FtoC(kernel[8],image[MAP(j+1,i-1,x)].b);
		}
	}
}

thank you . cya,

Share this post


Link to post
Share on other sites
Advertisement
You should FIRST compute the sum kernel[k]*pixel_value[k] and THEN map to char.
The 5th filter element has a value of +9. If you multiply - say - 50 by 9 and clip it,
you get completely wrong results. That's why you get colored noise. First compute the sum,
then clip to char.

Share this post


Link to post
Share on other sites
Your kernel is a derivative-like filter. First, you need to kernel values to sum to 0. The kernel[4] value should be "8", not "9". Second, you should ensure that the absolute values of the kernel values sum to 1. So multiply all your kernel[] values by 1/16 = 0.0625.

Share this post


Link to post
Share on other sites
thank you.
i have another question :
let's say i want make blurring effect what is the kernel matrix for it and what do i need to change ?
@Wasting Time :
what do u mean by "absolute values of the kernel"?

thanks again ^^.

Share this post


Link to post
Share on other sites
Quote:
Original post by ff8
let's say i want make blurring effect what is the kernel matrix for it and what do i need to change ?


There are infinitely many choices for a 3x3 blur-like kernel. Generally, you want some reasonable constraints:
1. symmetric:
kernel[0] = kernel[2] = kernel[6] = kernel[8]
kernel[1] = kernel[3] = kernel[5] = kernel[7]

2. nonnegativity: kernel >= 0 for all i

3. influence of pixels decreases with distance:
kernel[4] >= kernel[1] >= kernel[0]

4. energy preserving:
kernel[0] + kernel[1] + ... + kernel[8] = 1

You also have to decide how to handle boundary pixels (clamp? repeat? mirrored-repeat? wrap? ...)

Quote:

what do u mean by "absolute values of the kernel"?


I meant:
|kernel[0]| + |kernel[1]| + ... + |kernel[8]| = 1

Share this post


Link to post
Share on other sites
thank you again ^^.
ok let's say i want to try symmetric kernel for blur filter what about the kernel elements' values is there any rule for them or just pick them randomly ?

Share this post


Link to post
Share on other sites
Hello again ,
ok i tried this matrix :

float kernel[9]={0.0625,0.1,0.0625,
0.1,0,0.1,
0.0625,0.1,0.0625};


i got smooth effect not blured and the image was kinda dark
so i am not sure how can i select the kernel values is there anything to do w/ these values like rules for picking them ?
thanks again .
cya,

Share this post


Link to post
Share on other sites
Quote:
Original post by ff8
i got smooth effect not blured and the image was kinda dark


Are you paying attention to what I posted?

Your example violates two of the constraints I mentioned. First, you have kernel[4] = 0, which violates Constraint 3 (influence of pixels decreases with distance). When you compute a weighted average at a pixel, you invariably want to assign that pixel the *largest* weight. Second, the sum of your kernel values is 0.65, not 1, which violates Constraint 4 (energy preserving). The fact that the sum is less than 1 guarantees that the blurred image will be darker.

Try, for example, kernel[0..8] = (1/28)*{1,4,1,4,8,4,1,4,1}.

Share this post


Link to post
Share on other sites
Assigning the elements based on the value of a gaussian function is used rather often, and produces nice results.

What exactly do you want to do anyway? As in, what's this for?

Share this post


Link to post
Share on other sites
thank you again ^^ ,
i am really sorry about the missunderstanding =if i want to control the blur what do i need to do ? increase the kernel matrix or is there anothere way ?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!