I am trying to blur an image without using opencv predefined functions like blur(). I am using standard average and not the weighted average. here is my code but the result is still the same with the input image. this is for 3x3.

    IplImage* img = cvLoadImage(argv[1]);
    IplImage* dst = cvCloneImage(img);

    height = img->height;
    width = img->width;
    step = img->widthStep;
    channels = img->nChannels;
    data = (uchar *)img->imageData;

    height2    = dst->height; // row
    width2     = dst->width; // col
    step2      = dst->widthStep; // size of aligned image row in bytes
    channels2  = dst->nChannels; 
    dstData      = (uchar *)dst->imageData;
    int total = 0;

    //blur
    for (i = 0; i < height; i++) {
        for (j = 0; j < width; j++) {          
           for (x = 0; x <= 2; x++)
                for (y = 0; y <= 2; y++)
                    total =(data[x-1,y-1]+data[x-1,y]+data[x-1,y+1]+
                            data[x,y-1]+data[x,y]+data[x,y+1]+
                            data[x+1,y-1]+data[x+1,y]+data[x+1,y+1])/9;
                    dstData[i,j] = total;
                    }
            }

i think my problem is on this one

                       total =(data[x-1,y-1]+data[x-1,y]+data[x-1,y+1]+
                       data[x,y-1]+data[x,y]+data[x,y+1]+
                       data[x+1,y-1]+data[x+1,y]+data[x+1,y+1])/9;
                       dstData[i,j] = total;

what could be done?

有帮助吗?

解决方案

a complete program that shows how to do it. you have several errors, 1) incorrect pixel access(http://www.comp.leeds.ac.uk/vision/opencv/iplimage.html). 2) blur loop is wrong,you are always getting data from top left 3x3 corner. if pixel access is correct, you should get a constant image in dst.

another thing is you would also need to take care of channel information, the program bypass that by reading in a single channel image. otherwise you would need to do the blur for each channel

#include <opencv2/opencv.hpp>


int main(int argc, char* argv[])
{

    IplImage* img = cvLoadImage("c:/data/2.jpg",0);
    IplImage* dst = cvCloneImage(img);
    int height,width,step,channels;
    int height2,width2,step2,channels2;

    height = img->height;
    width = img->width;
    step = img->widthStep;
    channels = img->nChannels;
    uchar* data = (uchar *)img->imageData;

    height2    = dst->height; // row
    width2     = dst->width; // col
    step2      = dst->widthStep; // size of aligned image row in bytes
    channels2  = dst->nChannels; 
    uchar* dstData      = (uchar *)dst->imageData;
    int total = 0;
    int i,j,x,y,tx,ty;
    //blur
    for (i = 0; i < height; i++) {
        for (j = 0; j < width; j++) {   
            int ksize=3;
            total=0;
            for (x = -ksize/2; x <=ksize/2; x++)
                for (y = -ksize/2; y <=ksize/2; y++)
                {
                    tx=i+x;
                    ty=j+y;
                    if(tx>=0&&tx<height && ty>=0 && ty<width)
                    {
                        total+=data[tx*step+ty];
                    }
                }

            dstData[i*step+j] = total/ksize/ksize;
        }
    }
    cvShowImage("img",img);
    cvShowImage("dst",dst);
    cvWaitKey(0);
}

其他提示

Assume assigning 0 to pixels out of range, the following code should be what you want. The core is my_averagefunction, it computes the average of the 3 * 3 window centered at i and j.

for (i = 0; i < height; i++)
     for (j=0; j < width; j++)
         dstData[i*width+j] = my_average(data, i, j, height, width);

double my_average(uchar * data, int y, int x, int height, int width) {
    double sum = 0;
    if(x-1 >= 0 && y-1 >= 0) {
        sum += data[(y-1)*width + x-1];
    }
    if(x-1 >= 0) {
        sum += data[y*width + x-1];
    }
    if(x-1 >= 0 && y+1 < height) {
        sum += data[(y+1)*width + x-1];
    }
    if(y-1 >= 0) {
        sum += data[(y-1)*width + x];
    }
    sum += data[y*width + x];
    if(y+1 < height) {
        sum += data[(y+1)*width + x];
    }
    if(x+1 < width && y-1 >= 0) {
        sum += data[(y-1)*width + x+1];
    }
    if(x+1 < width) {
        sum += data[y*width + x+1];
    }
    if(x+1 < width && y+1 < height) {
        sum += data[(y+1)*width + x+1];
    }

    return sum/9;
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top