图像识别——《OpenCV3编程入门-毛星云》第三部分 掌握imgproc组件
Posted somebot
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了图像识别——《OpenCV3编程入门-毛星云》第三部分 掌握imgproc组件相关的知识,希望对你有一定的参考价值。
博主QQ:1356438802
QQ群:473383394——UVC&OPENCV473383394
平台:Win7 64bits + Visual Studio 2012 + OpenCV 2.4.10
截止今天我终于把《OpenCV3编程入门-毛星云》这本书看完了,看了将近两个月终于看完了!看的挺累的,有点吃力,很多讲算法原理的地方看的很模糊。但是因为我一直带着一个问题去看:如何识别摄像头视频流中的红外LED灯?每看完一个案例我就会想有没有帮助,能不能用的上,然后做一些笔记,还算有点收获。
后面我会把我做了笔记,加了书签(原书电子档并没有书签)的PDF上传,有需要的可以拿去用。
按照惯例,先上目录,我们先把书本内容弄完,再去做自己的实验。
下面红色文字是我自己的总结!
第三部分 掌握imgproc组件 151
第6章 图像处理 153
6.1 线性滤波:方框滤波、均值滤波、高斯滤波 154
从结果来看,图像滤波就是把图像模糊或者锐化;
从用途来看,图像滤波是为了减少图像上的噪点或者失真。
6.1.1 平滑处理 154
6.1.2 图像滤波与滤波器 154
方框滤波、均值滤波、高斯滤波、中值滤波、双边滤波
6.1.3 线性滤波器的简介 155
低通滤波器、高通滤波器、带通滤波器、带阻滤波器
6.1.4 滤波和模糊 155
高斯低通——模糊
高斯高通——锐化
6.1.5 邻域算子与线性邻域滤波155
线性领域滤波算子:用不同的权重去结合一个小领域内的像素,得到应有的处理效果。
6.1.6 方框滤波(boxFilter) 156
加权系数,就是那个核,核就像一个3x3的方框一样,在图像中移动,根据方框内的加权值计算中心点像素值。
归一化:就是把要处理的量都缩放到一个范围内,如(0, 1),以便统一处理和直观量化。
6.1.7 均值滤波 157
均值滤波:最简单的滤波操作,输出图像的每一个像素是核窗口内输入图像对应像素的平均值(即所有像素加权系数相等)
6.1.8 高斯滤波 159
用一个模板扫描图像中的每一个像素,用模板确定的领域内像素的加权平均灰度值去替代模板中心像素点的值。
高斯滤波器是一类根据高斯函数的形状来选择加权值的线性平滑滤波器。对于抑制服从正太分布的噪声非常有效
6.1.9 线性滤波相关OpenCV源码剖析 160
6.1.10 OpenCV中GaussianBlur函数源码剖析 164
6.1.11 线性滤波核心API函数 165
6.1.12 图像线性滤波综合示例170
可以仔细看看案例,体会下这几个滤波方法的结果有什么区别,我觉得区别最大的是高斯滤波。
6.2 非线性滤波:中值滤波、双边滤波 175
6.2.1 非线性滤波概述 175
6.2.2 中值滤波 175
中值滤波:用像素点领域灰度值的中位值来代替该像素点的灰度值。对于斑点噪声和椒盐噪声很有效。
缺点:中值滤波花费的时间是均值滤波的5倍以上。
6.2.3 双边滤波 177
双边滤波:结合图像的空间领近度(定义域)和像素值相似度(值域)的一种折中处理,同时考虑空域信息和灰度相似性,达到保边去噪的目的。
6.2.4 非线性滤波相关核心API函数 178
对于中值滤波,主要是孔径(核)大小的设置
对于双边滤波,其实就是指定 定义域核的大小和值域核的大小。
6.2.5 OpenCV中的5种图像滤波综合示例 181
作者的原话:通过滑动滚动条,就可以控制图像在各种平滑处理下的模糊度,有一定的可玩性。
6.3 形态学滤波(1):腐蚀与膨胀 187
6.3.1 形态学概述 187
数学形态学包括,二值腐蚀和膨胀、二值开关运算、骨架抽取、极限腐蚀、击中击不中变换、形态学梯度、Top-hat变换、颗粒分析、流域变换、灰值腐蚀和膨胀、灰值开关运算、灰值形态学梯度等。
膨胀和腐蚀的功能:
- 消除噪声
- 分割出独立的图像元素,在图像中连接相邻的元素
- 寻找图像中的明显的极大值区域或极小值区域
- 求出图像的梯度
腐蚀和膨胀是对白色部分而言的,膨胀是对图像中的高亮部分进行扩张,腐蚀是原图中高亮部分缩小面积。
6.3.2 膨胀 188
膨胀就是求局部最大值的操作。
6.3.3 腐蚀 189
腐蚀就是求局部最小值的操作。
6.3.4 相关OpenCV源码分析溯源 190
erode和dilate函数内部都调用了morphOp
6.3.5 相关核心API函数讲解 191
关键是用getStructuringElement()函数生成膨胀核、腐蚀核,有三种核:矩形核(MORPH_RECT)、十字形核(MORPH_CROSS)、椭圆形核(MORPH_ELLIPSE)。
6.3.6 综合示例:腐蚀与膨胀195
有一定的可玩性!
6.4 形态学滤波(2):开运算、闭运算、形态学梯度、顶帽、黑帽 198
6.4.1 开运算 199
开运算,先腐蚀后膨胀。用来消除小物体,在纤细点处分离物体,并且在平滑较大物体的边界的同时不明显改变其面积。
dst = open(src, element) = dilate(erode(src, element))
6.4.2 闭运算 200
闭运算,先膨胀后腐蚀。排除小型黑色区域。
dst = close(src, element) = erode(dilate(src, element))
6.4.3 形态学梯度 200
膨胀图与腐蚀图之差。用来保留物体的边缘轮廓。
dst = dilate(src, element) - erode(src, element)
6.4.4 顶帽 201
dst = tophat(src, element) = src - open(src, element)
顶帽运算可以用来分离比邻近点 亮一些的斑块,分离即剔除。因为前景物体会比较亮,用顶帽运算将其剔除,剩下就是背景!
6.4.5 黑帽 202
dst = blackhat(src, element) = close(src, element) - src
黑帽运算可以用来分离比邻近点 暗一些的斑块,分离即剔除。因为背景物体会比较暗,用黑帽运算可以把背景的细节掩盖,从而留下的是前景物体的轮廓。
6.4.6 形态学滤波OpenCV源码分析溯源 203
关键的morphologyEx()函数
6.4.7 核心API函数:morphologyEx() 205
标识符:
- MORPH_OPEN
- MORPH_CLOSE
- MORPH_GRADIENT
- MORPH_TOPHAT
- MORPH_BLACKHAT
- MORPH_ERODE
- MORPH_DILATE
6.4.8 各形态学操作使用范例一览206
6.4.9 综合示例:形态学滤波208
通过这里的例程,可以详细感受下各种形态学操作的效果
6.5 漫水填充 214
6.5.1 漫水填充的定义 214
漫水填充:用特定的颜色填充连通区域,通过设置可连通像素的上下限以及连通方式来达到不同的填充效果。
结果就是,让某一块颜色接近的区域全部上一个色。
6.5.2 漫水填充法的基本思想214
当邻近像素点位于给定的范围内或在原始seedPoint像素值范围内时,FloodFill函数就会为这个点涂上颜色。
6.5.3 实现漫水填充算法:floodFill函数 214
int floodFill(InputOutputArray image, Point seedPoint, Scalar newVal, Recv *recv=0, Scalar loDiff=Scalar(), Scalar upDiff=Scalar(), int flags=4)
seedPoint,起始点/种子像素
newVal,要填充的色值
loDiff,upDiff,可连通像素的上下限
flags,FLOODFILL_FIXED_RANGE,FLOODFILL_MASK_ONLY,
fixed——固定的
6.5.4 综合示例:漫水填充 216
固定范围:考虑当前像素和种子像素之间的差
浮动范围:考虑当前像素和相邻像素之间的差
6.6 图像金字塔与图片尺寸缩放 223
6.6.1 引言 223
图像金字塔,就是图像经过缩放后生成的N张图片组成的金字塔。
缩放图片有两种方法:
- resize
- pyrUp()向上采样、pyrDown()向下采样
6.6.2 关于图像金字塔 223
- 高斯金字塔用来向下降采样图像
- 拉普拉斯金字塔用来从倒金字塔底层图像中向上采样,重建一个图像
向上是图像尺寸加倍,向下是图像尺寸减半,和金字塔的方向相反!
pryDown()是一个会丢失信息的函数。为了恢复原来更高分辨率的图像,我们要获得由降采样操作丢失的信息,这就与拉普拉斯金字塔有关!
6.6.3 高斯金字塔 225
6.6.4 拉普拉斯金字塔 226
可是一般情况下,你拿到一张图片时不可能有它的拉普拉斯金字塔残差,所以向上采样放大后的图像必然是模糊的!有什么卵用?!
6.6.5 尺寸调整:resize()函数 227
缩放比例,由dsize(目标尺寸)或者fx(水平缩放系数) / fy(垂直缩放系数),决定。
缩小图像一般用CV_INTER_AREA,放大图像一般用CV_INTER_LINEAR。
6.6.6 图像金字塔相关API函数 230
6.6.7 综合示例:图像金字塔与图片尺寸缩放 234
6.7 阈值化 237
利用物体与背景之间的灰度差异,将物体像素点的灰度值设定为0(黑色),其他的像素点的灰度值设置为255(白色),这时很方便观察物体。
这个功能非常好,正好用于手写笔的识别!阈值化之后,手写笔的光点将非常突出,直接求其坐标即可!
6.7.1 固定阈值操作:Threshold()函数 238
典型应用:对灰度图像进行阈值操作得到二值图像。
THRESH_BINARY: 二值阈值化
THRESH_BINARY_INV: 反向二值阈值化
THRESH_TRUNC: 截断阈值化
THRESH_TOZERO: 超过阈值被置为0
THRESH_TOZERO_INV: 低于阈值被置为0
6.7.2 自适应阈值操作:adaptiveThreshold()函数 239
6.7.3 示例程序:基本阈值操作240
可以看下五种阈值化方法的效果!
6.8 本章小结 244
第7章 图像变换 247
7.1 基于OpenCV的边缘检测 248
7.1.1 边缘检测的一般步骤 248
滤波、增强、检测
7.1.2 canny算子 248
当今最优的边缘检测算法!输入图像必须是单通道8位图像,即灰度图。
Canny边缘检测步骤:
- 消除噪声--高斯滤波
- 计算梯度幅值和方向
- 非极大值抑制
- 滞后阈值--推荐高低阈值比在2:1到3:1之间
7.1.3 sobel算子 253
sobel结合了高斯平滑和微分求导,用来计算图像灰度函数的近似梯度。
- 分别在x和y两个方向求导(一阶导就是梯度)
- 在图像的每一点,结合以上两个结果求出近似梯度
7.1.4 Laplacian 算子256
Laplacian算子是N维欧几里得空间中的一个二阶微分算子,定义为梯度grad的散度div。二阶导数可以用来进行检测边缘。另外Laplacian使用了图像梯度,它内部的代码其实是调用了Sobel算子。
7.1.5 scharr滤波器 259
7.1.6 综合示例:边缘检测 262
7.2 霍夫变换 267
7.2.1 霍夫变换概述 267
霍夫变换是图像处理中从图像中识别几何形状的基本方法之一。
经典霍夫变换用来检测图像中的直线,后来霍夫变换扩展到任意形状物体的识别。
7.2.2 OpenCV中的霍夫线变换268
霍夫变换的直接输入只能是边缘二值图像!
OpenCV支持三种:标准霍夫变换、多尺度霍夫变换、累计概率霍夫变换
7.2.3 霍夫线变换的原理 268
通过(x, y)点的直线族的极坐标系表达式:r = x cosQ + y sinQ
每个表达式在极径极角平面可以得到一条正弦曲线,如果三条曲线相交,说明它们通过了同一条直线,即三个表达式对应的那三个点经过同一条直线。
7.2.4 标准霍夫变换:HoughLines()函数 270
输入的必须是二值图像,最终输出是线条矢量,极坐标表示。
7.2.5 累计概率霍夫变换:HoughLinesP()函数 272
输入的必须是二值图像,最终输出是线条矢量,用起始点、结束点两个坐标表示。
7.2.6 霍夫圆变换 274
可以用来检测跟踪圆形物体
7.2.7 霍夫梯度法的原理 275
核心思想:取样一个圆心点,计算累加器中的点与圆心之间的距离,如果距离相等的点足够多,那么认为这个圆存在!
7.2.8 霍夫梯度法的缺点 276
- 有同心圆时只能选择最大的圆
- 阈值低时,耗时长
7.2.9 霍夫圆变换:HoughCircles()函数 276
输入灰度图像,输出圆矢量,用圆心坐标和半径表示。
7.2.10 综合示例:霍夫变换278
7.3 重映射 281
7.3.1 重映射的概念 281
直观的效果就是,可以对图像进行,中心对称、轴对称、缩小放大等处理。
7.3.2 实现重映射:remap()函数 282
需要传入x和y两组映射关系
7.3.3 基础示例程序:基本重映射283
7.3.4 综合示例程序:实现多种重映射 285
7.4 仿射变换 289
7.4.1 认识仿射变换 289
仿射变换比重映射的效果更复杂些:可以将图像缩小放大、扭曲、旋转再平移。
7.4.2 仿射变换的求法 290
7.4.3 进行仿射变换:warpAffine()函数 291
输入2x3的变换矩阵
7.4.4 计算二维旋转变换矩阵:getRotationMatrix2D()函数 292
给旋转中心、旋转角度、缩放系数,计算旋转矩阵
7.4.5 示例程序:仿射变换 292
另外一个求仿射变换矩阵的函数:getAffineTransform(srcTriangle, dstTriangle)
输入两组三点坐标,得出变换矩阵
7.5 直方图均衡化 295
7.5.1 直方图均衡化的概念和特点296
直方图均衡化是通过拉伸像素强度分布范围来增强图像对比度的一种方法。
7.5.2 实现直方图均衡化:equalizeHist()函数 297
就是把直方图的每个灰度等级进行归一化处理,求每种灰度的累计分布,得到一个映射的灰度映射表。
7.5.3 示例程序:直方图均衡化298
效果就是,图片会更明亮些!
7.6 本章小结 300
第8章 图像轮廓与图像分割修复 303
8.1 查找并绘制轮廓 304
8.1.1 寻找轮廓:findContours()函数 304
输入为二值图像
每个轮廓存储为点向量,输出就是点向量集——点向量的向量
8.1.2 绘制轮廓:drawContours()函数 305
指定要绘制的点向量集,点向量序号(轮廓序号),轮廓颜色,轮廓线宽
8.1.3 基础示例程序:轮廓查找306
这个案例里面有个语法很屌:
srcImage = srcImage > 119; //srcImage取大于阈值119的那部分
8.1.4 综合示例程序:查找并绘制轮廓 308
8.2 寻找物体的凸包 312
8.2.1 凸包 312
给定二维平面的点集,凸包就是将最外层的点连接起来构成的凸多边形。
8.2.2 寻找凸包:convexHull()函数 313
void convexHull(InputArray points, OutputArray hull, bool clockwise=false, bool returnPoints=true)
输入参数points,二维点集,用Mat / std::vector
输出参数hull,按照后面两个案例代码:既可以保存凸包所有点在points中的下标序号,也可以直接保存凸包点坐标
8.2.3 基础示例程序:凸包检测基础313
vector<int> hull;
8.2.4 综合示例程序:寻找和绘制物体的凸包 315
vector<vector<Point>> hull(g_vContours.size());< 以上是关于图像识别——《OpenCV3编程入门-毛星云》第三部分 掌握imgproc组件的主要内容,如果未能解决你的问题,请参考以下文章 图像识别——《OpenCV3编程入门-毛星云》第二部分 初探core组件 图像识别——《OpenCV3编程入门-毛星云》第一部分 快速上手OpenCV