Vue框架:
从项目学Vue
OJ算法系列:
神机百炼 - 算法详解
Linux操作系统:
风后奇门 - linux
C++11:
通天箓 - C++11
Python常用模块:
通天箓 - python
计算机视觉系列博客分两条主线:算法理论 + opencv实操
理论来源于[计算机视觉(本科) 北京邮电大学 鲁鹏 清晰完整合集](https://www.bilibili.com/video/BV1nz4y197Qv/?spm_id_from=333.337.search-card.all.click&vd_source=78f225f12090c7d6b26a7d94b5887157)
实操将以kaggle具体比赛为例讲解opencv以及神经网络
人类视觉:
image / video -> 虹膜采集光 -> 视网膜成像 -> 传递到大脑 -> 解析看到的相
优点:利于分辨,150ms分辨是否动物
缺点:不利于动态视觉,多种语义分割,错觉感知(克林顿、静态图在动、同一个颜色)
计算机视觉:
image / video -> ccd / cmod成像 -> 计算机分析
CV目的:
通过像素了解真实含义(语义鸿沟)
图像给我们的信息:(两大研究方向)
历史线:
应用:
电影特效、3D重建、人脸检测、虹膜识别、指纹识别、自动驾驶、行人检测、虚拟现实、天气识别、
卷积核/滤波核:每个点的权值
如:权重相等的k=1/9 & [[1,1,1],[1,1,1],[1,1,1]]是平均卷
卷积操作:每个点的3*3矩阵翻转后乘像素值,加和赋值
m-k n-l 表示翻转后对应 k l
卷积操作的性质:
填充padding:
四个边的点缺失了邻居,无法卷积,需要padding。
五种填充方式:填0 填1 环状填原图 拉伸边 镜像边。防止卷积几次之后图像消失
卷积核大赏:
几何意义:
高斯卷积核两个参数:
高斯核卷积勾股定理:
两次直角边σ做高斯卷积 = 一次斜边σ’做高斯卷积
σ 斜边长 2 = σ 直角边长 2 + σ 直角边长 2 σ_{斜边长}^ 2 = σ_{直角边长}^2 + σ_{直角边长}^2 σ斜边长2=σ直角边长2+σ直角边长2
高斯核分解:分为x & y方向分别高斯
高斯核分解的应用:降低时间复杂度,大核可以用两次小核模拟
m*m的卷积核 对 n*n的图像 卷积:原本时间复杂度:O(n^2 * m^2),现在( n^2 * m)
高斯噪声:高斯噪声模型本身含有σ,噪声的σ越大,想要消除噪声的高斯核所需σ和窗宽越大,但是同时边缘也会被模糊的越大
中值滤波器:本身没有固定权值,每到一个图像,将窗框内所有像素值从大到小排序(非线性),选取中位数直接放到当前点上,不管重复:但是乘法求和是线性的
中值非平均的优缺点:
α == 1:
锐化:[[0,0,0],[0,2,0],[0,0,0]] - k=1/9 & [[1,1,1],[1,1,1],[1,1,1]]
原图i*卷积核e - 均值平滑/去噪i*卷积核g = 边缘图
原图 + 边缘图i*卷积核e = 锐化i*卷积核(2e - g)
最后的结果又称为拉普拉斯高斯,高低都比原本高斯大且尖锐
边缘的定义:边缘是图像强度函数中快速变化的地方,图像中的大多数语义和形状信息都可以编码在边缘中。
边缘4种分类:表面不连续,深度不连续,表面颜色不连续,光照不连续
边缘的信号描述:白色是255,值高于黑色的0,信号函数突变的地方就是边缘,对于突变的描述可以使用一阶导数
图像x方向导数公式:
将趋于0的变量直接置为1,得到CV中的导数公式:
一点(x,y)的水平导数 = - 该点像素值 + 右边点像素值 (-1,1)
X方向的导数(-1,1)可以检测纵向的边缘
Y方向的导数(-1,1)或者(1,-1)可以检测横向的边缘
典型:-1, 1
Prewitt算子:
Mx = [[-1,0,1],[-1,0,1],[-1,0,1]]
Sobel算子:对噪声敏感更低
Mx = [[-1,0,1], [-2,0,2], [-1,0,1]]
可以拆分为[1,2,1] * [-1,0,1],相等于先平滑去噪声,再求边缘
My = [[1,2,1], [0,0,0], [-1,-2,-1]]
Roberts算子:斜边
Mx = [[0, 1], [-1, 0]]
去噪声:噪声使得图像信号持续微小震荡,直接求梯度发现处处梯度变化剧烈,到处都是边,所以需要先去噪,采用高斯滤波(padding之后避免值消失)
导数算子进行卷积。
用卷积的结合律可以减少时间复杂度:
高斯偏导模板:高斯核进行求导
同样随着σ变化,获得的边越来越粗狂,可以按照自己的需求选择σ
虽然高斯核类似于softmax全员正数,但是高斯偏导核有着负数
高斯核元素求和是1,但是高斯偏导核元素求和是0(没边不能检测出边)
先看传统算法的优劣:
高斯模糊去噪(导致边变粗)
直接求每个点的梯度模值:
对每个点X方向(-1,1)卷积,对每个点Y方向(-1,1)卷积
卷积结果平方和开方得到该点梯度值
设定噪声识别阈值:
梯度值低于阈值的点被识别为噪声,删除(设为0)
这个操作会有两个问题:
导致过滤得到的点都被认为是边,从而加宽了边
门限设置的不恰当导致删除了很多实际边,或者噪声出来了很多假边
Canny算法采用了双门限:先用高门限确定真边,然后降低门限增加弱边缘。且假设所有的真弱边都和强边相连,所以就算噪声通过了低门限,但是不与强边连接时也被删除。
非最大化抑制:细化边缘
一个点和梯度方向的邻居比较梯度值,仅留下梯度最大者
如果梯度方向不是整数,这个方向没有邻居,那就用线性插值造一个邻居
Canny算法过程:
我们知道哪些点在线上时(所有点都是线上点),采用最小二乘法拟合线,求线条y=mx+b的m & b
y方向能量函数E的定义和计算:所有点到线的偏移
y方向对m和b求导,找到E的最小值:
缺点:(疑水平直线没有y,x和y没有关系,不能求解水平直线)
而且垂直直线y-y’恒为0,也不能求解垂直直线
对于摄像机旋转带来的线条角度变化不能应对
有外点,ρ函数规定多远的外点就不予考虑:
σ太小则所有点对直线的贡献都差不多
σ太大则和最小二乘差不多,近者权值大,远者权值小
由于ρ函数非线性,所以不能求导等手段求最小值,需要使用随机梯度下降等等下降法
外点较多,甚至有很多外部线
如下四步:
多次执行采样数N,大概需要几次的计算方法:
s点数是由模型固定,p正常概率和e外点率都是指定
e表明是说不在线上点的概率,其实是说在线上点的概率
上式中e很难人为指定,对数据集很有信心就设高点,没有信心就低点,但是对数据集不清楚的时候,可以采用自适应的RANSAC方法:
自适应过程:
N=+∞,sample_count =0
While N > sample_count:
选择样本拟合直线,计算线上点的数量
set 外点率e = 1- (线上点的数量)/(总点数)
从e重新计算N:N=log(1-p)/log(1-(1-e)^s)
将sample_count增加1
如果某一次迭代的N=100,当前N是150,那就再迭代50次
如果某一次迭代的N=100,当前N是120,那就结束
优缺点:
搭配最小二乘法:
RANSAC找到的线仅仅基于两个点和给定的距离阈值,可以说拟合的直线在这个范围内,但是大概率不是当前这条线。
当找到所有内点后,使用全方向的最小二乘法找到的直线更接近所有点
仿射变换:找到不同图片中的特殊点之后需要将他们对应起来
六个参数需要三对点构成三个方程,3个x和3个y
先随机找三对对应点,用剩下的点为构建的abcdef矩阵投票,最终得到一个可以满足最多对应的abcdef矩阵
不同的指纹和目标指纹都构建最优的abcdef矩阵,分别用各自的最优矩阵查看含有多少个对应点
让每个特征为所有与其兼容的模型投票,
希望噪声特征不会一致地投票给任何一个模型,
只要有足够的特征剩余,不要遮挡太多,就可以达成一个好的模型
初始投票方法:
初始投票的缺点:ab参数本身无限,且垂直直线需要无限个a
极坐标投票法:
梯度改进法:使用梯度的模和梯度方向为其投票
哪个格子的得票数最多,则这个格子对应的直线是目标直线
对于正方形则明显投票给了四个点(最亮),代表四条直线
对于圆形则明显没有达成一致的点,只是在一个范围内有一条带子
当我们使用Canny检测一个边缘点时,我们也知道它的梯度方向,这意味着点投票到的线是唯一确定的
修正霍夫变换:
对于每个边缘点(x,y)
θ=(x,y)上的梯度方向
ρ=x cos θ+ysin θ
H(θ, ρ) = H(θ, ρ) +1
圆三个参数:(x-a)^2 + (y-b)^2 = r^2,所以投票空间是三维
给定圆上一个点(x,y),直接在XOYOR空间确定一个R=0的点
因为圆弧梯度方向固定,所以圆形要么沿着梯度,要么背离梯度,每次确定圆半径后为两个点分别投出圆心票:
圆心票数最多的点(x,y,r)就是圆心,也就知道的圆的形状
角点满足第一步的四个要求,且角落附近的区域,图像梯度有两个或两个以上的主导方向,且独特而可重复
角点检测的基础方法:
小窗口在任何方向移动,窗口内都会产生很大的强度变化
移动[u,v]时窗口w(x,y)的外观变化:
E(u,v) = ∑w(x,y)·[I(x+u, y+v) - I(x,y)]^2,I表示Image本身,w(x,y)也是中心大而周围小
可以解决光照、平移、旋转
PPT:
用于检测图像中的角点(corner),即两条边缘交汇处的像素点,步骤:
图像预处理:首先,将输入图像转换为灰度图像。
计算图像每个像素处的高斯梯度:使用一种梯度计算方法(如Sobel算子)计算图像在水平和垂直方向上的梯度。这可以帮助我们捕捉图像中的边缘。
计算每个像素周围高斯窗口内的秒矩矩阵M:对于每个像素点,使用计算得到的梯度信息来计算结构张量秒矩矩阵,它是一个2x2的矩阵,用来描述该像素点周围区域的梯度分布情况。
计算角点响应函数:通过计算结构张量的特征值(特征值代表梯度的变化程度)来评估每个像素点的角点特性。Harris角点检测使用以下角点响应函数:
R = det(M) - k * trace(M)^2
其中,det(M)表示结构张量的行列式,trace(M)表示结构张量的迹(即主对角线上元素的和),k是一个经验参数(通常取值为0.04 - 0.06),用于调整响应函数的敏感度。
阈值处理:根据计算得到的角点响应函数,对每个像素点进行阈值处理,将响应函数大于设定阈值的像素点标记为角点候选点。
非极大值抑制:在角点候选点,也就是所有找到的响应函数局部最大值中,对相邻的像素点进行非极大值抑制,只保留响应函数最大的像素点作为最终的角点。
显示角点:根据检测到的角点坐标,在原始图像上标记出检测到的角点位置。
不变性invariance:变换后的图像角点位置不改变。
F(T(img)) = F(img)
协方差covariance:如果同一图像有两个变换后的版本,应该在对应的位置检测特征
F(T(img)) = T’(F(img))
目标:在同一幅图像的缩放版本中独立检测对应的区域需要尺度选择机制来寻找与图像变换协变的特征区域大小。
高斯二阶导零点:
边缘是图像变化剧烈的地方,则高斯一阶导的极值,对应高斯二阶导过零点(不是一直处于零点的地方):
为卷积乘σ^2,使得信号不衰减:给定图像后计算得到方差σ,到拉普拉斯中算出圆半径
高斯拉普拉斯算子:用于二维斑点检测的圆对称算子
拉普拉斯函数对半径为r的二元圆的最大响应是多少?为了得到最大的响应,拉普拉斯函数的零点必须与圆对齐
因此,最大响应出现在σ=r/√2处。
也就是说,当找到最大响应时,将此时的σ乘√2 = r
步骤:
拉普拉斯检测是一种简单而有效的边缘检测方法,特别适用于对图像中细节和纹理的检测。然而,由于离散二阶导数对噪声敏感,拉普拉斯检测可能会受到噪声的干扰,产生不稳定的边缘结果。因此,在实际应用中,通常会与其他图像处理技术(如高斯滤波)结合使用,以提高边缘检测的质量和稳定性。
求高斯函数在空间和尺度上的差异的局部最大值
DOG函数:不需要二阶导,两次高斯核卷积做差即可,且效果接近拉普拉斯核
而且两次卷积可以先用σ高斯核卷后,继续用((kσ)^2 - σ^2)开方得到kσ卷积结果,且两次卷积因为窗框都是2σ+1,所以窗框小了 计算量都比直接kσ卷积计算量小
且可以对图像进行放缩,最后在放缩中检测的圆R和不放缩中检测的圆R差异就是放缩倍数。
这里的放缩其实在图像中直接隔点采样即可
使用5个不同σ对图像进行卷积的结果做差,可以得到4张等效拉普拉斯卷积图,在四张拉普拉斯卷积图中,每三张进行一次非最大化抑制,得到一个合适的σ,一共得到了两个σ。
总结目标准备输出s个合适的σ时,k离散地进行取值,离散间隔为k = 2^(1/s)
仿射变换近似于大致平面物体和大致正射影相机的视点变化
要做到自适应椭圆可以借助harris角点检测工具:
找到SIFT或者拉普拉斯构建的圆,找到圆中像素梯度变化最剧烈的两个方向,沿着梯度方向改变圆半径,直到两个方向梯度变化一样,得到λ1=λ2的椭圆,此时椭圆内角度不同
分格子投票,每个格子内梯度方向投一个角度,统计最多得票的角度,将椭圆内角度扭转到此
不依靠强度判别图像相似度,如白天和晚上照片光阴强度差异很大。继续投票,每个小格子内给自己梯度方向投票:
按照投票将SIFT区域序列化:16个格子 * 每个里面8个方向的票数 = 128位,比较SIFT椭圆内的128位序列就能知道相似度。(小格投票可以防止误识别我爱中国和爱我中国一样,我!=爱)
创建高斯差分金字塔-用于模拟观察者距离物体的远近程度及模糊程度:
关键点位置确定:
关键点方向分配:
特征点匹配:
使用关键点的描述子,使用特征点之间的欧氏距离或相似度度量来找到最佳匹配对
如果和第一张图片对应点相似度明显高于和第二张图片对应点的相似度,那么视为有效对应点。反之,如果第一张图片对应点相似度和第二张图片差异不大,那么这个特征点有可能出错,就不参与判断过程。
步骤:
定义两个点之间的距离:
上述方法的两个缺点:
从小框逐渐过度到大框,当框内纹理特征变化很小时说明窗口大小合适了
可以选取很多种滤波器,在D维空间上进行Knn或者kmeans。常用的有48种纹理滤波器(6种方向+4种大小+点/边/bar)
卷积核尺寸越大,关注的内容越宏观,得到的图片越抽象
优点:非常简单,总可以收敛到误差函数的局部最小值
缺点:!需要人为指定分类数k 2. 内存开销很大 3. 对初始情况很敏感 4.对离群值敏感 5.只能找到“球状星团”
对初始值敏感可以通过两种方法避免:密度法逐个找距离当前最远的最密集点 或 将空间等距离划分
对非球形分类可以通过GMM寻找
在单个特征点初始化窗口,
对每个窗口执行mean shift,直到收敛,出现接近相同“峰值”或模式的窗口
核心三步:
聚类:一个模式的吸引盆地中的所有数据点。
吸引盆地:所有轨迹都指向同一模式的区域
Mean shift算法是一种非参数的聚类算法,其主要用于数据聚类和密度估计。
步骤:
Mean shift算法的核心思想是通过不断迭代调整种子点的位置,使其向高密度区域移动,直到收敛于局部最大值。这样可以找到数据中的聚类中心,并将数据点分配到对应的聚类中心。
优缺点:
优:不假设分类一定是球形,只需要一个参数(窗口大小),分类数目不需要预先指定,噪点干扰很小
缺点:计算复杂且量大(但可以不对圈内走过的点进行计算),非常依赖窗口大小设置(窗口太大则分类数少,太小则分类数过多),维度太高时点很稀疏很难算重心
图论:图片中每个点都作为顶点,不同顶点的边权值为点的相似度。
找图片中所有点构成的网络的最小割,分开后也完成了图片的分割。
将图分割成段,删除段之间交叉的链接,最容易断开具有低亲和力的链接。分割之后相似的像素应该在相同的段中,不相似的像素应该在不同的段中。
点的相似度:
假设我们用一个特征向量x来表示每个像素,并定义一个适合于这个特征表示的距离函数,然后我们可以借助广义高斯核将两个特征向量之间的距离转化为相似度:
小σ:仅和附近的点相似; 大σ:可以和远处的点相似。
普通切割的缺点:最小切割倾向于切断非常小的,造成很多独立的细小区域,这可以通过归一化切割的所有边的权重来固定。
归一化切割前的权重:
考虑到两点多边,w(A, B) = A和B之间所有边的权值之和
数学证明:
步骤:
优点:是普遍性框架,可用于许多不同的特征和亲和公式。缺点:高存储要求和时间复杂性。倾向划分的块都等大
各种任务:
能够对图像或视频进行分类的算法设计:检测和定位对象;估计语义和几何属性;对人类活动和事件进行分类
加剧识别难度:1. 种类巨多,人类可以识别1W到3W个物体。2. 不同视角下的同一对象的照片像素差异很大。3. 光照使得同一对象像素差异很大。4. 图像的先验不是很准。5. 形变。6. 遮挡。7. 背景杂波。8. 内部类的变化。
三大问题:
表示——如何表示对象类别?密集,随机、特征点、多重特征点。哪种分类方案?
学习-如何在给定训练数据的情况下学习分类器;
认知-如何在新数据上使用分类器
表示:直接密集分割为小图装入词袋?或者也考虑小图之间的相对位置拓扑关系。
为了处理类内的可变性,使用概率模型来描述对象类别是很方便的。对象模型:生成型、判别型和混合型
判别模型:最近邻、神经网络、支持向量机、Boosting
生成模型:朴素贝叶斯(最优似然函数)、潜在迪利克雷分布,LDA,2D部件模型、3D信息模型。
起源于纹理识别中看到简单纹理可以区别物体,统计物体中不同纹理出现次数。
原理:抽取所有图片中的特征,之后的图片向相关特征中投票,统计最后得票最多的特征,这个特征初始来源于哪个图片,则这张图片应该也属于这类图片
文章的向量表示:常见的母词有1W维,一篇文章为这一万个词投票,形成一个自己特点的直方图。
步骤:
好处:丢几个小图也不影响,遮挡、平移、旋转造成的干扰很小。
坏处:没有考虑图片中各个小图片的位置关系。
空间金字塔算法(Spatial Pyramid)可以有效地处理不同尺度和大小的图像内容。
原理:一张图片由很多层特征投票构成
步骤: