2018-02-08 20:01:33 huayunhualuo 阅读数 3637

图像分析的数据结构

1 图像数据表示的层次

四个层次

  1. 图标图像(iconic images):最底层的表示,有含有原始数据的图像组成,原始数据也就是像素亮度数据的整数矩阵。为了突出对后续处理重要 的图像的某些方面,需要进行预处理(滤波或边缘锐化)
  2. 分割图像(segmented images):为可能属于同一物体的区域。
  3. 几何表示(geometric representation):保存2D和3D形状知识。
  4. 关系模型(relational models):使我们能更有效地,并且在更高的抽象层次上的处理数据。

2 传统图像数据结构

矩阵,链,图,物体属性表,关系数据库

2.1 矩阵

矩阵是底层图像表示的最普通的数据结构,矩阵元素是整型的数值。

特殊图像

  • 二值图像(binary image):仅有两个亮度级别的图像,用仅含有0和1的矩阵来表示
  • 多光谱图像(multispectral image):可以用多个矩阵来表示,每个矩阵含有一个频带的图像。
  • 分层图像数据结构(bierarchical image data structures):用不同的分辨率的矩阵来获得。

共生矩阵(co-occurrence matrix)

​ 它是亮度为z的像素(i1,j1)和亮度为y的像素(i2,j2)的具有空间关系的两个像素的概率估计。

​ 假设这个概率仅依赖于亮度z的像素和亮度y的像素之间的某个空间关系r,那么关于关系r的信息就记录在方形的共生矩阵C中,它的维数对应图像的亮度级别数。

算法:关系r的共生矩阵Cr(x,y)

  1. Cr(z,y)=0,对于所有的z,y[0,L],L是最大的亮度。
  2. 对于图像中所有的像素(i1,j1) ,找到与像素(i1,j1)有关系r的像素(i2j2),做Cr[f(i1,j1),f(i2,j2)]=Cr[f(i1,j1),f(i2,j2)]+1.

积分图像

​ 描述全局信息的矩阵表示方法。积分图像的构造方式是位置(i,j)处的值ii(i,j)是原图像的(i,j)左上角所有像素的和:ii(i,j)=ki,ljf(k,l)

算法:积分图像的构建

  1. s(i,j)表示行方向的累加和,初始化s(i,1)=0

  2. ii(i,j)表示一个积分图像,初始化ii(1,i)=0

  3. 逐行扫描图像,递归计算每个像素(i,j)行方向的累加和s(i,j)和积分图像ii(i,j)的值

    s(i,j)=s(i,j1)+f(i,j)

    ii(i,j)=ii(i1,j)+s(i,j)

  4. 扫描图像一遍,当到达图像右下角像素时,积分图像ii构造好了。

积分图像这个数据结构主要用来快速计算多个尺度的简单矩阵图像特征。

2.2 链

​ 链在计算机视觉中用于描述物体的边界。链的元素是一个基本符号,这种方法使得在计算机视觉任务中可以使用任何形式的理论。链适合组织成符号序列的数据,链中相邻的符号通常对应于图像中邻接的基元。

2.3 拓扑数据结构

图(graph)G(V,E)是一个代数结构,有一组结点V=v1,v2,,vn和一组弧E=e1,e2,,en构成。每条弧ek代表一对无次序的结点{vi,vj}。结点的度数等于该结点所具有的弧数。

赋值图(evaluated graph):指弧和结点或两者都带有数值的图。

区域邻接图(region adjacency graph):其中结点对应与区域,相邻的区域用弧连接起来。

2.4 关系结构

3 分层数据结构

3.1 金字塔

M型金字塔(M-pyramids)矩阵

M型金字塔:是一个图像序列{ML,ML1,,M0}其中ML是具有与原图像同样的分辨率和元素的图像Mi1Mi降低一半分辨率得到的图像。通常我们只考虑维数是2的幂的方阵。

M型金字塔存储所有图像矩阵需要的像素个数为N2(1+14+116+)=1.33N2

T型金字塔(T-pyramids)树形

T型金字塔:树状结构。设2l是原图像的大小(最高分辨率)。

定义:

  1. 一个结点集合P={P=(k,i,j)}使得级别k[0,L]i,j[0,2k1]
  2. 一个映射F,定义在金字塔的结点Pk1,Pk之间F(k,i,j)=(k1,i div 2,j div 2)div表示整除
  3. 一个函数V,将金字塔的结点P映射到Z,其中Z是对应于亮度级别数的所有数的子集合

    特点:

  4. 对于给定的k,T型金字塔的结点对应于M型金字塔的一些图像点,结点P={(k,i,j)}集合的每个元素对应于M型金字塔的一个矩阵,称k为金字塔的层数。

  5. 对于给定的k ,图像P={(k,i,j)}构成金字塔的第k层的一个图像。
  6. F是所谓的父亲映射,在T型金字塔中,除了根(0,0,0)之外的所有的结点Pk都有定义。
  7. 除了叶子结点外,T型金字塔的每个结点都有4个子结点,叶子结点是第L层的结点,对应于图像的单个像素。

