这个部分是《opencv-tutorials.pdf》的部分,这部分也是几大部分中例子最多的,其实这个教程的例子都很不错,不过有些看得出来还是c接口的例子,说明例子有些年头了,其实在“opencv/sources/samples”有不同的接口的例子,看完这个教程,下一步就可以看看里面的不同的代码来学习,只是没有说明而已,不过在《opencv-refman.pdf》中会说到某某例子可以参考,也说明这里面的例子有很多都是为了解释这个手册中的一些函数的用法的。做完这些,就可以接着看opencv小组写的书籍了,书得不断的看,不断的学习,其实不是说等用到的时候再去学,这个一方面是到时候根本不知道该怎么做,其次,当如果有对某个函数一面之缘的情况下,第二次熟用的时候就会好很多。个人觉得学习:首先得圂囵吞枣的过一遍,有个大概的大局观,然后再是等用到再去查,再去细学,因为如果从第一遍就头仔细学:一,所有的知识都看成同等重要;二、学了前面忘了后面。当然用到才能记住,才能激发自己的欲求,才能重点关注某个知识点,推荐看看 托尼博赞的有关大脑学习的书籍,学习就得非线性的学,就得有取舍的学。

正文:

一、平滑

这里介绍四种平滑的函数,平滑也叫做模糊,是首先采用一个核(和CNN中一样的概念),然后进行卷积操作得到基于这个小滑框(cnn中叫做局部感受野)的值。其实也是很简单的概念,在之前使用的filter2D()函数中差不多的意思,只不过filter2D()函数需要自己指定核大小及其内部的数值。而这里是直接使用了函数得到不同的权值来进行平滑。

1、初始化工作

Mat src; Mat dst;//先声明源矩阵和目标矩阵
 src = imread( "../images/lena.jpg", 1 );//读取图像
namedWindow("demo", CV_WINDOW_AUTOSIZE );//创建窗口

2、归一化滤波

归一化滤波很简单,就是将选取的核,也就是滑框内的所有的值相加然后在接着除以滑框包含的像素的个数,将结果赋予指定的锚点位置的像素。

 blur( src, dst, Size( 5, 5 ), Point(-1,-1) );

它的函数原型为:

void blur(InputArray src, OutputArray dst, Size ksize, Point anchor=Point(-1,-1), int borderType=BORDER_DEFAULT );

参数列表:输入的矩阵、输出的句矩阵、核大小、锚点、边界类型;

其中的输入矩阵可以是多通道的,不过深度必须为CV_8U、CV_16U、 CV_16S、 CV_32F 、CV_64F;

输出矩阵会得到与输入矩阵一样的类型;锚点为负的时候表示会将这个滑框的中间位置作为锚点也就是输出滑框平滑后的值的位置。

最后的边界类型是用来推断图像外的像素。

notes:这里可以通过for等函数来调节其中的核大小,也就是滑框的大小来观察平滑的结果,这里显示框越大,结果越模糊。

3、高斯滤波

最有用的滤波器 (尽管不是最快的)。 高斯滤波是将输入数组的每一个像素点与 高斯内核 卷积将卷积和当作输出像素值。通过观察1维高斯的图像就能知道,靠近锚点的原始像素值的权值会比远离锚点的像素值的权值大,也就是锚点越远的,贡献的就越小。

GaussianBlur( src, dst, Size( 5, 5 ), 0, 0 );

它的函数原型为:

void GaussianBlur(InputArray src, OutputArray dst, Size ksize, double sigmaX, double sigmaY=0,int borderType=BORDER_DEFAULT );

参数列表:前两个与blur()的一样、第三个是核大小、x轴方向上高斯核的标准差、y轴方向上高斯核的标准差、边界类型。

其中第三个参数核大小,这里核的宽和高可以不同,但是必须是正的而且是奇数,当都为0的时候,就会采用后面两个参数来进行计算;

当sigmaY等于0的时候,sigmaY就会被设置成等于sigmaX。如果两个参数 sigmaX和sigmaY都等于0,那么就从第三个参数的高度和宽度中进行计算;

不过不论是将来如何的修改这几个参数,为了对这个函数的完全控制,还是推荐将第三、第四、第五三个参数进行具体的指定数值。

4、中值滤波

