# kerenl matrix problem =\

## 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 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 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 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 on other sites
Quote:
 Original post by ff8let'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 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 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 on other sites
Quote:
 Original post by ff8i 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 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 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 on other sites
Quote:
 Original post by ff8if 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 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 on other sites
anyone can give gaussian blur code ?

##### Share on other sites
The Gaussian Blur. That says everything you need to know about how to set up a kernel with gaussian elements. Code in this instance, would be pretty useless.

Thank you ^_^.

## Create an account

Register a new account

• ### Forum Statistics

• Total Topics
627708
• Total Posts
2978732

• 21
• 14
• 12
• 22
• 35