通过标准平均c ++模糊图像

时间:2014-01-08 15:17:38

标签: c++ opencv blur

我试图在不使用opencv预定义函数(如blur())的情况下模糊图像。我使用的是标准平均值而不是加权平均值。这是我的代码,但输入图像的结果仍然相同。这是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;
                    }
            }

我认为我的问题出在这个问题上

                       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;

可以做些什么?

2 个答案:

答案 0 :(得分:1)

一个完整的程序,展示了如何做到这一点。你有几个错误,1)不正确的像素访问(http://www.comp.leeds.ac.uk/vision/opencv/iplimage.html)。 2)模糊循环错误,你总是从左上角3x3角获取数据。如果像素访问是正确的,你应该在dst中获得一个恒定的图像。

另一件事是你还需要处理频道信息,程序绕过通过读取单个频道图像。否则你需要为每个频道进行模糊

#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);
}

答案 1 :(得分:0)

假设将0分配给超出范围的像素,以下代码应该是您想要的。核心是my_average函数,它计算以ij为中心的3 * 3窗口的平均值。

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;
}