基于纹理边缘抑制的轮廓和边界检测(Contour and Boundary Detection)

kezunhai@gmail.com

http://blog.csdn.net/kezunhai


一幅复杂的自然场景图像中包含丰富的信息,视觉不可能对空间中的每一点赋予相同的关注程度。对人类视觉系统的实验表明:图像中的轮廓特征特别重要,它们在保留关于物体的边界有用的结构信息的同时,极大地降低了数据量,从而简化了信息的表达形式,使视觉能对各种瞬息万变的输入可以及时有效地处理。在很多情况下,根据画出了的物体轮廓就可以识别出物体。

轮廓在计算机视觉中属于中层视觉,它是基于形状目标识别的一个重要特征。形状与结构的视觉分析在人类的视觉感知中起着重要的作用,物体往往是通过它的形状大小、颜色信息和几何结构等特征来描述的。在许多视觉任务中,由于形状具有很强的鲁棒性,因此一般物体的识别主要是根据形状特征。轮廓检测的一个首要问题是如何处理通过简单边缘检测机制产生的大量的候选成分。由于许多的边缘仅仅是一种对比度的突变,它们可能不属于任何有意思的和相关物理轮廓。通过来自周边环境上下文的信息影响  边缘检测器的响应来增强对相关边缘的敏感性,并根据上下文的信息将孤立的边缘点连接起来,构成某一个物体在图像上形成的一个区域的完整边界线,去除那些不具有实际物理意义的背景纹理边缘。

本文根据Cosmin Grigorescu等人的论文“Contour and boundary detection improved by surround suppression of texture edges"的内容和自己的理解而成,如果对其中的细节感兴趣,敬请参考原文。   在Cosmin Grigorescu的论文中,提出了一个重要的计算环节(Computational Step),叫做环境抑制(Surround Suppression)来提高自然场景中图像的目标轮廓和区域边界的检测。该灵感主要是受到人的初级视皮层(Primary Visual Cortex)中的那些具有方向选择性的神经元(Orientation Selective Neurons)激发,这些细胞对周围的非经典感受野区域具有抑制作用,并且影响对边缘和线条的聚集的感知能力(Perception of  Group of Edges or Lines)。接下来,本文将详细的介绍下这篇论文的基本内容。

(1)计算梯度(Gradient Computation)

这里的操作类似Canny算子的第一步,也即首先将原图与一个高斯函数进行卷积,对图像进行平滑滤波,然后对滤波后的图像进行有限差分运算,求梯度。在Canny中,其计算公式如下:

然而,通过学者的研究得出,采用上面的公式来计算是病态的(ill-posed),因此,在该文中,采用如下的公式来计算梯度:

其中,是高斯函数的一阶微分。接着,进一步来计算X、Y方向的梯度,计算公式如下:

计算完梯度,那么就可以进一步得到幅值和方向,公式如下:

接着,沿着梯度方向采用非极大值抑制来对图像中的边缘像素进行定位,非极大值抑制可以参考博文:Canny算子中的非极大值抑制(Non-Maximum Suppression)分析

(2)环境抑制(Surround Suppression)

通过第一步的计算,可以得到边缘图像,在这一步,需要对检测到的边缘图像进行非轮廓边缘的抑制,非轮廓边缘包括背景纹理以及噪声等。在该文中,通过高斯差分来模拟人的初级视皮层细胞对环境抑制机制,DOG的表达式如下:

权重函数的定义如下:

对图像中的每一个点,采用上面的权重函数进行处理。根据处理方式的不同,可以分为各向同性抑制和各向异性抑制。下面来简单介绍下这两种抑制。

(3)各向同性抑制(Isotropic Surround Suppression)

通过前面的两步计算,各向同性抑制的准备工作已经就绪了。该种方式的抑制作用只考虑距离因素,因此其表达公式如下:

最后,可以得到轮廓检测算子,用公式表达如下:

其中,alpha是一个控制因子(control factor),H(*)是一个操作算子,类似于Canny算子的后处理部分,包括轮廓的细化、滞后阈值化以及轮廓连接等,具体的可以参考Canny算子。

