像素间的基本关系—邻域、邻接、通路、连通、距离

描述

像素是图像的基本元素,像素与像素之间存在着某些联系,理解像素间的基本关系是数字图像处理的基础。常见的像素间的基本关系包括:邻域、邻接、通路、连通、距离。

Part1 1. 邻域

邻域表示了像素之间的连接关系。

像素(x,y)的邻域,是指与像素(x,y)对应的点的集合{(x+p,y+q)} ,其中 (p,q) 为一对有意义的整数。邻域是像素(x,y)附近像素形成的区域,像素 (x,y) 也被称为中心像素。

最常用的邻域有以下几种:

OpenCV

OpenCV

邻域.png

邻域是一个很基础的概念。后续我们对图像进行卷积操作的时候,通常是对当前像素的邻域像素进行操作的

以一个最简单的均值滤波为例,均值滤波是对于每一个像素点, 将其设定为取其邻域窗口内的所有像素的平均值。

OpenCV

这里的模板,也可以被称为核(kernels)、窗口(windows)、掩模(mask)。

下图以 3*3 的模板为例,均值滤波会对原图像的每一个像素点,计算它的邻域像素和模版矩阵的对应元素的乘积,然后加起来,作为该像素位置的值。窗口的移动是从左到右,然后从上到下依次移动。

OpenCV卷积.png

下面,实现一个简单的均值滤波函数

 

Mat meanFilter(Mat &src, int ksize = 3)
{
    cv::Mat dst = src.clone();

    int k0 = ksize/2;
    int sum[3] = {0,0,0};
    for(int i=k0;i(i-k0+m,j-k0+n)[channel];
                    }
                }

                dst.at(i,j)[channel] = saturate_cast((float)sum[channel] /(ksize*ksize));
            }
        }
    }
    return dst;
}

 

当然这个代码只是粗略地实现均值滤波,存在着很多优化的空间,例如使用积分图、卷积核分离等。OpenCV 也提供了均值滤波函数 blur() 函数。

 

int main(int argc,char *argv[])
{
    Mat src = imread(".../flower.jpg");
    imshow("src",src);
    Mat dst;

    dst = meanFilter(src, 15);
    imshow("meanFilter",dst);

    blur(src,dst,Size(15,15));
    imshow("blur",dst);

    waitKey(0);
    return 0;
}
OpenCV

均值滤波函数效果.png

 

上面只是简单例举了领域的使用场景,后续会有专门的文章来详细介绍卷积和滤波。

Part2 2. 邻接

邻接是指两个像素,在位置上相邻并且取值相同或相近

我们用 V 表示定义邻接的灰度值集合。在二值图像中,V={1} 表示值为1的像素邻接。在灰度图像中,V 包含更多的元素。

OpenCV

像素 p 和 q 是 4 邻接,那么它们一定是 8 邻接的。反之,不一定成立。

下图反应了 8 邻接会带来二义性。

OpenCV邻接.png

从图中可以看到,p 是中心像素。

q1、q2 和 p 是 8 邻接的。

q1 和 p 非 m 邻接的。

q2 和 p 是 m 邻接的。

某条通路经过像素 q2、p、q1,那会有几种走法呢?

如果从 p、q1、q2 是 8 邻接的角度看,p 到 q1 可以有2种走法,所以 q2 到 q1 的通路有2条。

同理,从 m 邻接角度看,p 和 q1 只有1种走法,所以 q2 到 q1 的通路只有1条。

所以,m 邻接的引入是为了消除 8 邻接常常带来二义性

从集合的角度看:

Part3 3. 通路

OpenCV

由不同的邻接定义,可以得到不同的通路:4 邻接 => 4 通路,8 邻接 => 8 通路,m 邻接 => m 通路

OpenCV通路.png

所以,从中间的图可以看到 q2 和 q1 之间存在 8 通路,从最右的图可以看到 q2 和 q1 之间存在 m 通路。

从集合的角度看:

下图中,p-q 通路对应的是不同的通路。

OpenCV多种通路.png

Part4 4. 连通

OpenCV

OpenCVlineType 参数.png

下面的例子,展示了使用不同的 lineType 参数的效果

 

int main(int argc,char *argv[])
{
    Mat image = Mat::zeros(Size(80, 80), CV_8UC3);
    image.setTo(255);// 设置屏幕为白色

    Point p1(20, 0);
    Point p2(80, 60);
    Point p3(0, 0);
    Point p4(80, 80);
    Point p5(0, 20);
    Point p6(60, 80);

    line(image, p1, p2, Scalar(0, 0, 255), 1, LINE_4);
    line(image, p3, p4, Scalar(255, 0, 0), 1, LINE_8);
    line(image, p5, p6, Scalar(0, 255, 0), 1, LINE_AA);

    imshow("src", image);

    waitKey(0);
    return 0;
}

 

将生成的图片放大,可以看到使用 LINE_4、LINE_8、LINE_AA 画出来的线段效果是不同的。使用 LINE_AA 效果看上去是最好的,其次是 LINE_8。

OpenCV不同lineType参数的效果.png

通过邻接可以引申很多概念,邻接 -> 通路 -> 连通 -> 连通集 -> 区域/邻接区域 -> 前景和背景 -> 边界

Part5 5. 距离

对于像素 p(x,y)、q(s,t) 和 z(u,v),如果满足:

非负性:D(p,q) ≥ 0

同一性:D(p,q)=0,当且仅当p=q时

对称性:D(p,q) = D(q,p)

直递性:D(p,z) ≤ D(p,q) + D(q,z)

则称 D 是距离的度量函数。

OpenCV

Part6 6. 总结

本文涉及到很多概念,这些概念代表着像素间的基本关系。像邻域、连通在后续文章中很多都会涉及到,像距离又跟相似度有关,所以它们是数字图像的基础。








审核编辑:刘清

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分