
作者博客https://blog.csdn.net/shuiyixin?type=blog
https://blog.csdn.net/shuiyixin/article/details/106046827
1.1.1 Mat类
https://blog.csdn.net/shuiyixin/article/details/106014341
1.1.2 Rect_结构
https://blog.csdn.net/shuiyixin/article/details/106085233
1.1.3 Scalar_结构
Scalar其实是一个从Vec派生得到的四元向量的模板类
一般情况,我们只赋值前三个,第一个参数表示蓝色,第二个参数表示绿色,第三个参数表示红色,也就是BGR:
https://blog.csdn.net/shuiyixin/article/details/106111460
1.1.4 RNG类
https://blog.csdn.net/weixin_43588171/article/details/104810295
1.2.1 saturate_cast()
https://blog.csdn.net/qq_27278957/article/details/88648737
在opencv中,saturate_cast的作用是防止数据溢出,作出保护。原理可理解为如下代码功能:
1.2.2 reshape()
cn: 表示通道数(channels), 如果设为0,则表示保持通道数不变,否则则变为设置的通道数。
rows: 表示矩阵行数。 如果设为0,则表示保持原有的行数不变,否则则变为设置的行数。
1.2.3 Create()
1.3.1 退出程序
数字图像在计算机中是以矩阵形式存储的,矩阵中的每一个元素都描述一定的图像信息,如亮度、颜色等
OpenCV利用Mat 类用于存储数据,利用自动内存管理技术很好地解决了内存自动释放的问题,当变量不再需要时, 立即释放内存.
CV_8U是 unsign 的8位/像素-即一个像素的值在0-255区间,这是大多数图像和视频格式的正常范围。
CV_32F是 float -像素是在0-1.0之间的任意值,这对于一些数据集的计算很有用,但是它必须通过将每个像素乘以255来转换成8位来保存或显示。
2.1.2 Mat类构造与赋值
1.Mat类的构造
2.Mat类的赋值
2.1.4 Mat元素的读取
其中有一个要注意的地方是i对应的是点的y坐标,j对应的是点的x坐标,而不是我们习惯的(x,y)
3.1.1 颜色模型与转换——converTo()
RGB模型再OpenCV中是BGR的顺序。
RGB模型增加透明度就是RGBA模型
HSV、YUV、Lab、GRAY
alpha和beta两个餐数用于声明两个数据类型间的转换关系,形式如m(x,y)=saturate_cast(α(*this)(x,y)+β),该转换方式就是将原有数据进行线性转换
3.1.2 多通道分离与合并——split(), merge()
下面这个图是把1个lena的img拆分了三个通道,分别放在一个mat[6]内,使用merge合并出来的6通道图片
3.2.1 图像像素统计
1.寻找像素最大值与最小值——minMaxLoc()
数据类型Point用于表示图像的像素坐标,
图像的像素坐标轴以左上角为坐标原点, 水平方向为x 轴, 垂直方向为y 轴
Point(x.y)对应于图像的行和列表示为Point (列数,行数)
在OpenCV 中对于二维坐标和三维坐标都设置了多种数据类型,针对二维坐标数据类型, 定义了整型坐标cv::Point2i (或者cv: :Point ) 、double 型坐标cv : :Point2d、浮点型坐标cv: :Point2f. 对于三维坐标,同样定义了上述的坐标数据类型,只需要将其中的数字" 2" 变成"3 气对于坐标中x、y、z 轴的具体数据, 可以通过变量的x、y、z 属性进行访问, 例如Point.x可以读取坐标的x 轴数据.
寻找多通道矩阵需要使用cv::Mat::reshape()将多通道变成单通道
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SPdtTvkr-1666660001256)(https://gitee.com/lyz-npu/typora-image/raw/master/img/%E5%9B%BE3-7.png)]
2.计算图像的平均值和标准差——mean, meanStdDev
图像的平均值表示图像整体的亮暗程度, 图像的平均值越大,则图像整体越亮。
标准差表示图像中明暗变化的对比程度, 标准差越大, 表示图像中明暗变化越明显。
3.2.2 图像间的像素操作
1.两幅图像的比较运算——max(), min()
这种比较运算主要用在对矩阵类型数据的处理上. 与掩模图像进行比较运算可以实现抠图或者选择通道的效果.
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UUdc5njU-1666660001256)(https://gitee.com/lyz-npu/typora-image/raw/master/img/%E5%9B%BE3-11.png)]
用黑框图片作为一个低通掩膜和lena图片求min(),就可以把外面的值剪掉。红色掩膜同理
2.两幅图片的逻辑运算——bitwise_()
3.2.3 图像二值化——threshold() 天津津门虎直播
THRESH_OTSU和THRESH_TRIANGLE这两种标志是获取阈值的方法,并不是阈值比较方法的标志, 这两个标志可以与前面5 种标志一起使用, 例如" THRESH_BINARY | THRESH_OTSU" . 前面5 种标志在调用函数时都需要人为地设置阈值,如果对图像不了解,设置的阈值不合理, 就会对处理后的效果造成严重的影响.这两个标志分别表示利用大津法(OTSU)和三角形法(TRlANGLE)结合国像灰度值分布特性获取二值化的阈值,并将阈值以函数返回值的形式给出.因此,如果该函数最后一个参数设置了这两个标志中的任何一个,那么该函数第三个参数thresh将由系统自动给出,但是在调用函数时仍然不能默认,只是程序不会使用这个数值.需要注意的是,到目前为止. OpenCV 4 中针对这两个标志只支持输入CV_8UC1类型的图像.
大津法——最大类间方差法:https://blog.csdn.net/yxswhy/article/details/77838622?locationNum=10&fps=1
三角形法——适用于单峰直方图:https://blog.csdn.net/qq_45769063/article/details/107102117
由threshold()函数全局只使用一个阈值,在实际情况中, 由于光照不均匀以及阴影的存在, 全局只有一个阈值会使得在阴影处的白色区域也会被函数二值化成黑色, 因此adaptiveThreshold() 函数提供了两种局部自适应阈值的二值化方法,基本的思路就是以目标像素点为中心选择一个块,然后对块区域里面的像素点进行高斯或者均值计算,将得到的平均值或者高斯值作为目标像素点的阈值,以此来对目标像素格进行二值化。对图像每一个像素格进行如此操作就完成了对整个图像的二值化处理。
3.2.4 查找表——LUT()
查找表,Look-Up-Table
函数输出图像的数据类型与LUT的数据类型保持一致,不与原图像保持一致。
如果第二个参数是单通道,则输入变量中的每个通道都按照一个LUT进行映射,如果第二个参数是多通道,则输入变量中的第i个通道按照第二个参数的第i个通道LUT进行映射.
3.3.1 图像连接——cv::vconcat, cv::hconcat
vconcat是纵向连接**,两者需要具有相同的宽度、数据类型及通道数**
hconcat是纵向连接**,两者需要具有相同的高度、数据类型及通道数**
3.3.2 图像尺寸变换——resize()
该函数的dsize 和fx ( fy ) 同时可以调整输出图像的参数,因此两类参数在实际使用时只需要使用一类,当根据两个参数计算出来的输出图像尺寸不一致时,以dsize 设置的图像尺寸为准.
dsize=Size(round(fx*src.cols), round(fy*src.rows))
缩小图像,通常使用INTER_AREA标志会有较好的效果
放大图像,采用INTER_CUBIC和INTER_LINEAR标志通常会有比较好的效果
标志参数简记作用INTER_NEAREAST0最近邻插值法INTER_LINEAR1双线性插值法INTER_CUBIC2双三次插值INTER_AREA3使用像素区域关系重新采样,首选用于图像缩小,图像放大时效果与INTER_NEAREST相似INTER_LANCZOS44Lanczos插值法INTER_LINEAR_EXACT5位精确双线性插值法INTER_MAX7用掩码进行插值
最邻近插值法、双线性插值:https://www.cnblogs.com/wanghui-garcia/p/11171954.html
双三次插值:https://blog.csdn.net/u013185349/article/details/84529982?
3.3.3 图像翻转——flip()
3.3.4 图像仿射变换——getRotationMatrix2D(), warpAffine(), getAffineTransform()
OpenCV4 提供了getRotationMatrix2D()函数用于计算旋转矩阵, 提供了warpAffine()函数用于实现图像的仿射变换.
确定了旋转矩阵后,通过warpAffine()函数进行放射变换可以实现矩阵的旋转。
相比于图像尺寸变换增加了两个插值方法,可以与其他插值方法一起用
仿射变换又称为三点变换
3.3.5 图像透视变换——getPerspectiveTransform(), warpPerspective()
透视变换又叫做四点变换。
3.3.6 极坐标变换——warpPolar()
极坐标变换就是将图像在直角坐标系与极坐标系中互相变换,
3.4 在图像上绘制几何图形
绘制圆形
绘制直线
绘制椭圆
绘制椭圆多边形
绘制多边形
3.5 感兴趣区域(ROI), 深拷贝与浅拷贝
在img中截取图像
OpenCV中提到的图像截取以及通过=赋值,都是浅拷贝
深拷贝方式, OpenCV 4 通过**copyTo()**函数实现两类方法
https://blog.csdn.net/zhu_hongji/article/details/81536820
图像"金字塔"的底部是待处理图像的高分辨率表示, 顶部是低分辨率的表示.
图像金字塔在特征检测中时基础理论和技术
高斯金字塔 ( Gaussian pyramid): 用来向下/降采样,主要的图像金字塔
拉普拉斯金字塔(Laplacian pyramid): 用来从金字塔低层图像重建上层未采样图像,在数字图像处理中也即是预测残差,可以对图像进行最大程度的还原,配合高斯金字塔一起使用。
这里的向下与向上采样,是对图像的尺寸而言的(和金字塔的方向相反),**向上就是图像尺寸加倍,向下就是图像尺寸减半。**而如果我们按上图中演示的金字塔方向来理解,金字塔向上图像其实在缩小,这样刚好是反过来了。
3.6.1 高斯“金字塔”——解决尺度不确定性
尺度:通俗理解,一格图像中包含的内容,,,缩小的 图像,一格中包含的信息多,是大尺度;一格中包含的信息少,是小尺度。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9V1hBRqL-1666660001260)(https://gitee.com/lyz-npu/typora-image/raw/master/img/%E5%9B%BE3-30.png)]
⑴对图像的向下取样
为了获取层级为 G_i+1 的金字塔图像,我们采用如下方法:
**<1>**对图像G_i进行高斯内核卷积
**<2>**将所有偶数行和列去除
每往上一层就会通过下来样缩小一次图像的尺寸, 通常情况下,尺寸会缩小为原来的一半
OpenCV 4 中提供了pyrDown() 函数专门用于图像的下来样计算
卷积:
https://www.cnblogs.com/geeksongs/p/11132692.html——讲的比较易懂
https://www.cnblogs.com/skyofbitbit/p/4471675.html——讲的比较仔细
高斯图像“金字塔”用到了卷积核
高斯分布https://blog.csdn.net/weixin_39124778/article/details/78411314
2.拉普拉斯金字塔
拉普拉斯金字塔是向上采样,重建上层未采样图像,在图像处理中预测残差。得到的图像比原来图像的尺寸大。向上采样如下:
(1)将图像在每个方向上扩大为原来的两倍,新增的行和列以0填充
(2)使用先前同样的内核(乘以4)与放大后的图像卷积,或得”新增像素”的近似值
乘4是因为用原来的一个像素高斯卷积核操作了新加的三个0像素,,,总共四个像素块,,用一个像素操作总共四个像素
3.7.1 窗口交互操作
回调函数是什么
https://www.zhihu.com/question/19801131
3.7.2 鼠标响应
同一物体无论是旋转还是平移,在图像中都具有相同的灰度值,因此直方因具有平移不变性、放缩不变性等优点
图像直方阁就是统计图像中每个灰度值的个数,之后将图像灰度值作为横轴,以灰度值个数或者灰度值所占比率作为纵轴绘制的统计图.
calcHist可以生成二维直方图
https://www.bilibili.com/video/BV1i54y1m7tw?p=26
4.2.1 直方图归一化——normalize()
另一种常用的归一化方式是寻找统计结果中的最大数值,把所有结果除以这个最大的数值,以实现将所有数据归一化为0~1 .
如果不进行归一化,每一个灰度值下的像素数目统计会随着图像尺寸的变大而变化
偏移归一化:
数组的数值被平移或缩放到一个指定的范围,线性归一化。
4.2.2 直方图比较——compareHist()
通过不同的方法计算相关系数,代表的含义不同
4.3.1 直方图均衡化——equalizeHist()
通过映射关系,将图像中灰度值的范围扩大,增加原来两个灰度值之间的差值,就可以提高图像的对比度,进而将图像中的纹理突出显现出来,这个过程称为图像直方图均衡化.
对原图直方图进行均衡化之后,虽然不是很平坦,但是比原图直方图平坦(每个颜色出现的次数相等)的多;扩展了动态范围,以前很窄,现在把其拉开;对于对比度出现很暗或者很亮的地方,没有什么对比度或集中在一块;通过均衡化一下就能把图像给拉开;
https://blog.csdn.net/schwein_van/article/details/84336633直方图均衡化操作
用r的累积分布函数作为变换函数,可产生一幅灰度级分布均匀概率密度的图像
4.3.2 直方图匹配(直方图规定化)
将直方图映射成指定分布形式的算法
直方图匹配操作能够有目的地增强某个灰度区间, 相比于直方图均衡化操作, 该算法虽然多了一个输入, 但是变换后
的结呆也更灵活.
直方图规定化是在直方图均衡化的基础上完成的(从结果来看跳过了图像均衡化的过程)
https://blog.csdn.net/superjunenaruto/article/details/80037777
按照累积概率插值最小原则进行映射,,,,例如原直方图5像素0.94累积概率到目标直方图的6像素0.84的距离大于到目标直方图7像素1的距离,因此原直方图5像素映射到目标直方图7像素的位置。
4.3.3 直方图反向投影——calcBackProject()
4.3.4 限制对比度的自适应直方图均衡化——CLANE()
直方图与增强对比度 - 程序员阿德的文章 - 知乎 https://zhuanlan.zhihu.com/p/98541241
https://www.cnblogs.com/geeksongs/p/11132692.html
图像卷积操作常将卷积模板通过缩放使得所有数值的和为1.进而解决卷积后数值越界的情况发生,
需要用不同的卷积模板对不同的通道进行卷积操作,就需要先使用split()函数将图像多个通道分离之后单独对每一个通道求取卷积运算
filter2D()函数不会将卷积模板进行旋转,如果卷积模板不对称,需要讲卷积模板旋转180°在输入给该函数
图像中常见的噪声主要有4种,分别是高斯噪声、椒盐噪声、泊松噪声和乘性噪声.
5.2.1 椒盐噪声
随机数函数原型
OpenCV中没有直接生成椒盐噪声的函数
椒盐噪声又称作脉冲噪声, 它会随机改变图像中的像素值,是由相机成像、图像传输、解码处理等过程产生的黑白相间的亮暗点噪声
5.2.2 高斯噪声
高斯噪声,顾名思义是指服从高斯分布(正态分布)的一类噪声,通常是因为不良照明和高温引起的传感器噪声。通常在RGB图像中,显现比较明显。
区别于椒盐噪声随机出现在图像中的任意位置,高斯噪声出现在图像中的所有位置.
OpenCV 4 的RNG类,是一个非静态成员函数
静态函数可以直接通过 类::函数 中方式调用,不用通过对象来调用函数,而非静态函数必须通过对象来调用,这里面还涉及到实例化对象时候的内存分配。
图像滤波是指去除图像中不重要的内容而使关心的内容表现得更加清晰的方法,例如去除图像中的噪声、提取某些信息等
将图像滤波分为消除图像噪声的滤波和提取图像中部分特征信息的滤波.
图像滤波使用的滤波器允许通过的信号频段,决定了滤波操作是去除噪声(低通、高阻:去除图像中的噪声)还是提取特征信息(高通:对图像边缘信息提取、增强和图像锐化的作用.).
在低通滤液中,模糊可以与滤波等价,例如图像高斯模糊和图像高斯低通滤波是个概念.
卷积操作中的卷积模板在图像滤波中称为滤波筷扳、滤波器或者邻域算子
5.3.1 均值滤波——blur()
求所有数据的平均值
5.3.2 方框滤波——boxFilter()
方框滤波可以选择不归一化,将所有像素值的和作为滤波结果,而不是所有像素值的平均值
boxFilter()默认进行归一化,不考虑数据类型的情况下,与blur()滤波结果相同。
sqrBoxFiler()函数实现对滤波器内每个像数值的平方求和,多用来处理CV_32F类型的图像数据,归一化后,变模糊的同时亮度也会变暗
该函数的归一化一样是除kernel的元素数
该函数的归一化一样是除kernel的元素数
5.3.3 高斯滤波——GaussianBlur()
高斯平滑也用于计算机视觉算法中的预先处理阶段,以增强图像在不同比例大小下的图像效果(参见尺度空间表示以及尺度空间实现)
建议将该函数的第三个、第四个、第五个参数都明确地给出.
高斯滤汲器的尺寸和标准偏差存在着一定的互相转换关系.
可以用该函数获取一个方向的高斯滤波器,然后两个方向的滤波器相乘得到一个k*k的二维滤波器
5.3.4 可分离滤波——sepFilter2D()
可分离性指的是先对x ( y ) 方向滤波, 再对y ( X ) 方向滤波的结果与将两个方向的滤波器联合后整体滤波的结果相同。两个方向的滤波器的联合就是将两个方向的滤波器相乘,
可以输入两个方向的滤波器,sepFilter2D不区分xy方向的滤波方向,但是filter2D需要区分
常见的非线性滤波有中值滤液和双边滤波
5.4.1 中值滤波——medianBlur()
中值滤波不依赖于滤波器内那些与典型值差别很大的值, 因此对斑点噪声和椒盐噪声的处理具有较好的效果.
5.4.2 双边滤波——bilateralFilter()
双边滤波对高频率的波动信号起到平滑的作用, 同时保留大幅值变化的信号波动, 进而实现对保留图像中边缘信息的作用.
滤波器对边缘附近的像素进行滤波时,距离边缘较远的像素值不会对边缘上的像索值影响太多,进而保留边缘的清晰性.
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-02ucXQ8J-1666660001265)(https://gitee.com/lyz-npu/typora-image/raw/master/img/%E5%9B%BE5-24.png)]
双边滤波采用了空间和灰度距离两个高斯滤波的结合
•空间距离指当前点与卷积核中心点的欧式距离,离中心点越近的点权重系数越大
•灰度距离指当前点灰度与中心点灰度的差的绝对值,颜色越接近的点权重系数越大
5.5.1 边缘检测原理
得到的正数值表示像素值突然由低变高,得到的负数值表示像素值由高到低,这两种都是图像的边缘,因此,为了在图像中同时表示出这两种边缘信息, 需要将计算的结果求绝对值.
5.5.2 Sobel算子——Sobel()
https://blog.csdn.net/qq_32811489/article/details/90312421
Sobel算子还结合了高斯平滑滤波的思想,将滤波器尺寸由ksize x 1改进为ksize x ksize. 提高了对平缓区域边缘的响应,效果更好
是一种中心差分,对中间水平线和垂直线上赋予较高的权重
其中第一个式子是n等于2时展开式的高斯平滑算子,也就是二项式展开式的系数,第二个式子表示差分。
最后得到的结果就是3阶sobel边缘检测算子。
5.5.3 Scharr算子——Scharr()
算子只有上面两种
5.5.4 生成边缘检测滤波器——getDeriveKernels()
Scharr()和Sobel()函数就是通过调用getDeriveKernels()函数得到了他们使用的算子
5.5.5 Laplacian算子——Laplacian()
Sobel算子和Scharr算子都需要提取x方向的边缘和y方向的边缘,然后将两个方向的边缘总和得到图像的整体边缘。
Laplacian算子具有个方向同性的特点
Laplacian算子对噪声具有无法接受的敏感性
5.5.6 Canny算子——Canny()
https://blog.csdn.net/likezhaobin/article/details/6892176
https://www.cnblogs.com/king-lps/p/8007134.html
该算法不容易受到噪声的影响,能够识别图像中的弱边缘和强边缘,并结合强弱边缘的位置关系, 综合给出图像整体的边缘信息.
5.5.7 LOG算子
LOG斑点检测https://www.cnblogs.com/ronny/p/3895883.html
6.1.1 图像像素距离变换——distanceTransform()
图像形态学操作主要包括图像腐蚀、膨胀、开运算与闭运算
图像形态学在图像处理中具有广泛的应用, 主要应用于从图像中提取对于表达和描述区域形状有意义的图像分嚣, 以便后续的识别工作能够抓住对象最为本质的形状特性,例如边界、连通域等.
图像处理中常用的距离有欧氏距离、街区距离和棋盘距离
该函数用于实现图像的距离变换. 即统计图像中所有像素距离0像素的最小距离.
Voronoi图,又叫泰森多边形或Dirichlet图,它是由一组由连接两邻点直线的垂直平分线组成的连续多边形组成。
6.1.2 图像连通域分析——connectedComponents()
图像的连通域是指图像中具有相同像素值并且位置相邻的像素组成的区域.
.提取图像中不同的连通域是图像处理中较为常用的方法,例如在车牌识别、文字识别、目标检测等领域对感兴趣区域的分割与识别
常用的图像邻域分析法有两遍扫描法和种子填充法.
https://blog.csdn.net/sy95122/article/details/80757281
腐蚀和膨胀是形态学的基本运算,通过这些基本运算可以去除图像中的噪声、分割出独立的区域或者将两个连通域连接在一起等.
6.2.1 图像腐蚀——erode()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cFQHVRjl-1666660001271)(https://gitee.com/lyz-npu/typora-image/raw/master/img/%E5%9B%BE6-12.jpg)]
白底图像黑底图像操作相反
6.2.2 图像膨胀——dilate()
6.3.1 开运算——morphologyEx()
图像开运算可以去除图像中的噪声, 消除较小连通域, 保留较大连通域,同时能够在两个物体纤细的连接处将两个物体分离, 并且在不明显改变较大连通域面积的同时能够平滑连通域的边界.
腐蚀—>膨胀
6.3.2 闭运算
图像闭运算可以去除连通域内的小型空洞, 平滑物体轮廓, 连接两个临近的连通域.
膨胀—>腐蚀
6.3.3 形态学梯度
形态学梯度能够描述目标的边界, 根据图像腐蚀和膨胀与原图之间的关系计算得到, 形态学梯度可以分为基本梯度、内部梯度和外部梯度.基本梯度是原图像膨胀后图像与腐蚀后图像间的差值图像, 内部梯度图像是原图像与腐蚀后图像间的差值图像, 外部梯度是膨胀后图像与原图像间的差值图像.
6.3.4 顶帽运算
图像顶帽运算是原图像与开运算结果之间的差值,往往用来分离比邻近点亮一些的斑块
腐蚀—>膨胀—>减原图像
6.3.5 黑帽运算
黑帽运算是原图像与顶帽运算结果之间的差值, 往往用来分离比邻近点暗一些的斑块.
膨胀—>腐蚀—>减原图像
6.3.6 击中击不中变换
击中击不中变换要求原图像中需要存在与结构元素一模一样的结构
6.3.7 图像细化——thinning()
图像细化是将图像的线条从多像素宽度减少到单位像索宽度的过程,有时又称为"骨架化"或者"中轴变换气"
细化算法主要分为迭代细化算法和非迭代细化算法
迭代细化算法:串行细化算法、并行细化算法
Zhang 细化方法被广泛使用.
7.1.1 直线检测——HoughLines()
霍夫变换(Hough Transfonn ) 是图像处理中检测是否存在直线的重要算法
使用标准霍夫变换和多尺度霍夫变换函数HoughLine()提取直线时无法准确知道图像中直线或者线段的长度,只能得到图像中是否存在符合要求的直线,以及直线的极坐标解析式.
Vec4i 中前两个元素分别是直线或者线段一个端点的x 坐标和y 坐标,后两个元素分别是直线或者线段另一个端点的x 坐标和y 坐标
7.1.2 直线拟合——fitLine()
与直线检测相比,直线拟合的最大特点是将所有数据只拟合除一条直线
最小二乘M-estimator 方法
7.1.3 圆形检测——HoughCircles()
https://blog.csdn.net/weixin_44638957/article/details/105883829
7.2.1 轮廓发现与绘制——findContours()、drawContours()
https://blog.csdn.net/dcrmg/article/details/51987348
为了描述不同轮廓之间的结构关系,定义由外到内的轮廓级别越来越低,也就是高一层级的轮廓包围着较低层级的轮廓
对于连接了图片边框的内容(例如下图的手),整个手不是个封闭图形,因此,在canny算子下找出了外轮廓,尽管使用了RETR_EXTERNEL来寻找最外层边框,依然会找到多余的边框。其实内部多出来的黑色轮廓是和手外部轮廓的同级边框
7.2.2 轮廓面积——contourArea()
通过轮廓面积的大小可以进一步分析每个轮廓隐含的信息.例如通过轮廓面积区分物体大小、识别不同的物体等
当参数取值为true时, 表示统计的面积具有方向性, 轮廓顶点顺时针给出和逆时针给出时统计的面积互为相反数;当参数取值为false 时, 表示统计的面积不具有方向性,输出轮廓面积的绝对值.
7.2.3 轮廓长度(周长)——arcLength()
若第二个参数式true,则三角形三个顶点的周长为三边和,,,,若为false,则周长为两边之和
7.2.4 轮廓外接多边形——boundingRect()、minAreaRect()、approxPolyDP()
7.2.5 点到轮廓距离——pointPolygonTest()
点到轮廓的距离,对于计算轮廓在图像中的位置、两个轮廓之间的距离以及确定图像上某一点是否在轮廓内部具有重要的作用.
7.2.6 凸包检测——convexHull()
将二维平面上的点集最外层的点连接起来构成的凸多边形称为凸包.但是逼近结果一定为凸多边形.
7.3.1 几何矩与中心矩——moments()
https://www.zhihu.com/question/26803016
矩是描述图像特征的算子,广泛应用于图像检索和识剔,图像匹配,图像重建,图像压缩,以及运动图像序列分析等领域.
7.3.2 Hu矩——HuMoments()
Hu 矩具有旋转、平移和缩放不变性,因此,在图像具有旋转和缩放的情况下, Hu矩具有更广泛的应用.
7.3.3 基于Hu矩的轮廓匹配——matchShapes()
由于Hu 矩具有旋转、平移和缩放不变性,因此可以通过Hu 实现图像轮廓的匹配.
对QR 二维码的识别儒要借助第三方工具,常用的是zbar 解码库.OpenCV4提供了解码函数
针对QR 二维码识别的两个过程. OpenCV 4 提供了多个函数用于实现每个过程, 这些函数分别是定位QR二维码的detect()函数、根据定位结果解码二维码的decode()函数,以及同时定位和解码的detectAndDecode()函数.
https://www.bilibili.com/video/BV1HJ411a7cp?spm_id_from=333.880
通俗讲解:图像傅里叶变换 - 麻花团子的文章 - 知乎 https://zhuanlan.zhihu.com/p/99605178
任何信号都可以由一系列正弦信号叠加形成, 一维领域信号是一维正弦波的叠加,二维领域是二维平面波的增加.由于图像可以看作是二维信号, 因此可以对图像进行傅里叶变换
对图像进行离散傅里叶变换
离散傅里叶变换广泛应用在图像的去噪、滤波等卷积领域
理解傅里叶分析:https://blog.csdn.net/u013921430/article/details/79683853
数字图像傅里叶分析:https://blog.csdn.net/u013921430/article/details/79934162
8.1.1 离散傅里叶变换——dft()、idft()
图像离散傅里叶变换之后的结果会得到既含有实数又含有虚数的图像,在实际使用时常将结果分成实数图像和虚数图像,或者用复数的幅值和相位来表示变换结果, 可以分成幅值图像和相位图像.
图像中像素波动较大的区域对应的频域是高频区域,因此高频区域体现的是图像的细节、边缘、纹理信息,而低频信息代表了图像的内容信息.
离散傅里叶变换算法倾向于对某些特定长度的输入矩阵进行处理, 而不是对任意尺寸的矩阵进行处理.因此,如果尺寸小于处理的最佳尺寸,那么常需要对输入矩阵进行尺寸变化以使得函数拥有较快的处理速度.常见的尺寸调整方式为在原矩阵的周围增加多层。像素, 因此dft()函数第四个参数才会讨论矩阵中出现第一个非零行.
填充多少行,列需要由下面的函数进行计算,,计算需要多少行、列
计算好最有尺寸后,改变图像的尺寸,在图像周围生成外框
由于离散傅里叶变换得到的数值可能为双通道的复数, 在实际使用过程中更加关注复数的幅值, 因此OpenCV 4 提供了magnitude()函数用于计算由两个矩阵组成的二维向量矩阵的幅值矩阵.
因为F(u,v)衰减、变化比较快,直接画图看不到什么点,因此需要加个1,,,再log运算,,,然后再对幅值谱进行分析
.在该程序中, 首先计算适合图像离散傅里叶变换的最优尺寸,之后利用copyMakeBorder()函数扩展图像尺寸,然后进行离散傅里叶变换,最后计算变换结果的幅值.为了能够显示变换结果中的幅值,将结果进行归一化处理。变换的原点位于4 个顶点,因此通过图像变换,将变换结果的原点调整到图像中心.
需要注意一点的是,频域图像归一化处理仅仅只是观察频谱图时有所帮助.包括对数变换也是一样,是为了更好的观察频域的能量分布的,因为图像的能量大多集中在低频区域,因此变换的结果大多也就是看到低频上一些白斑
图像傅里叶变换后为什么要归一化? - DBinary的回答 - 知乎 https://www.zhihu.com/question/354081645/answer/890215427
8.1.2 傅里叶变换进行卷积——mulSpecturms()
傅里叶变换可以将两个矩阵的卷积转换成两个矩阵傅里叶变换结果的乘积,通过这种方式可以极大地提高卷积的计算速度.但是图像傅里叶变换结果都是具有复数共辄对称性的复数矩阵,两个矩阵相乘需要计算对应位置的两个复数乘积. OpenCV 4 提供了用于计算两个复数矩阵的乘积的mulSepctrums()函数
通过离散傅里叶变换方式进行图像的卷积时,需要将卷积核也扩展到与图像相同的尺寸,然后同时对两个图片做尺寸最优化扩展矩阵, 并对乘积结果进行离散傅里叶变换的逆交换.
8.1.3 离散余弦变换
https://blog.csdn.net/akadiao/article/details/79778095
离散余弦变换经常使用在信号处理和图像处理领域中,主要用于对信号和图像的有损数据压缩中.离散余弦变换具有"能量集中" 的特性,信号经过变换后能量主要集中在结果的低频部分.
目前dct()函数只支持偶数大小的数组,
离散余弦变换具有很强的”能量集中”特性,左上方称为低频数据,右下方称为高频数据。
用于快速计算图像某些区域像素的平均灰度
.积分图像是比原因像尺寸大1 的新图像,例如,原因像尺寸为NxN , 那么积分图像尺寸为(N + 1) x (N + 1) .
积分图像中每个像素的像素值为原图像中该像素点与坐标原点组成的矩形内所有像素值的和,
P0的像素值为原图像中前四行和前四列相交区域内所有像素值之和
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-er9De8kL-1666660001277)(https://gitee.com/lyz-npu/typora-image/raw/master/img/%E5%9B%BE8-7.png)]
积分图像:标准求和积分图像、平方求和积分图像、倾斜求和积分图像(只是累加方向旋转了45°)
8.3.1 漫水填充法——floodFill()
8.3.2 分水岭法——watershed()
区别在于漫水填充法是从某个像素值进行分割, 是一种局部分割算法,而分水岭法是从全局出发,需要对全局进行分割.
https://zhuanlan.zhihu.com/p/67741538
两个区域的边界是-1,其他区域的值是1-n的数字,数字不可能大于 contour的数量。
8.3.3 Grabcut法——grabCut()
Grabcut 法是重要的图像分割算法,其使用高斯混合模型估计目标区域的背景和前景.该算法通过法代的方法解决了能量函数最小化的问题, 使得结果具有更高的可靠性.
8.3.4 Mean-Shift法——pyrMeanShiftFiltering()
https://blog.csdn.net/ttransposition/article/details/38514127
百度文库PPT:https://wenku.baidu.com/link?url=kZt9aLkbV0D74VY9AjCs_aL4cO4eSrbU8rDdzk2pLP0ZbSieurP-xFAJAPGxZSx3bLLxv14bMC5WoSlTkjZ5QXO7UOOO5IKKMqVixxsZst_
meanshift经常用来寻找模态点,即密度最大的点
均值漂移法,是一种基于颜色空间分布的图像分割算法,该算法的输出是一个经过滤色的“分色“图像,其图像会变得渐变,细纹纹理会变的平缓。,每个像素点用一个五维向量(x, y, b, g, r)表示,
去除图像中受"污染"的区域。图像修复不但可以去除图像中的划痕,而且可以去除图像中的水印、日期等.
离边缘区域越远的像索估计的准确度越低, 因此, 如果" 污染" 区域较大, 修复的效果就会降低.
先创建掩模(掩模是图像中的污染,通过二值化等操作求出污染的区域),然后可以适当膨胀扩大掩模的污染区域,在inpaint()函数中输入要去除污染的图像和污染掩模
9.1.1 显示关键点——drawKeypoints()
关键点是对图像中含有特殊信息的像素点的一种称呼,主要含有像素点的位置、角度等信息.
drawKeypoints() 函数用于一次性绘制所有的关键点
9.1.2 Harris角点检测——cornerHarris()
Harris角点对于旋转、平移具有不变性,,但是对于缩放没有不变性
Harris角点响应函数表达式是怎么得来的? - 大黑的回答 - 知乎 https://www.zhihu.com/question/37871386/answer/2311779754
角点检测:Harris 与 Shi-Tomasi - 程序员阿德的文章 - 知乎 https://zhuanlan.zhihu.com/p/83064609
Harris角点是最经典的角点之一,其从像素值变化的角度对角点进行定义,像素值的局部最大峰值即为Harris 角点
该函数计算得到的结果是Harris评价系数,但是由于其取值范围较广并且有正有负, 常需要通过normalize()函数将其归一化到指定区域内后,再通过阈值比较判断像素点是否为Harris 角点
9.1.3 Shi-Tomas角点检测——goodFeaturesToTrack()
9.1.4 亚像素级别角点检测——cornerSubPix()
亚像素级别角点检测是先计算出Harris角点/Shi-Tomas角点后,再精细化计算亚像素角点
9.1.5 FAST角点检测——FAST()
https://blog.csdn.net/tostq/article/details/49314017
https://aibotlab.blog.csdn.net/article/details/65662648
1.fast很快;
2.没有sift的尺度不变性,也不具有旋转不变性;
3.当图片中的噪点较多时,它的健壮性并不好,而且算法的效果还依赖于一个阈值t
特征点与角点在宏观定义上相同,都是能够表示图像中局部特征点多的像素点,但是特征点去有别于角点的是其具有能够唯一描述像素点特征的描述子,例如该点左侧像素比右侧像素大,该点是局部最低点等。
通常特征点有关键点和描述子组成,例如SIFT特征点、ORB特征点等都需要先计算关键点坐标,之后再计算描述子
9.2.1 关键点
该函数需要被其他类继承之后才能使用,即只有在特征点具体的类中才能使用,例如在ORB特征点的ORB类中,可以通过ORB::detect()函数计算ORB特征点的关键点,在SIFT特征点的SIFT类中,可以通过SIFT::detect()函数计算SIFT特征点的关键点
9.2.2 描述子——detectAndCompute()
描述子是用来唯一描述关键点的一串数字,与每个人的个人信息类似,通过描述子可以区分两个不同的关键点,也可以在不同的图像中寻找同一个关键点
9.2.3 SIFT特征点检测——Ptr
SIFT 特征点之所以备受欢迎, 是因为其在光照、噪声、视角、缩放和旋转等干扰下仍然具有良好的稳定性.
Sift算子特征点提取https://blog.csdn.net/dcrmg/article/details/52577555
128维特征项量的来源:https://www.cnblogs.com/wangguchangqing/p/4853263.html
S1FT类变量,用于表明从Features2D类中继承的函数是计算SIFT特征点,而不是计算其他特征点、SIFT 类在xfeatures2d 头文件和命名空间中,因此在使用时需要在程序中通过"#include
9.2.4 SURF特征点检测——Ptr
https://blog.csdn.net/zrz0258/article/details/113176528
SURF 特征点直接用方框滤波器去逼近高斯差分空间
SURF 特征点中, 不同组间图像的尺寸都是相同的, 但不同组使用的方框滤波器的尺寸逐渐增大,同一组内不同层间使用相同尺寸的滤波器,但是滤波器的模糊系数逐渐增大.
9.2.5 ORB特征点检测——Ptr
https://www.cnblogs.com/alexme/p/11345701.html
https://blog.csdn.net/yang843061497/article/details/38553765
ORB 特征点以计算速度快著称,计算速度可以达到SURF 特征点的10 倍、SIFT 特征点的100 倍,
ORB特征点由FAST角点与BRIEF描述子组成,首先通过FAST角点确定图像中与周围像索存在明显像素点作为关键点, 之后计算每个关键点的BRIEF描述子, 从而唯一确定ORB特征点.
具有旋转不变性和尺度不变性
特征点匹配就是再不同的图像中寻找统一物体的同一个特征点
9.3.1 DescriptorMatcher类介绍
DMatch 类型是OpenCV4 中用于存放特征点描述子匹配关系的类型,类型中存放着两个描述子的索引、距离等.
与特征点detect()函数很像,,只有创建了类继承了虚类后,才能使用match函数
9.3.2 暴力匹配——BFMatcher.match()
暴力匹配会对每个查询描述子寻找一个最佳的描述子,但是有时这种约束条件也会造成较多错误匹配,例如某个特征点只在查询描述子图像中出现,这种情况在另一幅图像中不会存在匹配的特征点,但是根据暴力匹配原理,这个特征点也会在另一幅图像中寻找到与之匹配的特征点,造成错误的匹配.
9.3.4 FLANN匹配——FlannBaesdMatcher.match()
虽然暴力匹配的原理简单, 但是算法的复杂度高, 当遇到特征点数目较大的情况时, 会严重影响程序运行时间,因此OpenCV 4 提供了快速最近邻搜索库( Fast Library for Approximate Nearest Neighbors. FLANN) 用于实现特征点的高效匹配.
k-d树结构:https://blog.csdn.net/u011067360/article/details/23934361
k-means聚类:https://www.cnblogs.com/pinard/p/6164214.html
Hierarchical Clustering层次聚类:https://blog.csdn.net/zhangyonggang886/article/details/53510767
层次聚类(Hierarchical Clustering)是聚类算法的一种,通过计算不同类别数据点间的相似度来创建一棵有层次的嵌套聚类树。在聚类树中,不同类别的原始数据点是树的最低层,树的顶层是一个聚类的根节点墨尔本城比赛前瞻。创建聚类树有自下而上合并和自上而下分裂两种方法,本篇文章介绍合并方法。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fcKn9Lj6-1666660001284)(https://gitee.com/lyz-npu/typora-image/raw/master/img/20161207212645385)]
9.3.5 RANSAC优化特征匹配
为了更好地提高特征点匹配精度, 我们可以采用RANSAC 算法。 随机抽样一致算法( RANdom SAmple Consensus )
**RANSAC:**https://blog.csdn.net/robinhjwy/article/details/79174914,,,,,,非常重要的算法
使用了数据集内随机挑选的点拟合出一个模型,并计算数据集的点是否落在阈值内成为内点,不断迭代,迭代过程依据内点数量,计算找到内点最多效果最好的拟合的模型的数据,,,,,,,其价值在于去除离群点outlier,然后再使用剩余的inlier内点,使用xxx拟合算法求出较为准确的模型
单应矩阵理解:https://blog.csdn.net/lyhbkz/article/details/82254893
通过该函数优化匹配的特征点,需要判断输出的掩码矩阵中每一个元素是否为0. 如果不为0.那么表示该点是成功匹配的特征点, 边而在vector
10.1.1 单目相机模型
测量内参系数是使用摄像头之前首先要进行的步骤
相机的内参矩阵只与相机的内部参数相关, 因此称为内参矩阵。通过内参矩阵可以将相机坐标系下任意的三维坐标映射到像素坐标系中, 构建空间点与像素点之间的映射关系.
10.1.2 标定板角点提取
https://zhuanlan.zhihu.com/p/94244568
findChessboardComers()函数检测到的内角点坐标只是近似值,为了更精确地确定内角点坐标,可以使用我们前面介绍过的计算亚像素角点坐标的comerSubPix()函数.此外. OpenCV4也有专用于提高标定板内角点坐标精度的find4QuadConerSubpix()函数。
10.1.3 单目相机标定
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CpCz6Uum-1666660001286)(https://gitee.com/lyz-npu/typora-image/raw/master/img/%E5%9B%BE10-6.png)]
相机标定主要是计算机相机内参矩阵和相机畸变的5个系数
10.1.4 单目相机校正
在得到相机的畸变系数矩阵后,可以根据畸变模型将图像中的畸变去掉,生成理论上不含畸变的图像,
一:initUndistortRectifyMap()——remap()
二:unidistort()
10.1.5 单目投影
单目投影是指根据相机的成像模型计算空间中三维坐标点在图像二维平面中坐标的过程.OpenCV4 中提供了projectPoints()函数用于计算世界坐标系中的三维点投影到像素坐标系中的二维坐标
10.1.6 单目位姿估计
.本章中将重点介绍如何检测视频中移动的物体,并对移动物体进行跟踪, 主要的方法有差值法、均值迁移法和光流法.
11.2.1 均值迁移法实现的目标跟踪
均值迁移法能够实现目标跟踪,其原理是首先计算给定区域内的均值, 如果均值不符合最优值条件, 那么将区域向靠近最优条件的方向移动, 经过不断地法代来找到目标区域。
均值迁移法又可以称为爬山算法。
11.2.2 自适应均值迁移法实现的目标跟踪
自适应均值迁移法对均值迁移法进行了改进,使得可以根据跟踪对象的大小自动调整搜索窗口的大小。除此之外,改进的均值迁移法不但能返回跟踪目标的位置, 而且能够返回角度信息.
光流是空间运动物体在成像图像平面上投影的每个像素移动的瞬时速度, 在较短的时间间隔内可以等同于像素点的位移。在忽略光照变化影响的前提下,光流的产生主要是由于场景中目标的移动、相机的移动或者两者的共同运动。光流表示了图像的变化,由于它包含了目标运动的信息, 因此可被观察者用来确定目标的运动情况,进而实现目标跟踪.
光流法要求像素移动较小距离,但是有时得到的连续图像中像素的移动距离较大,此时需要采用图像"金字塔" 来解决大尺度移动的问题.
根据计算光流速度的像素点数目, 光流法可以分为稠密光流法(所有像素都要使用)和稀疏光流法.(只使用部分像素点)
11.3.1 Farneback多项式扩展算法
稠密光流法常用于相机固定的视频数据的目标跟踪.
11.3.2 基于LK稀疏光流法的跟踪
https://blog.csdn.net/a_31415926/article/details/50515835
calcOpticalFlowPyrLK()函数需要人为输入图像中稀疏光流点的坐标,通常情况下可以检测图像中的特征点或者角点,将特征点或者角点的坐标作为初始稀疏光流点的坐标输入
最大的问题:角点数目越来越少,因此需要时刻统计跟踪的焦点数目,当角点数目小于一定阈值时,需要再次检测角点,以增加角点数目。如果图像中有不运动的物体,那么每幅图像中都能检测到这些物体上的角点,从而使得角点数目一直高于阈值,然而这些固定的特征点不是我们需要的,因此需要判断角点在两帧图像中是否移动,删除不移动的角点,进而跟踪移动的物体。