3.2 四叉树

​ 对T型金字塔的改进,除叶子结点外每个结点有4个子结点(西北NW,东北NE,西南SW,东南SE),在每个层次图像被分解为4个象限。

2018-04-21 15:45:00 learning_tortosie 阅读数 10012

实验目的

1.理解并掌握形态学图像处理中的开操作和闭操作
2.熟悉并掌握MATLAB软件的使用

实验环境

操作系统:Windows 10
软件:MATLAB R2014a

相关知识

1.定义

开操作:使图像的轮廓变得光滑,断开较窄的狭颈和消除细的突出物。
使结构元B对集合A进行开操作,定义为:

AB=(AB)B

含义:先用B对A进行腐蚀,然后用B对结果进行膨胀。
闭操作:同样使图像的轮廓变得光滑,但与开操作相反,它能弥合狭窄的间断和细长的沟壑,消除小的孔洞,并填补轮廓线中的裂痕。
使用结构元B对集合A进行闭操作,定义为:

AB=(AB)B

含义:先用B对A进行膨胀,然后用B对结果进行腐蚀。

2.几何解释

(1)开操作的何解释
A○B的边界由B中的点建立
当B在A的边界内侧滚动时,B所能到达的A的边界的最远点。


(2)闭操作的几何解释
A•B的边界由B中的点建立
B在A的边界外侧滚动
满足〖(B)〗_z⋂A≠”Ø” 的所有点的集合

3.相关函数说明

(1)strel
功能:形态学结构元素。
用法:
SE = STREL('arbitrary',NHOOD,HEIGHT) 创建一个指定领域的非平面结构化元素。HEIGHT是一个矩阵,大小和NHOOD相同,他指定了NHOOD中任何非零元素的高度值。
SE = STREL('ball',R,H,N) 创建一个空间椭球状的结构元素,其X-Y平面半径为R,高度为H。R必须为非负整数,H是一个实数。N必须为一个非负偶数。当N>0时此球形结构元素由一系列空间线段结构元素来近似。
SE = STREL('diamond',R) 创建一个指定大小R平面钻石形状的结构化元素。R是从结构化元素原点到其点的距离,必须为非负整数。
SE = STREL('disk',R,N) 创建一个指定半径R的平面圆盘形的结构元素。这里R必须是非负整数. N须是0, 4, 6, 8.当N大于0时,圆盘形结构元素由一组N(或N+2)个周期线结构元素来近似。当N等于0时,不使用近似,即结构元素的所有像素是由到中心像素距离小于等于R的像素组成。N可以被忽略,此时缺省值是4。注: 形态学操作在N>0情况下要快于N=0的情形。
如:se1 = strel('square',11) % 11乘以11的正方形
(2)imeroad
腐蚀图像
用法:IM2 = imerode(IM,SE)
腐蚀灰度、二进制或压缩二进制图像 IM ,返回腐蚀图像 IM2 。参数 SE 是函数 strel 返回的一个结构元素体或是结构元素体阵列。
(3)imdilate
膨胀图像
用法:IM2 = imdilate(IM, SE)
膨胀灰度图像、二值图像、或者打包的二值图像IM,返回膨胀图像M2。变量SE是一个结构元素或者一个结构元素的数组,其是通过strel函数返回的。

实验内容

先开操作再闭操作,组成形态学滤波器。
a 图是受噪声污染的指纹的二值图像,噪声为黑色背景上的亮元素和亮指纹部分的暗元素
b图是使用的结构元
c图是使用结构元素对图a腐蚀的结果:背景噪声消除了,指纹中的噪声尺寸增加
d图是使用结构元素对图c膨胀的结果:包含于指纹中的噪声分量的尺寸被减小或被完全消除,带来的问题是:在指纹纹路间产生了新的间断
e图是对图d膨胀的结果,图d的大部分间断被恢复,但指纹的线路变粗了
f图是对图e腐蚀的结果,即对图d中开操作的闭操作。最后结果消除了噪声斑点
缺点:指纹线路还是有断点,可以通过加入限制性条件解决。

实验结果

总结

通过本次实验,我基本掌握了开操作和闭操作的理论知识和matlab实现方法,同时体会到了数字图像处理的强大功能,在我们生活的方方面面都有着广泛的应用。学习理论知识第一步,还需要用编程软件去实现,再进一步是应用到现实生活中,再进阶一步就是提出新的理论。
总之,这次实践让我收获颇多,最后衷心感谢老师的细致讲解,她严谨的学风和认真的态度给我打开了数字图像处理领域的大门。