很简单的滤波,中值滤波将图像的每个像素用邻域 (以当前像素为中心的正方形区域)像素的 中值 代替 。

 medianBlur ( src, dst, 5 );

它的函数原型为:

void medianBlur(InputArray src, OutputArray dst, int ksize);

参数列表:前两个参数一样,第三个是因为中值滤波的滑框是限定成正方形的,只需要一个参数就够了,不过必须为正奇数。

5、双边滤波

具体原理见:http://blog.csdn.net/shouhuxianjian/article/details/42324809。保边去噪,不过相比较其他过滤器来说很慢。

bilateralFilter ( src, dst, i, i*2, i/2 );

它的函数原型为:

void bilateralFilter(InputArray src, OutputArray dst, int d, double sigmaColor, double sigmaSpace,int borderType=BORDER_DEFAULT );

参数列表:原图像、目标图像,核大小,颜色标准差,空间标准差,边界类型;

原图像必须是8位或者浮点类型,1通道或者是3通道;第三个参数表示设计到近邻像素范围的直径,如果是非正的,就从sigmaSpace中计算得到。

第四个参数:颜色空间中的过滤器的sigma。这个值越大,表示这个像素极其周边像素(基于第五个参数)会涉及到更深的颜色值,生成更大范围的半相等颜色;控制上面链接中的范围过滤器。

第五个参数;坐标空间中的过滤器的sigma。更大的值表示只要颜色足够接近(基于第四个参数),更远范围内的像素都能够相互影响,当d大于0,就用d来指定邻居的范围而不使用这个参数,否则d 也就是涉及的范围直径,就是与这个参数成比例的。控制上面链接中的域过滤器。

sigma:简单化的话,设置两个值一样就行,如果它们很小,比如小于10,这个过滤器的效果显现不出来,如果很大比如大于150,那么就有着很强的效果。

过滤器的大小:当d大于5的时候是很慢的,所以可以使用d=5来进行实时,对于d=9的离线应用来说,就需要大量的噪声过滤了。

二、形态学操作

简单来讲,形态学操作就是基于形状的一系列图像处理操作。通过将 结构元素 作用于输入图像来产生输出图像。

最基本的形态学操作有二:腐蚀与膨胀(Erosion 与 Dilation)。 他们的运用广泛:

消除噪声;

分割(isolate)独立的图像元素,以及连接(join)相邻的元素;

寻找图像中的明显的极大值区域或极小值区域。

1、腐蚀

原理很简单,就是和filter2D一样采用滑框的方式进行不断的移动,但是移动的过程中的操作却是很有意思,不论是这里的腐蚀还是下面的膨胀,它们都是类似CNN中的池化操作一样,简单,话不多说,重点就是进行滑框的卷积操作(记得是操作),取这个滑框中的最小值作为滑框中的锚点的值。可想而知在滑框划过的时候,总是挑选那些最小值,而这些最小值都是更暗的像素值,如果背景是白色的,前景是黑色的,那么前景区域会变大;如果相反,那么前景会缩小。

void erode(InputArray src, OutputArray dst, InputArray element, Point anchor=Point(-1,-1), int iterations=1, int borderType=BORDER_CONSTANT, const Scalar& borderValue=morphologyDefaultBorderValue() );

上面是腐蚀的函数原型,可以看出除了前几个参数,后面的参数都有默认值了,所以大部分情况也就不需要自己考虑了。

参数列表:输入图像、输出图像、结构元素(内核,滑框,等等同义的)、锚点、腐蚀迭代的次数、边界类型、边界值。

输入图像:通道数可以是任意的,但是深度必须是CV_8U、 CV_16U、CV_16S、CV_32F 、CV_64F中的一个。

输出图像:与输入图像有着一样的尺寸

结构元素:如果element = Mat();那么就使用一个3×3的矩阵结构元素。

锚点:结构元素中锚点的位置,默认值为Point(-1-1),表示锚点在结构元素的中间。

后三个就不介绍了,

这就是它的操作函数的数学表达

这个函数支持in-place模式,为了应对多通道的图片,这个函数直接对不同的通道进行单独的处理。