(4)各向异性抑制(Anisotropic Surround Suppression)

各向异性抑制与各向同性抑制相比,增加了一个抑制因素,也即方向因素。对于两个点(x,y)和(x-u,y-v),其方向因素表示如下:

通过上式可知,如果这两个点的方向一致,那么抑制最用最大,因为cos(0)=1,随着夹角的增大,抑制作用逐渐减少,当两个点相互垂直时,抑制作用最小(cos(90)=0)。

增加了方向的环境抑制因素后,抑制作用表示如下:

公式中的符号与前面相同,不再介绍。

下面给出两段代码:

(1)非极大值抑制

  1. // non-maximum suppression
  2. void NonMaxSuppress(float*pMag, float* pGradX, float*pGradY, Size sz, unsigned char* pNSRst)
  3. {
  4. long x,y;
  5. int nPos;
  6. // the component of the gradient
  7. float gx,gy;
  8. // the temp varialbe
  9. float g1,g2,g3,g4;
  10. float weight;
  11. float dTemp,dTemp1,dTemp2;
  12. //设置图像边缘为不可能的分界点
  13. for(x=0;x<sz.width;x++)
  14. {
  15. pNSRst[x] = 0;
  16. pNSRst[(sz.height-1)*sz.width+x] = 0;
  17. }
  18. for(y=0;y<sz.height;y++)
  19. {
  20. pNSRst[y*sz.width] = 0;
  21. pNSRst[y*sz.width + sz.width-1] = 0;
  22. }
  23.  
  24. for (y=1;y<sz.height-1;y++)
  25. {
  26. for (x=1;x<sz.width-1;x++)
  27. {
  28. nPos=y*sz.width+x;
  29. // if pMag[nPos]==0, then nPos is not the edge point
  30. if (pMag[nPos]==0)
  31. {
  32. pNSRst[nPos]=0;
  33. }
  34. else
  35. {
  36. // the gradient of current point
  37. dTemp=pMag[nPos];
  38. // x,y 方向导数
  39. gx=pGradX[nPos];
  40. gy=pGradY[nPos];
  41. //如果方向导数y分量比x分量大,说明导数方向趋向于y分量
  42. if (fabs(gy)>fabs(gx))
  43. {
  44. // calculate the factor of interplation
  45. weight=fabs(gx)/fabs(gy);
  46. g2 = pMag[nPos-sz.width]; // 上一行
  47. g4 = pMag[nPos+sz.width]; // 下一行
  48. //如果x,y两个方向导数的符号相同
  49. //C 为当前像素,与g1-g4 的位置关系为:
  50. //g1 g2
  51. // C
  52. // g4 g3
  53. if(gx*gy>0)
  54. {
  55. g1 = pMag[nPos-sz.width-1];
  56. g3 = pMag[nPos+sz.width+1];
  57. }
  58. //如果x,y两个方向的方向导数方向相反
  59. //C是当前像素,与g1-g4的关系为:
  60. // g2 g1
  61. // C
  62. // g3 g4
  63. else
  64. {
  65. g1 = pMag[nPos-sz.width+1];
  66. g3 = pMag[nPos+sz.width-1];
  67. }
  68. }
  69. else
  70. {
  71. //插值比例
  72. weight = fabs(gy)/fabs(gx);
  73. g2 = pMag[nPos+1]; //后一列
  74. g4 = pMag[nPos-1]; // 前一列
  75. //如果x,y两个方向的方向导数符号相同
  76. //当前像素C与 g1-g4的关系为
  77. // g3
  78. // g4 C g2
  79. // g1
  80. if(gx * gy > 0)
  81. {
  82. g1 = pMag[nPos+sz.width+1];
  83. g3 = pMag[nPos-sz.width-1];
  84. }
  85.  
  86. //如果x,y两个方向导数的方向相反
  87. // C与g1-g4的关系为
  88. // g1
  89. // g4 C g2
  90. // g3
  91. else
  92. {
  93. g1 = pMag[nPos-sz.width+1];
  94. g3 = pMag[nPos+sz.width-1];
  95. }
  96. }
  97. dTemp1 = weight*g1 + (1-weight)*g2;
  98. dTemp2 = weight*g3 + (1-weight)*g4;
  99. //当前像素的梯度是局部的最大值
  100. //该点可能是边界点
  101. if(dTemp>=dTemp1 && dTemp>=dTemp2)
  102. pNSRst[nPos] = 128;
  103. else
  104. //不可能是边界点
  105. pNSRst[nPos] = 0;
  106. }
  107. }
  108. }
  109. }

