c++ - 实现拉普拉斯 3x3

标签 c++ image-processing wxwidgets

我正在阅读 Gonzalez 和 Woods 的 DIP 第 2 版,并尝试使用 wxImage 用拉普拉斯掩码(第 129 和 130 页)弄脏我的手。

float kernel [3][3]= {{1, 1, 1},{1,-8, 1},{1, 1, 1}};   

这是处理循环:

unsigned char r,g,b;                    

float rtotal, gtotal, btotal; rtotal = gtotal = btotal = 0.0;   
//ignore the border pixel              

for(int i = 1; i<imgWidth-1; i++)
{

   for(int j = 1; j<imgHeight-1; j++) 
    {

     rtotal = gtotal=btotal =0.0;


       for(int y = -1; y<=1;y++)

       {

            for(int x = -1; x<=1;x++)

            {

            // get each channel pixel value

            r = Image->GetRed(i+y,j+x);

            g = Image->GetGreen(i+y,j+x);

            b = Image->GetBlue(i+y,j+x);

            // calculate each channel surrouding neighbour pixel value base   

            rtotal += r* kernel[y+1][x+1];

            gtotal += g* kernel[y+1][x+1] ;

            btotal += b* kernel[y+1][x+1];

            }

    }
            //edit1: here is how to sharpen the image
            // original pixel - (0.2 * the sum of pixel neighbour)
            rtotal = loadedImage->GetRed(x,y) - 0.2*rtotal;

    gtotal = loadedImage->GetGreen(x,y) - 0.2*gtotal;

    btotal = loadedImage->GetBlue(x,y) - 0.2*btotal;
    // range checking

    if (rtotal >255) rtotal = 255;

       else if (rtotal <0) rtotal = 0;

    if(btotal>255) btotal = 255;

       else if(btotal < 0) btotal = 0;

    if(gtotal > 255) gtotal = 255;

       else if (gtotal < 0 ) gtotal =0;

    // commit new pixel value

    Image->SetRGB(i,j, rtotal, gtotal, btotal);

我将其应用于北极图片(灰色图像),但我得到的只是一团黑白像素!

有什么想法我可能在 for 循环中遗漏了什么吗?

Edit1:在谷歌上四处寻找后终于得到了答案。这个dsp的东西绝对是棘手的!我添加到上面的代码中,它会锐化图像。

干杯

最佳答案

首先,与拉普拉斯算子卷积的结果可能有负值。考虑一个值为 1 并被 0 包围的像素。该像素处的卷积结果将为 -8。

其次,结果的范围将在 [-8 * 255, 8 * 255] 之间,这肯定不适合 8 位。本质上,当您进行范围检查时,您会丢失大部分信息,并且大多数结果像素最终将变为 0 或 255。

您需要做的是将结果存储在一个类型的数组中,该数组具有符号且宽度足以处理范围。然后,如果您希望输出 8 位图像,则需要重新缩放值,以便 -8 * 255 映射到 0,8 * 255 映射到 255。或者您可以重新缩放它,以便最小值映射到0,最大值映射到 255。

编辑:在这种特定情况下,您可以执行以下操作:

rtotal = (rtotal + 8 * 255) / (16 * 255) * 255;

简化为

rtotal = (rtotal + 8 * 255) / 16;

这会将 rtotal 映射到 0 到 255 之间的范围内而不截断。您应该对 gtotalbtotal 执行相同的操作。

关于c++ - 实现拉普拉斯 3x3,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7449596/

相关文章:

c++ - 在特定对象上调用的成员函数上设置断点

c++ - 如何判断一个 vector 是否有一定数量的元素C++

matlab - matlab中的图像标记和寻找质心

ios - iOS 中的稀疏图像匹配

python - OpenCV HOGDescripter Python

c++ - wxColour 设置为 int 数组?

c++ - 在事件上使用 "Dispatch"函数的原因是什么?

c++ - LLVM/Clang 是否支持弱链接的 'weak' 属性?

python - wxPython,改变 StyledTextCtrl 的背景颜色

xcode - 如何使用 wxWidgets 在 Xcode 7 上创建项目?