Zengrui
Zengrui

Reputation: 77

Box Filtering Algorithm in C++

I am using the box filtering algorithm to do RGB image blur. But the result is really bad. I could not recognize the original image at all. The data of the image is stored in an array Data[Width*Height*3], with the order of BGRBGRBGR... And kernel is a 9x9 box.

Here is my box filtering function:

void MyImage::BoxFiltering(vector<int> kernel){
char *temp = new char[Width * Height * 3];

int denominator = 0;
int indexOffset;
int red = 0, blue = 0, green = 0;

int indices[] = {-(Width + 1), -Width, -(Width - 1),
                 - 1,          0,      1,
                 Width - 1,    Width,  Width + 1};

for(int i = 0; i < kernel.size(); ++i){
    denominator += kernel[i];
}


if(denominator == 0)
    denominator = 1;

//Copy Data
for(int i = 0; i < Width * Height * 3; ++i){
    temp[i] = Data[i];
}

for(int i = 1; i < Height - 1; ++i){
    for(int j = 1; j < Width - 1; ++j){
        //Get Pixel Index
        indexOffset = getIndex(j, i);

        for(int k = 0; k < kernel.size(); ++k){
            blue    += Data[3 * (indexOffset + indices[k])] * kernel[k];
            green   += Data[3 * (indexOffset + indices[k]) + 1] * kernel[k];
            red     += Data[3 * (indexOffset + indices[k]) + 2] * kernel[k];
        }

        temp[3 * indexOffset] = static_cast<char>(blue / denominator);
        temp[3 * indexOffset + 1] = static_cast<char>(green / denominator);
        temp[3 * indexOffset + 2] = static_cast<char>(red / denominator);
    }
}

for(int i = 0; i < Width * Height * 3; ++i){
    Data[i] = temp[i];
}

delete [] temp;
}

Could anybody help me figure out what's wrong with my implementation? Thanks!

Upvotes: 1

Views: 5109

Answers (1)

Zengrui
Zengrui

Reputation: 77

Problem Solved. I forgot to retrieve the lower 8 bits and clamp the color. Post codes here in case someone need it!

for(int i = 1; i <= Height - 1; ++i){
    for(int j = 1; j <= Width - 1; ++j){
        //Get Pixel Index
        indexOffset = getIndex(j, i);

        for(int k = 0; k < kernel.size(); ++k){

            blue    += (Data[3 * (indexOffset + indices[k])]     * kernel[k])  & 0xff;
            green   += (Data[3 * (indexOffset + indices[k]) + 1]  * kernel[k]) & 0xff;
            red     += (Data[3 * (indexOffset + indices[k]) + 2]  * kernel[k]) & 0xff;
        }

        blue    /= denominator;
        green   /= denominator;
        red     /= denominator;

        if (red>0xff) 
            red = 0xff ;
        else if (red<0) 
            red = 0 ;
        if (green>0xff) 
            green = 0xff ;
        else if (green<0) 
            green = 0 ;
        if (blue>0xff) 
            blue = 0xff ;
        else if (blue<0) 
            blue = 0 ; 


        temp[3 * indexOffset]     = static_cast<char>(blue);
        temp[3 * indexOffset + 1] = static_cast<char>(green);
        temp[3 * indexOffset + 2] = static_cast<char>(red);
    }
}

Upvotes: 1

Related Questions