(2)高斯差分DoG

  1. // sigma2 = 4*sigma1
  2. void getDoGKernel( Mat& kernel, int kSize, double sigma1, double sigma2)
  3. {
  4. double sigma1x = sigma1*sigma1;
  5. double sigma2x = sigma2*sigma2;
  6. Mat mkernel (kSize, kSize, CV_64F);
  7. int center = (kSize-1)/2;
  8. int i,j;
  9. double dsum = 0;
  10.  
  11. for ( i=0; i<kSize; ++i )
  12. {
  13. double* data = (double*)(mkernel.data+ mkernel.step[0]*i);
  14. int di = (i-center);
  15. for ( j=0; j<kSize; ++j )
  16. {
  17. int dj = (j-center);
  18. double d1 = (1.0/sigma1x)*exp(-(di*di+dj*dj)/(2*sigma1x));
  19. double d2 = (1.0/sigma2x)*exp(-(di*di+dj*dj)/(2*sigma2x));
  20. double dis = d2 - d1;
  21. if ( dis>0.0)
  22. data[j] = dis;
  23. else
  24. data[j]=0.0;
  25. dsum += fabs(dis);
  26. }
  27. }
  28. // 归一化
  29. mkernel = mkernel/dsum;
  30. mkernel.copyTo( kernel);
  31. return;
  32. }

最后,再附上一小节代码:

  1. Sobel( gray, sobelX, CV_32F, 1, 0, 3);
  2. Sobel( gray, sobelY, CV_32F, 0, 1, 3);
  3. magnitude( sobelX, sobelY, mag);
  4. //cartToPolar( sobelX, sobelY, mag, dir, true);
  5. // 非极大值值抑制
  6. filter2D( mag, mag, mag.depth(), kernel); // 环境抑制 surround suppression

另外,推荐几篇相关论文:

1、Cosmin Grigorescu.  contour detection based on nonclassical receptive field inhibition(2003 TIP).

2、唐奇伶. 基于初级视皮层感知机制的轮廓与边界检测(2007华中科技大学博士论文)

作者:kezunhai出处:http://blog.csdn.net/kezunhai欢迎转载或分享,但请务必声明文章出处。