附录

matlab程序

A=imread('Fig0911(a)(noisy_fingerprint).tif'); %注意图片的路径要设置正确
subplot(2,3,1);
imshow(A)
title('噪声图像')
se=strel('square',3);
A2=imerode(A,se);
subplot(2,3,2);
imshow(A2)
title('腐蚀后的图像')
A3=imopen(A,se);
subplot(2,3,3);
imshow(A3)
title('A的开操作')
A4=imdilate(A3,se);
subplot(2,3,4);
imshow(A4)
title('开操作的膨胀')
A5=imclose(A3,se);
subplot(2,3,5);
imshow(A5)
title('开操作的闭操作')
2019-09-01 19:51:41 webzhuce 阅读数 385

基本概念

        “骨架”是指一幅图像的骨骼部分,它描述物体的几何形状和拓扑结构,是重要的图像描绘子之一。计算骨架的过程一般称为“细化”或“骨架化”,在包括文字识别、工业零件形状识别以及印刷电路板自动检测在内的很多应用中,细化过程都发挥这关键作用。通常,对我们感兴趣的目标物体进行细化有助于突出目标的形状特点和拓扑结构并且减少冗余的信息。
在这里插入图片描述
这里给出细化算法
在这里插入图片描述

示例演示

        实现基于形态学的细化算法。与上面算法介绍不同,将白色作为前景,黑色作为背景。完整工程代码。

/*
 *only process binary image
 * white is foreground
*/
void Thining(const cv::Mat &src, cv::Mat &dst)
{

    //four conditions
    bool condition1 = false, condition2 = false, condition3 = false, condition4 = false;

    //n*n neighbours
    constexpr int N = 5;
    uchar neighbour[N][N];
    const int kOffset = N / 2;
    src.copyTo(dst);

    bool modified = true;
    while(modified)
    {
        modified = false;
        Mat img;
        dst.copyTo(img);

        for(int i = kOffset; i < (dst.rows - kOffset); i++)
        {
            for(int j = kOffset; j < (dst.cols - kOffset); j++)
            {
                if(dst.at<uchar>(i, j) == 0)
                    continue;

                condition1 = false;
                condition2 = false;
                condition3 = false;
                condition4 = false;

                //get N*N neighbours of current point
                //white : 0, black : 1
                for(int m = 0; m < N; m++)
                {
				    for(int n = 0; n < N; n++)
                    {
                        neighbour[m][n] = dst.at<uchar>(i + n - kOffset, j + m - kOffset) == 255 ? 1 : 0;
                    }
                }

                //2 <= NZ(P1) <=6
                int count = neighbour[1][1] + neighbour[1][2] + neighbour[1][3] +
                        neighbour[2][1] + neighbour[2][3] +
                        neighbour[3][1] + neighbour[3][2] + neighbour[3][3];
                if(count >= 2 && count <=6)
                    condition1 = true;

                //Z0(P1) == 1
                count = 0;
                if(neighbour[1][2] == 0 && neighbour[1][1] == 1)
                    count++;
                if(neighbour[1][1] == 0 && neighbour[2][1] == 1)
                    count++;
                if(neighbour[2][1] == 0 && neighbour[3][1] == 1)
                    count++;
                if(neighbour[3][1] == 0 && neighbour[3][2] == 1)
                    count++;
                if(neighbour[3][2] == 0 && neighbour[3][3] == 1)
                    count++;
                if(neighbour[3][3] == 0 && neighbour[2][3] == 1)
                    count++;
                if(neighbour[2][3] == 0 && neighbour[1][3] == 1)
                    count++;
                if(neighbour[1][3] == 0 && neighbour[1][2] == 1)
                    count++;
                if(count == 1)
                    condition2 = true;

                //P2*P4*P8 = 0 or Z0(P2) != 1
                if(neighbour[1][2] * neighbour[2][1] * neighbour[2][3] == 0)
                    condition3 = true;
                else
                {
                    count = 0;
                    if(neighbour[0][2] == 0 && neighbour[0][1] == 1)
                        count++;
                    if(neighbour[0][1] == 0 && neighbour[1][1] == 1)
                        count++;
                    if(neighbour[1][1] == 0 && neighbour[2][1] == 1)
                        count++;
                    if(neighbour[2][1] == 0 && neighbour[2][2] == 1)
                        count++;
                    if(neighbour[2][2] == 0 && neighbour[2][3] == 1)
                        count++;
                    if(neighbour[2][3] == 0 && neighbour[1][3] == 1)
                        count++;
                    if(neighbour[1][3] == 0 && neighbour[0][3] == 1)
                        count++;
                    if(neighbour[0][3] == 0 && neighbour[0][2] == 1)
                        count++;
                    if(count != 1)
                        condition3 = true;
                }

                //P2*P4*P6 = 0 or Z0(P4) != 1
                if(neighbour[1][2] * neighbour[2][1] * neighbour[3][2] == 0)
                    condition4 = true;
                else
                {
                    count = 0;
                    if(neighbour[1][1] == 0 && neighbour[1][0] == 1)
                        count++;
                    if(neighbour[1][0] == 0 && neighbour[2][0] == 1)
                        count++;
                    if(neighbour[2][0] == 0 && neighbour[3][0] == 1)
                        count++;
                    if(neighbour[3][0] == 0 && neighbour[3][1] == 1)
                        count++;
                    if(neighbour[3][1] == 0 && neighbour[3][2] == 1)
                        count++;
                    if(neighbour[3][2] == 0 && neighbour[2][2] == 1)
                        count++;
                    if(neighbour[2][2] == 0 && neighbour[1][2] == 1)
                        count++;
                    if(neighbour[1][2] == 0 && neighbour[1][1] == 1)
                        count++;
                    if(count != 1)
                        condition4 = true;
                }

                if(condition1 && condition2 && condition3 && condition4)
                {
                    img.at<uchar>(i, j) = 0;
                    modified = true;
                }
                else
                    img.at<uchar>(i, j) = 255;

            } // for columns
        } // for rows
        img.copyTo(dst);
    } //  for while
}

