OpenCV2 图像处理与计算机视觉(一)—— 去除一幅二值化图像中的椒盐噪声

通过 imgproc.hpp 文件中的 threshold 函数我们可得一幅二值化图像(或者叫 mask 掩码图像),所谓一幅二值化图像中的椒盐噪声,即为在一个 image patch 中,如果某一点的像素值为 0(也即黑色),而其 5*5 的邻域内均是255(白色),我们就可简单地将这个黑色孤点视为椒盐噪声。

去除一幅二值化图像中的椒盐噪声的关键就在于寻找这样的一些黑色孤点:

void removePepperNoise(Mat& mask)
{
    for (int y = 2; y < mask.rows-2; ++y)
    {
        uchar *pThis = mask.ptr(y);
        uchar *pUp1 = mask.ptr(y - 1);
        uchar *pUp2 = mask.ptr(y - 2);
        uchar *pDown1 = mask.ptr(y + 1);
        uchar *pDown2 = mask.ptr(y + 2);

        pThis += 2; pUp1 += 2; pUp2 += 2; pDown1 += 2; pDown2 += 2;

        int x = 2;
        while( x < mask.cols - 2)
        {
            uchar v = *pThis;
            // 当前点为黑色
            if (v == 0)
            {
                // 5 * 5 邻域的外层
                bool allAbove = *(pUp2 - 2) && *(pUp2 - 1) && *(pUp2) && *(pUp2 + 1) && *(pUp2 + 2);
                bool allBelow = *(pDown2 - 2) && *(pDown2 - 1) && *(pDown2) && *(pDown2 + 1) && *(pDown2 + 2);
                bool allLeft = *(pUp1 - 2) && *(pThis - 2) && *(pDown1 - 2);
                bool allRight = *(pUp1 + 2) && *(pThis + 2) && *(pDown1 + 2);
                bool surroundings = allAbove && allBelow && allLeft && allRight;

                if (surroundings)
                {
                    // 5*5 邻域的内层(3*3的小邻域)
                    *(pUp1 - 1) = *(pUp1) = *(pUp1+1) = 255;
                    *(pThis - 1) = *pThis = *(pThis + 1) = 255;
                    *(pDown1 - 1) = *pDown1 = *(pDown1 + 1) = 255;
                    //(*pThis) = ~(*pThis);
                                            // 0 ⇒ 255
                }
                pUp2 += 2; pUp1 += 2; pThis += 2; pDown1 += 2; pDown2 += 2;
                x += 2;
            }
            ++pThis; ++pUp2; ++pUp1; ++pDown1; ++pDown2; ++x;
        }
    }
}

你可能感兴趣的:(OpenCV2 图像处理与计算机视觉(一)—— 去除一幅二值化图像中的椒盐噪声)