• 深度学习与CV基础阶段的课程安排

    • OpenCV图像处理 3-4天 (大部分了解即可)

    • 深度学习基础+CV深度学习模型学习 4-5天 (重点)

    • 最后6天 目标检测 + 目标分割 (重点)

  • anaconda里面创建虚拟环境的同时指定Python解释器的版本:

    • conda create -n 虚拟环境名称 python=3.6.8

  • OpenCV基本操作:

    • 像素值一般使用8位无符号整型来表示($$0 \sim 2^8 - 1$$),即0-255表示像素点的明暗程度,越靠近0越暗,越靠近255越明亮;
    • OpenCV里面读取出来的图像默认的通道顺序是 BGR,使用matplotlib进行显示时需要将通道的顺序转换成RGB,img[:, :, ::-1];
    • 单个图像读取出来本质上是3维数组,(H(rows),W(cols), C);
    • MixUp:图像混合,一般用于图像增强,cv.addWeighted();
    • 插值的作用:图像在经过缩放之后,多出来的那些像素点的像素值的表示方法;
  • 几何变换:

    • warpAffine:仿射操作,包括平移、旋转、斜切等操作;
    • 任何矩阵的几何变换都可以通过代数的形式进行表达,矩阵乘法
    • 在图像领域,显示图像的时候Y轴的方向是向下的,坐标轴原点在图像的左上角

  • 图像旋转步骤:

    • 1、将图像的原点从左上角平移到旋转中心;
    • 2、以指定的旋转角度逆时针进行旋转;
    • 3、将原点从旋转中心平移回图像的左上角。
  • 图像旋转操作步骤:
    • 生成旋转矩阵:M = cv.getRotationMatrix2D((cols/2,rows/2),90,1)
    • 使用仿射变换API进行旋转:dst = cv.warpAffine(img,M,(cols,rows))
  • 仿射变换:
    • 1、获取仿射矩阵注意点:
      • 参数中两个点集,分别是对应的图像平面上任意不共线的三个点的坐标(三角形的三个顶点):M = cv.getAffineTransform(pts1,pts2)
      • 完成仿射变换:dst = cv.warpAffine(img,M,(cols,rows))
      • 仿射变换的性质:在原图像中具有平行关系的特征,仿射变换后,还会保持这样的关系。
  • 透射变换:
    • 1、获取透视变换矩阵:T = cv.getPerspectiveTransform(pts1,pts2)
      • 注意:参数中的两个点集,在图像平面上任取4个点,这4个点必须满足任意三点不共线(四边形的四个顶点);
    • 2、通过透视变换API进行对应的操作:dst = cv.warpPerspective(img,T,(cols,rows))
    • 仿射变换是一种特殊的透视变换
  • 图像金字塔:
    • 分为上采样 pyrUp() 和下采样 pyrDown()
    • 上采样是对图像进行放大,下采样是缩小,比例是固定的2倍
  • 形态学操作:
    • 操作的是二值图:灰度值只包含0或1。
    • 1、邻域:位置相邻,根据位置不一样,可以分为4邻域、D邻域、8邻域;
    • 2、连通性:
      • 位置相邻;
      • 像素的灰度值相似。
    • 腐蚀和膨胀:
      • 注意点:指定对应的核结构去对原始二值图进行腐蚀和膨胀的操作
      • 腐蚀:cv.erode(img,kernel,iterations)
      • 膨胀:cv.dilate(img,kernel,iterations)
      • 腐蚀能够消除一些噪声,让对应的目标区域或者线条变细;
      • 膨胀能够让目标结构或者线条变粗,而且会消除目标中的空洞。
    • 开闭运算:
      • 开运算:先腐蚀再膨胀
      • 开运算能消除圆二值图中目标周围的一些噪声;
      • 闭运算:先膨胀再腐蚀
      • 闭运算消除结构中孔洞;
      • API:cv.morphologyEx(img, op, kernel)
      • 开运算:op:cv.MORPH_OPEN
      • 闭运算:op:cv.MORPH_CLOSE
    • 礼帽(顶帽)和黑帽:
      • 礼帽:原图像与“开运算“的结果图之差
      • 作用是能够凸显原二值图中的一些有规律的噪声
      • 黑帽:”闭运算“的结果图与原图像之差
      • 作用是凸显目标结构当中的孔洞
      • API:cv.morphologyEx(img, op, kernel)
      • 礼帽:cv.MORPH_TOPHAT
      • 黑帽:cv.MORPH_BLACKHAT
  • 图像平滑:
    • 概念:
      • 噪声,是通讯过程,或者感光器件在成像过程中产生的一些对图像质量有影响的一些像素点,常见的噪声有椒盐噪声、高斯噪声
  • 均值滤波:利用滤波器(核结构、卷积核,filter,kernel),大小一般是奇数。
    • anchor:核结构的中心点,锚点
  • 高斯滤波:
    • 1、生成符合二维高斯分布的滤波器的权重
    • 2、对权重进行归一化
    • 3、使用归一化后的滤波器对原图像进行高斯滤波
    • 应用场景:原图像中包含的噪声都是高斯噪声
  • 中值滤波:
    • 使用像素点周围邻域的灰度值的中值作为这个像素点滤波操作之后的结果
    • 应用场景:原图像中包含噪声是椒盐噪声
  • 灰度直方图:
    • 作用:观察图像中像素强弱分布状况
    • 掩膜(mask、蒙版):
      • 提取感兴趣的区域
      • 屏蔽
      • 结构特征提取
    • 直方图均衡化
      • 提高原始图像的对比度
      • 全局的操作
    • 自适应均衡化:
      • 1、将整幅图像进行分块,8*8这样的数目的块
      • 2、分别对每一个小块做直方图均衡化
      • 3、对块的边界区域进行插值并进行块的拼接
      • 实现:
      • API:实例化自适应均衡化的对象:clahe = cv.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
      • 在原图像上进行应用:cl1 = clahe.apply(img)
  • 边缘检测:
    • 1、基于搜索,通过寻找图像的一阶导数中的最大值,sobel、Scharr
    • 2、基于零穿越,通过寻找图像的二阶导数中为零的点,Laplacian
    • Sobel算子:
      • 1、根据得到的卷积核去分别计算出X方向和Y方向的梯度
      • 2、然后对这两个方向的梯度进行合并
      • 3、对合并后的结果图进行展示
      • 注意:当我们指定ksize=-1时,此时的Sobel算子是Scharr算子
      • API中的Ddepth参数指的是存储每个像素所用的位数,一般为了防止计算出来的梯度被截断,损失部分信息,都会采用较大的位数存储,例如 CV16S,CV64F。
    • Laplacian算子:
      • 1、基于零穿越,即像素的二阶导去寻找一阶导数的极大值
    • Canny算子:
      • 迄今为止,效果最好的边缘检测方法
      • 1、取出噪声,因为边缘检测这样的操作对噪声敏感
      • 2、求取X方向和Y方向的梯度以及梯度的方向
      • 3、非极大抑制
      • 4、设置滞后阈值,通过设置minVal和maxVal判断该点像素是否为边界点,大于maxVal的被认为是真正的边界点,小于minVal的点被舍弃掉,介于这两个阈值之间的点,判断是否和真正的边界点相连,如果是,则被判断成边界点,反之,不是。
  • 模板匹配:
    • 1、先要有这样的一个模板图片
    • 2、根据模板图片形成的滑动窗口去原图片中寻找相似度最大的匹配位置
    • 3、根据得到的最大值对应的左上角像素的坐标以及模板的宽和高绘制匹配出来的矩形区域
    • 对原图像的尺度敏感
  • 霍夫变换:
    • 1、构建累加器,对于每一个直线上的点(x, y)分别用于统计不同 $$\theta$$ 角度计算下的 $$\rho$$ 值,存入累加器,如果这个数值在上述累加器中存在相应的位置,则在该位置上加1,对于不同的点,每次更新累加器中的值
    • 2、搜索累加器中的最大值所对应的($$\rho$$, $$\theta$$),用于表示图像中的直线。
  • 角点特征:
    • 用一个滑动窗口去观察它,在这个角点沿不同的方向去滑动,会引起窗口灰度值的变化,根据不同方向滑动灰度值变换的大小,我们就可以判断是否为角点
    • 沿着平行于边界的方向滑动,灰度值不变,沿着垂直与边界的方向滑动,灰度值也会发生变化
    • 角点沿着任意方向移动,灰度值大幅变化
    • 在图像内部滑动,灰度值不变
  • 怎么去评估一个特征提取算方法的好坏
    • 视角不变性、尺度不变性、光照不变性
  • Harris角点检测:
    • I:intensity,强度,对应图像上像素点的像素值大小
    • 检测过程:
      • 将最终的表达式进行正交相似对角化,可以得到M矩阵的特征值
      • 根据特征值的大小进行特征判断:
      • 1、特征值都较大,则为角点
      • 2、如果其中一个特征值远大于另一个特征值,那么就是边界
      • 3、如果特征值的绝对值都很小,那么就是平坦区域
    • API实现:
      • 角点响应值:R = det M − α(trace M)^2
      • API中的K值就是公式中的 $$\alpha$$ ,值越小,检测出来的可能的角点越多,反之,越少。一般取值为:0.04~0.06
      • dst = cv.cornerHarris(gray, 2, 3, 0.04)
      • 特性:具有旋转不变性,不具有尺度不变性
  • Shi-Tomas角点检测:
    • 角点响应值的近似方法:R=min(λ1, λ2)
    • 指定一个阈值,使用特征值中最小的那个和阈值进行比较
    • API:cv2.goodFeaturesToTrack(image, maxcorners, qualityLevel, minDistance)
    • 注意:Harris和Shi-Tomas检测出来的角点都是像素级的
  • SIFT(Scale-invariant feature transform):
    • 对于尺度不变特征的提取具有里程碑意义
    • 基本流程:
      • 1、在不同的尺度空间进行极值检测
      • 依据原图像构建不同尺度的图像金字塔,将原图首先进行上采样,获取更多的细节信息
      • 在每一层构建不同高斯模糊的图像,大小都是一样的
      • 采用高斯差分算法近似高斯拉普拉斯算法,减少计算量,然后对每一层的相邻的模糊图像进行高斯差分计算,如果这层有6张图像,那么计算之后会有5层新的图像生成
      • 然后对生成高斯差分图像进行极值点检测,对某个像素点的26(8 + 2*9)个邻域的像素点进行值的比较,如果是极大值,则被认为是一个关键点
      • 2、关键点定位
      • 设定一个灰度阈值(一般是0.03-0.04)去除噪声点,然后去除边界(沿用Harris角点检测的方法,分别去计算不同方向的曲率),设定一个阈值,小于这个阈值的可以保留,大于的作为边界进行舍弃
      • 3、关键点方向的确定
      • 依据极值点周围的像素点的梯度的幅值和方向,然后使用直方图对每一个方向区间内的梯度进行累加,累加之前对不同位置的梯度值进行高斯加权,体现位置的重要性
      • 根据绘制的直方图找到主方向和辅方向,超过主方向80%的角度,我们可以把它作为辅方向
      • 使用抛物线拟合插值得到精确的方向表示,最终得到关键点的一些信息(位置信息,方向,尺度)
      • 4、对关键点进行描述
      • 对目标点邻域内的像素进行高斯加权,然后计算梯度
      • 根据切分的块和计算的梯度进行插值
      • 最终以 4 4 8维的特征向量来描述关键点,作为它的描述符
  • SURF:
    • 基于SIFT的基础上做了一些优化,实时性比SIFT更好,计算精度更高
    • 计算得到的描述符可以和机器学习当中的一些算法进行结合,完成对应的特征的检测和分类
  • Fast(Features from accelerated segment test):
    • 思想:若一个像素周围有一定数量的像素与该点像素值不同,则认为其为角点
    • 步骤:
      • 1、选取一个像素点
      • 2、以r为半径作圆,将覆盖在圆周上的M个像素点找出来,然后将他们的像素值与中心点的像素值进行比较,假设r为3,那么M为16,最终如果有连续的12个或以上的像素点的差值符合与给定的阈值关系,那么我们就可以把该点判断为角点
    • 改进:
      • 1、选择与我们当前场景相关的训练图片
      • 2、找到对应的特征点,构成这样的一个多维的向量
      • 3、对这样的一些特征点的值进行判断并分类,根据判断结果,标注对应特征向量的目标值为True或者False
      • 4、利用这些特征值和目标值训练ID3 DecisionTree
      • 5、用构建好的决策树去快速的实现图像的角点检测
      • 6、非极大抑制:构建打分函数,将与角点的分数相近的一些小分数的点进行舍弃
  • ORB(Oriented Fast and Rotated Brief):
    • 构造金字塔,为Fast特征点添加了方向,从而使得关键点具有了尺度不变性和旋转不变性
    • 在不同尺度通过fast检测出来的角点进行Harris响应值的计算并排序,选取前N个特征点作为某尺度下的特征点
    • 计算以特征点为圆心半径为r的圆形邻域内的灰度质心位置,将从特征点位置到质心位置的方向做特征点的主方向
    • 特征描述使用的Brief算法来做:
      • 1、图像滤波,取出噪声,因为对噪声敏感
      • 2、根据适合的方法去选取点对
      • 3、根据选取的点对构建描述符,一般是256-512bit的这样的一个字符串
  • 视频追踪:
    • meanshift:
      • 1、使用视频第一帧中存在的目标区域,与后续视频读取出来的每一帧图像进行比对,获取最相似的区域,即为视频追踪的位置
      • 2、使用了形心和质心,感兴趣区域的灰度集中的质心,通过质心与形心的重合迭代,最终让质心与形心重合,即找到了最佳匹配位置
      • 3、先计算感兴趣区域的直方图,然后使用这个直方图去读取出的每一帧图像中去比对,通过反向映射直方图获取到最佳的匹配位置。
  • meanshift:
    • 缺点:当我的目标是运动状态的时候,在视频中的大小会发生变换,所以会影响到最终的检测结果,如果感兴趣的区域是均匀分布,效果可能不理想
  • camshift:
    • 对meanshift做了一个优化,能够检测并匹配运动中的目标物体,对一些尺度变化的场景效果更好,对于一些背景和感兴趣区域相似的场景,效果不好。
  • 人脸检测:
    • 使用的是能够检测出符合人脸特征的一些Haar特征,通过这样的一些Haar检测算子(卷积核),最后通过级联的AdaBoost检测器进行模型的训练,最后就可以将训练好的模型应用到实际的检测场景中
  • LBP(Local Binary Pattern):
    • 原始LBP:去检测像素点周围的3*3邻域内的像素点,对他们的像素值进行比较,分别使用0和1去标记,最后形成一个二进制码,对应的10进制数即为该点像素的像素值
    • 圆形LBP:以某个半径作圆,获取对应的邻域的像素点,然后进行像素值的比较,然后使用和原始LBP一样的方式进行目标像素点像素值的表示,和原始LBP一样,不具有旋转不变性
    • 旋转不变LBP特征:将得到的LBP特征进行旋转,使用最小值表示目标像素点的像素值
    • 等价模式(均匀模式):
      • 使用我们统计出二进制的LBP表示方法,去观察它的跳变次数,绝大多数LBP模式最多只包含两次从1到0或从0到1的跳变,那么我们就可以去统计这样的只包含两次跳变或者以下的这样的一些LBP特征去进行特征的提取
    • LBP特征提取方法,一般用在人脸检测场景,配合SVM算法完成人脸的检测
    • 是一种用来描述图像局部特征的算子
  • HOG(Histogram Oriented Gradient):
    • 流程:
      • 1、颜色空间归一化
      • 使用Gamma校正完成对原来的颜色空间进行校正,它是一种常用的非线性变换,在HOG特征提取中,Gamma值一般取为0.5
      • 效果:提升图像的对比度,让图像在局部阴影以及光照变化的场景中不受太大的影响,同时还能消除部分噪声
      • 2、梯度计算
      • 使用较小的矩形卷积核模板进行梯度的计算,分别求取X和Y方向的梯度并合并,以及计算梯度的方向
      • 3、构建梯度方向直方图
      • 首先将图像切分成多个cell单元,每个cell单元一般都是8*8的大小
      • 将每个cell单元计算出来的梯度进行直方图的绘制,无符号的梯度直方图,分成9个方向通道,然后根据求取的方向值,进行梯度的分配
      • 4、重叠块的直方图归一化
      • 通过构建一个block,也就是2*2个cell组成的区域,然后将这个构成的block快进行滑动,每滑动一次,可以得到9X2X2维的直方图特征向量,然后进行归一化
      • 5、构建HOG特征
      • 对上一步收集的每一个block直方图进行串联,得到最终的HOG特征向量
      • 应用:一般与机器学习算法模型SVM搭配进行行人检测