运行结果

在这里插入图片描述

2016-07-06 20:50:26 zhougynui 阅读数 2601

背景知识

结构元素

腐蚀和膨胀

开操作

       定义:对集合A做腐蚀操作,然后对结果再进行膨胀操作。

         公式:

                                               

         功能:平滑屋里的轮廓、断开较窄的狭颈并消除细的突出物。

         原理说明:把结构元素B视为一个(扁平)的“转球”,B对A的开操作的边界由B中的点建立:当B在A的边界内侧滚动时,B所能到达的A的边界的最远点。即为右侧图中黑色线部分。

闭操作

       定义:结构元素B对集合A的闭操作就是简单的用B对A膨胀,紧接着用B对结果进行腐蚀。

       公式:


       功能:平滑轮廓的一部分,弥合较窄的间断和细长的沟壑,消除小的空洞,填充轮廓线中的断裂。

       原理说明:把结构元素B视为一个(扁平)的“转球”,B对A的开操作的边界由B中的点建立:当B在A的边界外侧滚动时,B所能到达的A的边界的最远点。即为右侧图中黑色线部分。




2019-04-11 17:23:14 qq_35789421 阅读数 185

1.形态学梯度

梯度用于刻画目标边界或边缘位于图像灰度级剧烈变化的区域,形态学梯度根据膨胀或腐蚀与原图作差组合来实现增强结构元素邻域中像素的强度,突出高亮区域的外围。最常用的形态学梯度是计算膨胀与腐蚀之间的算术差,另外两种计算形态学梯度分别是膨胀结果与原图的算术差以及原图与腐蚀结果的算术差,对于结构元素E,形态学梯度可以表示为:

G_{E}=\sigma _{E}-\xi _{E}

形态学梯度操作的输出图像像素值实在对应结构元素而非局部过渡区域所定义的邻域中灰度级强度变化的最大值。

2.顶帽和黑帽运算

形态学Top—Hat变换是指形态学顶帽操作与黑帽操作,前者是计算原图像与开运算结果图之差,后者是计算闭运算结果图与原图像之差。形态学Top-Hat是常用的一种形态学滤波器,具有高通滤波器的某部分特性,可实现在图像中检测出周围背景亮结构或周边背景暗结构。顶帽操作常用于检测图像中的峰结构,而黑帽操作常用于检测图像中的波谷结构。

在Opencv中提供了morphologyEx函数用于形态学运算,其参数如下:

void morphologyEx(InputArray src,OutputArrat dst,int op,InputArray kernel,Point anchor = Point(-1,-1),int iterations = 1 ,int morph-ologyDefaultBorderValue())

其中参数src为输入图像;dst为输出图像;op为形态学操作算子类型,可以进行MORPH_OPEN开操作,MOPRH_CLOSE闭运算,MOPRH_GRADIENT形态学梯度操作,MOPRH_TOPHAT顶帽操作,MOPRH_BLACKHAT黑帽操作;iterations可设置腐蚀与膨胀的操作的次数;borderType与borderValue为可选参数设置,针对边界处理。

没有更多推荐了,返回首页