2
votes

I'm writing a Gaussian Blur filter with 3x3 matrix(kernel) and using QImage as external library. The kernel is calculated as it has to be. After kernel is initialized and calculated I bring the unsigned int Matrix into the program:

typedef std::vector<std::vector<unsigned int> > uintMatrix; // For copying pixels value

In the main.cpp it's initialized like:

uintMatrix tmpPxMat(image.width(); std::vector<unsigned int> (image.height(), 0));

I use it as a temporary storage for blurred pixels values.

Then, I use my algorithm to blur the image:

// Blur Pixels
for(int x = 0; x < image.width(); x++)
    for(int y = 0; y < image.height(); y++) {
        // To avoid edge cases don't process them, I'll fix it soon
        if(x == 0 || x == image.height()-1 || y == 0 || y == image.width()-1)
            continue;
        // 3x3 Matrix
        tmpPxMat[x][y] += kernel[0][0] * image.pixel(x-1, y-1) +
                          kernel[0][1] * image.pixel(x, y-1) +
                          kernel[0][2] * image.pixel(x+1, y-1);

        tmpPxMat[x][y] += kernel[1][0] * image.pixel(x-1, y) +
                          kernel[1][1] * image.pixel(x, y) +
                          kernel[1][2] * image.pixel(x+1, y);

        tmpPxMat[x][y] += kernel[2][0] * image.pixel(x-1, y+1) +
                          kernel[2][1] * image.pixel(x, y+1) +
                          kernel[2][2] * image.pixel(x+1, y+1);
    }

Then, I copy the result of tmpPxMat[][] to the origin image:

// Copy blurred values to the image
for(int x = 0; x < image.width(); x++)
        for(int y = 0; y < image.height(); y++)
            image.setPixel(x, y, tmpPxMat[x][y]);

And save it:

image.save("/home/john/Pictures/blurred", "PNG", 100);

But at the end I get not the result I was waiting for. Here what I get:

Before / After:

Origin/Blurred

Sorry for the long question description, but I compressed it as much as I could.

1
Are you sure there is no problem with casting? Gaussian kernel should be a float matrix, the result of your convolution being a float saved as an int.Miki
How are the colors of the image represented in the texture?jaggedSpire
Your output image is coloured, yet your processing doesn't seem to be processing three channels of colour data (RGB) so are you using greyscale processing on colour images?Mark Setchell
@Miki, my kernel is float matrix, but temporary storage is not. I've changed it to float as needed, but at the end - I use setPixel() function, which accepts uint, I can avoid casting when calculate values, but can't when setting these values to the pixel. The casting should be very small, can it damage picture so hard?pushandpop
It was just a guess.. probably wrong! @MarkSetchell question seems more appropriateMiki

1 Answers

3
votes

I assume uintMatrix is a two-dimensional array of 32-bit ints, and that you've packed the red, green, and blue channels into that.

If so, that's your problem. You need to blur each channel independently.