/**  @function Erosion  */
void Erosion( int, void* )
{int erosion_type;if( erosion_elem == 0 ){ erosion_type = MORPH_RECT; }else if( erosion_elem == 1 ){ erosion_type = MORPH_CROSS; }else if( erosion_elem == 2) { erosion_type = MORPH_ELLIPSE; }Mat element = getStructuringElement( erosion_type,Size( 2*erosion_size + 1, 2*erosion_size+1 ),Point( erosion_size, erosion_size ) );/// 腐蚀操作erode( src, erosion_dst, element );imshow( "Erosion Demo", erosion_dst );
}

上述例子用来解释函数原型中第三个参数,默认的时候为3×3的矩阵,而需要自己定义的时候可以如上图所示使用函数getStructingElement()来自定义,定义不同的结构元素,有三种不同的内核类型可以指定:

 矩形: MORPH_RECT
交叉形: MORPH_CROSS
椭圆形: MORPH_ELLIPSE

然后,我们还需要指定内核大小(上面例子中的erosion_size可以自己赋值,前面的代码没贴),以及 锚点 位置。不指定锚点位置,则默认锚点在内核中心位置。

2、膨胀

前面与腐蚀一样,只是将滑框中的卷积操作中取滑框中的最大值作为滑框中的锚点的值。所以经过膨胀之后,图像中亮度较高的区域就会变大

void dilate(InputArray src, OutputArray dst, InputArray kernel, Point anchor=Point(-1,-1),int iterations=1, int borderType=BORDER_CONSTANT, const Scalar& borderValue=morphologyDefaultBorderValue() );

这是膨胀的函数原型,其中的参数和腐蚀的是完全一样的。

其中的数学表达就是与上面一样,只不过将min换成了max。

上述:腐蚀和膨胀都是基于更亮的区域的。

3、更高级的形态学操作

a、开运算

开运算是通过先对图像腐蚀再膨胀实现的:

在假设背景是相比前景较亮的,这样可以排除一些小团块物体。

如上图,开运算可以让上图中下面的白色被包围的小块消失掉:在腐蚀的过程中白色的块被周围黑色的颜色代替了,然后这时候没有白色存在那个闭合小团内,所以这时候使用膨胀是为了让其他位置的粗细程度回到原来的位置上。

b、闭运算

闭运算是通过先对图像膨胀再腐蚀实现的:

如上图,闭运算让上图中首先进行膨胀,那么有的线较细的地方就会被白色背景代替掉,成了破碎的样子,这时候接着使用腐蚀只是为了剩下的部分的粗细程度能够恢复到以前。

c、形态梯度

膨胀图与腐蚀图之差:

能够保留物体的边缘轮廓,如下所示:

d、顶帽

原图像与开运算结果图之差:

e、黑帽

闭运算结果图与原图像之差:

上面5个心态学操作,其实在opencv中不是5个函数,而是一个函数中的5个不同的参数可选值。

void morphologyEx(InputArray src, OutputArray dst, int op, InputArray kernel, Point anchor=Point(-1,-1), int iterations=1, int borderType= BORDER_CONSTANT,  const Scalar&borderValue=morphologyDefaultBorderValue() );

上面这个函数就是执行高级形态学操作。参数列表:输入图像、输出图像、结构元素、操作类型、迭代次数、边界类型、边界值。

输入图像:图像可以是任意通道的,但是深度必须是CV_8U, CV_16U, CV_16S, CV_32F 、CV_64F。

输出图像:具有和输入图像一样的尺寸和类型;

结构元素:可以使用函数 getStructuringElement() 来创建

Mat element = getStructuringElement( morph_elem, Size( 2*morph_size + 1, 2*morph_size+1 ), Point( morph_size, morph_size ) );//这是个例子而已。

操作类型:下面的5个操作它们可以分别用(2、3、4、5、6)这几个数字来代替。

– MORPH_OPEN - an opening operation– MORPH_CLOSE - a closing operation– MORPH_GRADIENT - a morphological gradient– MORPH_TOPHAT - “top hat”– MORPH_BLACKHAT - “black hat”

迭代次数:默认为1次;剩下两个参数也和上面的是一样的。

  /// 运行指定形态学操作morphologyEx( src, dst, operation, element );imshow( window_name, dst );

