I'm trying to do a simple smoothing filter for my image using
and I have my expected result using OpenCV Blur
void blur()
{
blur(image1, image2, cv::Size(3, 3));
imshow("Orginal", image1);
imshow("Filtered", image2);
waitKey(0);
}
I have also read up some details from OpenCV: Understanding Kernel
but I want to learn how to do the filter without using OpenCV features but i'm having some problem understanding convolving an image with some kernel
From https://en.wikipedia.org/wiki/Kernel_(image_processing)
I tried using my best of knowledge of what I understand so far and Here's my code(" 3x3 matrix ) but theres error at accumulator = image1.at<Vec3b>(x, y) * kernelarray[x + k][y + l];
Mat image1 = imread("Balloon.jpg", CV_LOAD_IMAGE_ANYCOLOR);
void filter(Mat image1)
{
const int kernelWidth = 3;
const int kernelHeight = 3;
float kernelarray[kernelWidth][kernelHeight];
int accumulator;
for (int x = 0;x < image1.rows;x++)
for (int y = 0; y < image1.cols;y++) {
accumulator = 0;
for (int k = 0;k < 3;k++)
{
for (int l = 0;l < 3;l++)
{
accumulator = image1.at<Vec3b>(x, y) * kernelarray[x + k][y + l];
}
image1.at<Vec3b>(x, y) = accumulator;
}
}
}
What should I do for me to get the expected result that I wanted?
Convolution in images is an operation where a pixel color is changed depending on the colors of the neighbors of that pixel. Each pixel (apart from image edges) has 8 neighbors. If you put the pixel and its neighbors in a matrix, the pixel is centered and neighbors around.
What you do is set a 'weight' (as in weighted average) for each neighbor. Then you just add the result of multiplying each neighbor by its weight. The center pixel can also have its own weight. This is a total 9 multiplications and sums. You assign the result (after cropping into 0-maxColor range) to the center pixel.
When you want to do this convolution for all pixels in the image, normally you want to use the same weights. This 9 weights group is called "kernel". Different kernels produce different results.
If you write the weights in a matrix you get two matrices: pixel and its neighbors, weights for all of them. But this is just a representation. No matrix operation is involved here.
You can use not only 8 neighbors, but perhaps 22... and then you need 23 weights.
In your code, kernelarray is not filled with weights.
Ah, solved it with
for (int y = 1; y < src.rows - 1; y++) {
for (int x = 1; x < src.cols - 1; x++) {
sum = 0.0;
for (int k = -1; k <= 1;k++) {
for (int j = -1; j <= 1; j++) {
sum = sum + Kernel[j + 1][k + 1] * src.at<uchar>(y - j, x - k);
apparently its easier to smooth it with grayscale than with color
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.