Sign in to follow this  

kerenl matrix problem =\

This topic is 4159 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
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[i] >= 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
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
Quote:
Original post by ff8
if i want to control the blur what do i need to do ? increase the kernel matrix or is there anothere way ?


You can do either. If you increase the kernel matrix size, then you spend more cycles applying the "convolution" with the image. This takes you into the realm of "fast Fourier transforms", which allow you to take advantage of the structure of the convolution to speed up the computation.

Alternatively, you can iterate using a 3x3 kernel. Sparing you all the details, let B(x,y,t) be the blurred image at "time" t. The original image is B(x,y,0). The iteration is

B(x,y,t+k) = (1-4*k/(h*h))*B(x,y,t) + (k/h*h)*(B(x+h,y,t) + B(x-h,y,t) + B(x,y+h,t) + B(x,y-h,t))

where k is the increase in time and h is a change in spatial position. For an image, you think of h = 1. The "energy preserving" constraint and wanting the pixel (x,y) to influence the result requires that 1-4*k/(h*h) > 0. For h = 1, you need to choose k < 1/4. The value k = 1/8 is reasonable. (This condition on k is a "conditional stability" condition, if you know some numerical analysis.)

In terms of your original code, when h = 1 and k = 1/8, you set kernel[4] = 1/2, kernel[0] = kernel[2] = kernel[6] = kernel[8] = 0, and kernel[1] = kernel[3] = kernel[5] = kernel[7] = 1/8.

Generate the blurred image from the original. Then make the blurred image your original and repeat the algorithm. The larger the number of iterations, the greater the blur.

[The iterative algorithm is a numerical implementation of the linear heat equation, which is equivalent to convolving the input image with a Gaussian kernel. The Gaussian scale is s and is related to t by t = 2*s*s.]

Share this post


Link to post
Share on other sites
so increasing the kernal will slow it but when i repeat the 3x3 kernel
on the blurred image that came from last loop wouldn't this
will be slower ?(i hope this is what u meant)
can u post code for that if u don't mind . so i make sure from this matter
cya^^,

Share this post


Link to post
Share on other sites

This topic is 4159 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this