拉普拉斯算子不能提供所需的输出

时间:2011-10-27 17:35:22

标签: c++ image-processing opencv

这是我的代码:

    int Factor=3,offset=0,k,l,p,q;
    IplImage * image = cvCreateImage(cvSize(img->width, img->height),img->depth, img->nChannels);
     cvCopy (img, image, 0);
    long double mean=0,nTemp=0,c,sum=0,n=0,s=0,d=0;
    int i=0,j=0,krow,kcol;
    kernel[0][0]=kernel[0][2]=kernel[2][0]=kernel[2][2]=0;
    kernel[0][1]=kernel[1][0]=kernel[1][2]=kernel[2][1]=1;
    kernel[1][1]=-4;
    uchar* temp_ptr=0 ;
    int rows=image->height,cols=image->width,row,col;

     //calculate the mean of image and deviation 

    for ( row = 1; row < rows - 2; row++ )
    {
        for ( col = 1; col < cols - 2; col++ )
        {
            nTemp = 0.0;
                for (p=0, krow = -1 ; p < 3; krow++,p++)
                {
                    for (q=0, kcol = -1; q < 3; kcol++,q++)
                    {   
                        temp_ptr  = &((uchar*)(image->imageData + (image->widthStep*(row+krow))))[(col+kcol)*3];
                        for(int k=0; k < 3; k++)
                        Pixel[p][q].val[k]=temp_ptr[k];
                    }
                }
                for (i=0 ; i < 3; i++)
                {
                    for (j=0 ; j < 3; j++)
                    {
                        c = (Pixel[i][j].val[0]+Pixel[i][j].val[1]+Pixel[i][j].val[2])/Factor ;
                        nTemp += (double)c * kernel[i][j];
                    }
                }

            sum += nTemp;
            n++;
        }
    }
mean = ((double)sum / n);
    for ( row = 1; row < rows - 2; row++ )
    {
        for ( col = 1; col < cols - 2; col++ )
        {
            nTemp = 0.0;

                for (p=0, krow = -1 ; p < 3; krow++,p++)
                {
                    for (q=0, kcol = -1; q < 3; kcol++,q++)
                    {   
                        temp_ptr  = &((uchar*)(image->imageData + (image->widthStep*(row+krow))))[(col+kcol)*3];
                        for(int k=0; k < 3; k++)
                        Pixel[p][q].val[k]=temp_ptr[k];
                    }
                }
                for (i=0 ; i < 3; i++)
                {
                    for (j=0 ; j < 3; j++)
                    {
                        c = (Pixel[i][j].val[0]+Pixel[i][j].val[1]+Pixel[i][j].val[2])/Factor ;
                        nTemp += (double)c * kernel[i][j];
                    }
                }

            s = (mean - nTemp);
            d += (s * s);
        }
    }
    d = d / (n - 1);
    d = (sqrt(d));
    d=d* 2;
     // Write to image
    for ( row = 1; row < rows - 2; row++ )
    {
        for ( col = 1; col < cols - 2; col++ )
        {   
                nTemp = 0.0;
                for (p=0, krow = -1 ; p < 3; krow++,p++)
                {
                    for (q=0, kcol = -1; q < 3; kcol++,q++)
                    {   
                        temp_ptr  = &((uchar*)(image->imageData + (image->widthStep*(row+krow))))[(col+kcol)*3];
                        for(int k=0; k < 3; k++)
                        Pixel[p][q].val[k]=temp_ptr[k];
                    }
                }
                for (i=0 ; i < 3; i++)
                {
                    for (j=0 ; j < 3; j++)
                    {
                        c = (Pixel[i][j].val[0]+Pixel[i][j].val[1]+Pixel[i][j].val[2])/Factor ;
                        nTemp += (double)c * kernel[i][j];
                    }
                }
            temp_ptr  = &((uchar*)(image->imageData + (image->widthStep*row)))[col*3];
            if (nTemp > d)
                temp_ptr[0]=temp_ptr[1]=temp_ptr[2]=255;
            else
                temp_ptr[0]=temp_ptr[1]=temp_ptr[2]=0;
        }
    }

我哪里错了?我以类似的方式实现了高斯滤波,我的算法有什么问题吗?

2 个答案:

答案 0 :(得分:1)

似乎您的代码(标记为“写入图像”)会在计算过程中覆盖输入图像。这个不好。创建图像副本,计算其像素,然后删除原始图像。

答案 1 :(得分:1)

我注意到你的代码是不必要的复杂和低效的。在计算平均值之前,您不需要对图像进行卷积 - 卷积只是将平均值乘以内核条目的总和。

此外,由于你的卷积核总和为零,你在卷积后得到的平均值也(几乎)为零。唯一的非零贡献将来自图像的边缘。我很怀疑这实际上是你想要计算的(如果是这样的话,你可以通过仅在第一个边缘上求和来节省大量时间。)

第三,as pointed out in another answer(我自己错过了这个),你没有对所有颜色通道进行平均,你在红色通道上平均三次。(另外,你可能应该use a weighted average anyway, after applying gamma correction。)

最后,as anatolyg said,您在完成阅读之前会覆盖图像数据。有几种方法可以解决这个问题,但最简单的方法是将输出写入单独的缓冲区。