• 几个常用的CV知识点


    刚结束一段实习,图像算法工程师。总结一下图像算法的几个基本的操作,图像操作算子各式各样,各显神通,光是滤波filter这一个专题就可以有很多的技巧和功能。

    我从做过的两个小项目入手, 简单介绍一下该项目中使用到的cv算法。 

    车牌识别(中文车牌识别)

    项目地址: https://github.com/liuruoze/EasyPR

    项目介绍: http://www.cnblogs.com/subconscious/p/3979988.html

    整个车牌识别分为两个部分:车牌框的识别,和车牌内容的识别。 一般在图像处理的预处理阶段,会对图像进行滤波处理。

    对于RGB图像:

    (1),在不考虑图像颜色的影响的情况下,先将图像转成灰度图

    (2),需要考虑颜色的,可以设置颜色阈值处理,找出符合特定颜色的区域。

    对于灰度图:

    (1), 平滑线性滤波处理器

    平滑线性空间滤波器的输出是包含在滤波掩膜领域内像素的简单平均值。(也称为是平滑滤波器), 很直观地减小了图像灰度的尖锐变化。 (典型的随机噪声是由灰度级的尖锐变化造成的) 应用:一般将图像转成灰度图之后,对正常图像(600×600 至 1920×1080)进行3维度的平滑滤波处理, 得到一张消除了尖锐噪声的灰度图像。

    (2), 边缘检测 Sobel

    相反于平滑滤波器,该滤波器是属于锐化空间滤波器的一阶微分的细节滤波器,它们的特点是a, 在灰度不变(平坦段)微分值为0, (b), 在灰度阶梯或者斜坡的起点处的微分值不为0. (c), 沿着斜坡的微分值非零。 中心点就是微分值点x。

    所以对于Sobel操作算子, 采用x轴方向和y轴方向,两个方向去滤波处理。得到的图片就是对该图像进行一阶微分的结果。 微分求导数的公式:

     

    对于x轴方向的滤波: 滤波矩阵可以分解为两个向量的乘积,左边的向量 [1, 2, 1] 具有平滑的特点, 让中间的pixel和左右两边的pixel的差别尽可能变化小, 右边的向量[1, 0, -1] 是一个微分作用,对当前三个pixel的段进行微分处理。

    [1, 0, -1]      [1]

    [2, 0, -2]  =  [2] * [1, 0, -1]

    [1, 0, -1]      [1]

    应用: 算子滤波器矩阵的大小,关系到Sobel对图像边界检测的大小, 矩阵的维度越大,处理的图像的边界就越大。 对灰度图处理完之后,得到的是一张黑白二值的图像,含有检测到的sobel边界(白色),平坦部分为黑色。

    拓展: 因为内核大小为3, Sobel可能会产生明显的误差,Sobel选择的边界候选位置稍微宽些。

    处理的方法1: 将Sobel的平滑分算子[1, 2, 1]进行归一化;

    处理的方法2: 使用opencv内部提供的更加优秀的算子Scharr , 该函数仅仅作用于 3 ×3 的算子矩阵,运算速度一样快,且效果更加准确。

     

    Reference:

    (1), http://www.sxt.cn/u/4647/blog/5749 ;

    (2); opencv document

     

    Canny

    Canny 边缘检测是一个多状态的边缘检测算法,可以检测图像中的粗线条的边缘。 为了满足检测各种各样的边,Canny使用了微分变换,检测的最优函数由4个指数项的和构成,可由Gaussian函数的一阶导数近似。 Canny算法的流程:

    (1), 使用Gaussian filter平滑图像达到去除噪声;

    一般建议的filter大小是5×5

    (2), 找到图像的强度梯度

    使用Sobel检测水平x,垂直y方向。

    (3), 使用non-maximum suppression 去除边缘检测的多余重复的边 NMS 是一种边缘细化的技术, 可以将所有非局部最优的梯度压缩为0。

    具体算法:对梯度图像中的每一个像素进行, 先比较每一个像素点的边界强度(梯度)对正负方向的像素点的梯度值,如果这个值是最大的,保留,否则压缩掉这个值(置为0) paper: Efficient Non-Maximum Suppression , 2006

    (4), 使用双阈值 经过NMS处理之后,边界会变得很精确了,但是还存在一些由噪声和颜色变换引起的多余的边界点,这些可以很容易通过梯度阈值滤波器除掉,设置两个阈值,高阈值和低阈值, 对于一张梯度值图像的像素点,如果是大于高阈值,被置为强边界像素,若是低于高阈值且大于低阈值,被置为弱边界像素,低于低阈值的被压缩掉。

    (5),磁滞边界寻踪(Edge tracking by hysteresis) 强边界像素点一定会保留,对于弱边界像素点的去留是个问题,弱边界像素点有两个来源:噪声和图像边界。一般情况下,靠近强边界像素点的弱边界像素点是正确的图像边界,从一个弱边界像素点的周围8个像素点观察,一旦有一个是强像素点则保留,否则压缩掉该像素点。

    reference:

    (1), http://blog.csdn.net/pb09013037/article/details/45477591,

    (2), opencv document ;

    canny wikipedia

     

    颜色检测:

    检测特点颜色的区域:中国车牌的颜色一般分为两种:黄色和蓝色,所以根据车牌的颜色找到待定的区域块。(颜色在RGB中是呈现一个区域的,符合RGB特定域的是特定一种颜色)

    logo_detection SYSTEM

    SIFT 算法

    SIFT(Scale-invariant feature transform) 是一种检测图像的局部特征点的算法。 SIFT算法功能强大,包含很多技巧: 关键点的定位,尺度和变换问题,由多尺度空间和定向作用来解决; 几何失真由blurring和局部图像定向重采样解决,等等。

    SIFT算法的很稳定,对图像的一致变换,定向变换,仿射失真,光照变化保持效果不变。

    SIFT算法在本项目中的应用: SIFT算法从一系列的库图像中(指的是每一个可能存在的标签)提取关键点,并将其存在内存中,对于一幅新来的图像,分别比较库图像与新图像之间的特征点,根据特征向量的欧式距离找到待定的匹配特征。对于不同的图像有着不同的匹配成功的阈值,可以根据多次实验得到每一个特定库图像的成功匹配的阈值。

    算法步骤:

    (1), 尺度空间极值检测 使用连续的几个Gaussian Filter 去处理图像,得到几个不同scale的Gaussian-blurred 图像,不同的差分高斯空间DoG中的极值(极大值或者极小值)提取出来作为关键点。 对于不同scale的图像,又再次通过不同的 B 值的Gaussian Filter得到同一尺度下的不同octave的图像。对于同一尺度不同octave下的几张图像,若中心像素点是极值点则可以提取出来作为关键点

    (2),邻近数据的精确位置插值 DoG 尺度空间函数,其泰勒展开式是:

    可以根据上面的公式, x是该像素点的偏移量,如果x大于0.5,表示该极值点靠近另一个极值点,则该点被插值公式得到的值取代。否则加入待选关键点中。这样就可以减少很多的极值点

    (3),去除低对比度的关键点 根据D的泰勒展开式,求得偏移量x,如果x小于0.03, 则该关键点丢弃。 否则保留,并且最终的特征空间的位置是y+x, y是原关键点的位置

    (4),衡量边界响应 DoG函数有很强的边界响应,待选的关键点对噪声很敏感,对于DoG尺度空间图像的每一个像素点,可以求得该像素点的主曲率,主曲率高的像素点一般都是较差的极值点 利用二阶Hessian矩阵H的特征值,

    不妨定义较大的特征值为a, 较小的特征值为b,有ratio=a/b, 如果ratio大于rth=10,则抛弃该极值点。

    (5),设定方向 为了实现特征点的抗旋转,给每一个特征点基于局部图像的梯度方向设置一个或多个方向变量。然后,设计一个有36个格的方向histogram,每一个格包含10度,每一个极值点带权值(梯度量级和高斯权值)加入到histogram中,选择80%内的histogram高度的像素群,所以这就选择了有相同方向和scale基于原图像的像素点。

    (6)关键点描述 利用方向histogram对4×4的局部邻域进行量级和方向的统计。 归一化之后得到关键点。

     

    整个项目的算法实现

    基于opensift算法,opensift还多了一个处理操作,就是RANSCC算法,对两幅图像中的像素点进行匹配之前,对图像的噪声点或者说是偏离点进行丢失处理。

    RANSCC算法(random sample consensus ), 通过从数据样本中抽样,计算误差,直到,找到一致集的迭代算法。 被CV领域广泛应用。

    对于两幅图像的特征点匹配,有一个匹配阈值,达到良好的匹配值,才会被认为是正确的匹配。

    Reference:

    (1), http://blog.csdn.net/abcjennifer/article/details/7639681

    (2), sift wikipedia

  • 相关阅读:
    算法与数据结构 (四) 排序 一 交换类排序
    算法与数据结构 (三) 二叉树的简单应用 二叉查找树,二叉堆排序
    算法与数据结构 (二) 二叉树的简单实现,非递归的前序遍历 中序遍历 后序遍历
    算法与数据结构 (一) 链表,栈,队列的简单实现
    服务器端的redis和MySQL的远程连接的简单解决方案
    记一次自定义监听器使用spring 管理的bean的问题
    基于java开发的RBAC模型权限管理系统
    2019 本科java开发春招面经(实习)
    记一次Bootstrap框架下 使用Ajax失效的问题
    [转]在static代码块或static变量的初始化过程中使用ServiceManager提供的api的陷阱
  • 原文地址:https://www.cnblogs.com/zhang-yd/p/5952394.html
Copyright © 2020-2023  润新知