opencv6.1-imgproc图像处理模块之平滑与形态学操作相关推荐

  1. OpenCV2:总结篇 imgproc(图像处理模块)

    一.简介 二.常用的函数 void erode( InputArray src, OutputArray dst, InputArray kernel, Point anchor = Point(-1 ...

  2. 图像处理-形态学操作

    形态学有四个基本操作:腐蚀.膨胀.开.闭. opencv笔记(十七)--形态学操作(膨胀.腐蚀.开.闭操作)_马大哈先生的博客-CSDN博客一.设置结构元素:getStructuringElement ...

  3. python的窗口处理模块_python的图像处理模块

    除了opencv专门用来进行图像处理,可以进行像素级.特征级.语义级.应用级的图像处理外,python中还有其他库用来进行简单的图像处理,比如图像的读入和保存.滤波.直方图均衡等简单的操作,下面对这些 ...

  4. python图像处理---python的图像处理模块Image

    https://blog.csdn.net/jiaoyangwm/article/details/79293272 [python图像处理]python的图像处理模块Image 版本信息:2.7.11 ...

  5. 无人机光电系统图像处理模块AVT22

    aseVision无人机光电系统图像处理模块AVT22 上海凯视力成信息科技有限公司 刘泊淼 CaseVision公司最新推出适合无人机光电系统的多功能图像处理模块AVT22.该模块提供了丰富的视频处 ...

  6. python中paste函数的作用_PIL图像处理模块paste方法简单使用详解

    python2中提供了PIL基础的图像数据出来模块,在python3中更名为了pillow模块,名字虽然发生了改变,但是提供的方法和功能都是一样的,对于日常基础的图像数据处理分析来说是足够用了的,现在 ...

  7. 开源智能相机- Xilinx Zynq-7000高清图像处理模块

    Zynq-7000图像处理模块设计资料保存:开源智能相机- Xilinx Zynq-7000高清图像处理模块 一.产品概述 Z-turn Board是一款以Xilinx Zynq-7010/7020全 ...

  8. python5-PIL的其他图像处理模块

    如上一篇博文的介绍,Image模块是最重要的一个.此篇总结学习过程中遇到的其他模块. 1.ImageChops模块 此模块包含一些算术图形操作,叫做channeloperations("ch ...

  9. python图像数据是几维数据_Python图像处理库PIL的ImagePath模块被用于存储和操作二维向量数据...

    ImagePath模块被用于存储和操作二维向量数据.Path对象会被传递到ImageDraw模块中. 一.ImagePath模块的函数 1. Path 定义:ImagePath.Path(coordi ...

最新文章

  1. php学习之道:WSDL具体解释(三)
  2. web框架之Django(一)
  3. html刮刮卡开始刮奖页面,html5刮刮卡抽奖 示例源码
  4. python入门之类的基础语法-关于一些Python的一些基础语法训练
  5. python 函数参数类型判断(判断类型)
  6. 收获,不止SQL优化——抓住SQL的本质--第十四章
  7. c语言prog1已停止工作,1.在考生文件夹下,要求程序PROG.C的功能是.doc
  8. git reset --mixed, - soft和--hard有什么区别?
  9. 单页面路由工程使用微信分享及二次分享解决方案
  10. CSDN博客专家申请成功
  11. 起心动念成大愿,点亮心灯祝世界 “点亮心灯祝福世界”活动圆满收官
  12. 数字人民币的基础-共识与信任
  13. 《南怀瑾讲述99个人生道理》——刘清海编著
  14. 学之思开源代码学习(1)
  15. java程序笑脸怎么打_Java程序运行后出现一张笑脸,鼠标点击一次则变成哭脸,再点击一次又变成笑脸,依次轮换。...
  16. Magento后台添加商品属性集属性集详细教程
  17. 国产开源项目管理软件ZenTao
  18. 线上拼团活动方案怎么制作设计?
  19. 我们为你精选了一份Jupyter/IPython笔记本集合-上篇
  20. Linux之C++毫秒级计时方法

热门文章

  1. JavaScript正则表达式笔记
  2. 超郁闷的本地连接故障解决过程!!!
  3. Linux Kernel TCP/IP Stack — 协议栈发包处理流程
  4. 架构师之路 — API 经济 — 权限管理系统(分权分域设计)
  5. 配置基于Devstack的嵌套KVM虚拟化
  6. PyQt4 Python GUI窗体应用程序
  7. 制作旋转LED的经验
  8. 在mac上安装 docker
  9. python处理时间戳
  10. 基于docker的 Hyperledger Fabric 多机环境搭建(上)