基于纹理边缘抑制的轮廓和边界检测(Contour and Boundary Detection)的更多相关文章

  1. 基于纹理的图片检索及demo(未启动)

    基于纹理的图片检索及demo(未启动)

  2. opencv::轮廓发现(find contour in your image)

    轮廓发现(find contour) 轮廓发现是基于图像边缘提取的基础寻找对象轮廓的方法. 所以边缘提取的阈值选定会影响最终轮廓发现结果 //发现轮廓 cv::findContours( InputO ...

  3. Halcon编程-基于纹理的mara检测

    表面瑕疵检测是机器视觉领域非常重要的一个应用.机器视觉是集光学.机电和计算机三个领域的一门不算新的技术.但目前表面瑕疵检测在学界主要是计算机专业或者控制专业瞄准图像处理方向在做,而视觉光学系统这一块主 ...

  4. 每天进步一点点------Sobel算子(3)基于彩色图像边缘差分的运动目标检测算法

    摘  要: 针对目前常用的运动目标提取易受到噪声影响.易出现阴影和误检漏检等情况,提出了一种基于Sobel算子的彩色边缘图像检测和帧差分相结合的检测方法.首先用Sobel算子提取视频流中连续4帧图像的 ...

  5. 基于纹理内存的CUDA热传导模拟

    原文链接 项目中有三个,第一个是全局内存,其余两个分别是基于1d和2d纹理内存.项目打包下载. 纹理内存是只读内存,与常量内存相同的是,纹理内存也缓存在芯片中,因此某些情况下,它能减少对内存的请求并提 ...

  6. 基于Qt的FreeType字体轮廓解析

    一.本文目的 以前的文档中.详细的介绍了FreeType开源字体引擎库的基础知识.基本用法.但并未详细的阐明在TurboCG中.是如何解析出一个文字的轮廓的,本文集中阐述.怎么样使用FreeType开 ...

  7. 基于图像二维熵的视频信号丢失检测(Signal Loss Detection)

    1 图像二维熵 ​图像二维熵作为一种特征评价尺度能够反映出整个图像所含平均信息量的高低,熵值(H)越大则代表图像所包含的信息越多,反之熵值(H)越小,则图像包含的信息越少.对于图像信息量,可以简单地认 ...

  8. Image Processing and Analysis_8_Edge Detection:Edge and line oriented contour detection State of the art ——2011

    此主要讨论图像处理与分析.虽然计算机视觉部分的有些内容比如特 征提取等也可以归结到图像分析中来,但鉴于它们与计算机视觉的紧密联系,以 及它们的出处,没有把它们纳入到图像处理与分析中来.同样,这里面也有 ...

  9. Canny边缘检測算法原理及其VC实现具体解释(一)

    图象的边缘是指图象局部区域亮度变化显著的部分,该区域的灰度剖面一般能够看作是一个阶跃,既从一个灰度值在非常小的缓冲区域内急剧变化到还有一个灰度相差较大的灰度值.图象的边缘部分集中了图象的大部分信息,图 ...

随机推荐

  1. VC皮肤库SkinSharp 1.0.6.6的使用

    SkinSharp又称Skin#,是Windows环境下一款强大的换肤组件. SkinSharp作为换肤控件,仅仅须要在您的程序中加入一行代码,就能让您的界面焕然一新,并拥有多种主题风格和色调的动态切 ...

  2. ACdream 1083 有向无环图dp

    题目链接:点击打开链接 人民城管爱人民 Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 128000/64000 KB (Java/Othe ...

  3. python-生成随机字符

    需求: 随机生成6位的大写字母: 方法一: #!/usr/bin/env python # -*- coding:utf-8 -*- import random li = [] for i in ra ...

  4. fastclick.js介绍

    原文地址:http://www.uedsc.com/fastclick.html 用途:去掉移动端click事件的300ms的延迟. 延迟为什么存在   …在移动浏览器中,当你点击按钮的单击事件时,将 ...

  5. FullCalendar 的学习笔记(二)

    下面是一个.NET webForm的具体列子 注意引用了artDialog 以及异步请求数据的json格式字符串 <html xmlns="http://www.w3.org/1999 ...

  6. 【HTML5】在head 设置 meta 能更方便开发

    <meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initi ...

  7. 我的开源框架之TAB控件

    需求 (1)支持iframe.html.json格式的tab内容远程请求 (2)支持动态添加tab (3)支持远程加载完成监听,支持tab激活事件监听 (4)支持reload tab内容[如果是远程加 ...

  8. 10 个十分难得的 javascript 开发经验

    Javascript 的很多扩展的特性是的它变得更加的犀利, 同时也给予程序员机会创建更漂亮并且更让用户喜欢的网站. 尽管很多的开发人员都乐于颂扬 javascript,但是仍旧有人看到它的阴暗面. ...

  9. EF 拉姆达 动态拼接查询语句

    EF 动态拼接查询语句 using System; using System.Collections.Generic; using System.IO; using System.Linq; usin ...

  10. 超大文件上传到Azure Linux虚拟机最佳实践

    客户在实际进行迁移的时候,往往碰到需要将本地数据中心的超大文件,比如单个200GB的文件,或者总共1TB的无数文件上传到Azure上的情况,尤其是传到Azure的Linux虚拟机的场景,这种场景包括: ...