刚结束一段实习,图像算法工程师。总结一下图像算法的几个基本的操作,图像操作算子各式各样,各显神通,光是滤波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

几个常用的CV知识点的更多相关文章

  1. atitit 商业项目常用模块技术知识点 v3 qc29

    atitit 商业项目常用模块技术知识点 v3 qc29 条码二维码barcodebarcode 条码二维码qrcodeqrcode 条码二维码dm码生成与识别 条码二维码pdf147码 条码二维码z ...

  2. JAVA项目中常用的异常知识点总结

    JAVA项目中常用的异常知识点总结 1. java.lang.nullpointerexception这个异常大家肯定都经常遇到,异常的解释是"程序遇上了空指针",简单地说就是调用 ...

  3. Python常用基础语法知识点大全

    记得我是数学系的,大二时候因为参加数学建模,学习Python爬虫,去图书馆借了一本Python基础书,不厚,因为有matlab和C语言基础,这本书一个星期看完了,学完后感觉Python入门很快,然后要 ...

  4. python基础之列表常用操作及知识点小结

    列表(list) List(列表) 是 Python 中使用最频繁的数据类型.列表可以完成大多数集合类的数据结构实现.它支持字符,数字,字符串甚至可以包含列表(所谓嵌套).列表用[ ]标识,是pyth ...

  5. 开发中常用的JS知识点集锦

    索引 1.对象深拷贝 2.网络图片转base64, 在线图片点击下载 3.常用CSS样式记录(超出宽高省略展示/播放icon/按钮背景颜色渐变...) 4.对象深拷贝 5.对象深拷贝 6.对象深拷贝 ...

  6. iOS一些常用的小知识点

    //获取全局的Delegate对象,这样我们可以调用这个对象里的方法和变量 [[UIApplication sharedApplication] delegate]; //获得程序的主Bundle N ...

  7. 常用的.Net 知识点

    1.Replace C#:(using System.Text.RegularExpressions;) string txt = Regex.Replace(txtLog.Text.ToString ...

  8. 会议管家——常用的JQ知识点

    一.seTimeout时间延迟 $(".ticket_one table td a").eq(0).click(function(){ editOd('57503394363048 ...

  9. 开发常用的 JavaScript 知识点总结

    No1.语法和类型 1.声明定义 变量类型:var,定义变量:let,定义块域(scope)本地变量:const,定义只读常量.变量格式:以字母.下划线“_”或者$符号开头,大小写敏感.变量赋值:声明 ...

随机推荐

  1. xcode8打包ipa文件, application loader上传成功,但是iTunes Connect不显示构建版本

    最近更新的Xcode8.今天提交新项目时.按照以往的流程走 Xcode 编译ipa文件.applicaiton loader提交成功 但是.iTunes connect构建版本不显示.非常疑惑.平时等 ...

  2. Storm基础

    Storm基本概念 Storm是一个开源的实时计算系统,它提供了一系列的基本元素用于进行计算:Topology.Stream.Spout.Bolt等等. 在Storm中,一个实时应用的计算任务被打包作 ...

  3. Git 技能总结

    创建和使用git ssh key 首先设置git的user name和email: git config --global user.name "xxx" git config - ...

  4. 打开MySQL数据库远程访问的权限

    说明:转自,http://www.cnblogs.com/ycsfwhh/archive/2012/08/07/2626597.html    本人亲测方法1有效,方法2待验证 下载GPL版本安装 M ...

  5. YourSQLDba设置共享路径备份

    YourSQLDba可以将数据库备份到网络路径(共享路径),这个也是非常灵活的一个功能,以前一直没有使用过这个功能,最近由于一个需求,于是我测试了一下YourSQLDba备份到网络路径,中间遇到了一些 ...

  6. sql monitor生成不了报告& FFS hint不生效两个问题思考

    事情的发生就是这么偶然,一步步的深入才能汲取到更深入的知识~~ -------------------START------------------------------------------- ...

  7. css3【语法要点】

    语法要点 display: -webkit-box; /* 老版本语法: Safari, iOS, Android browser, older WebKit browsers. */ display ...

  8. linq to sql 输出SQL语句

    DataClassesDataContext db = new DataClassesDataContext(); db.Log=Response.Output; var result = from ...

  9. Hadoop Cluster 安装

    本篇源自Hadoop官网,先将中文翻译如下. 目标 本文章主要是描述如何安装和配置几个节点的Hadoop clusters,甚至于数以千计的节点数.为了了解详细的安装步骤,需要先了解如何安装在单台机器 ...

  10. [Java入门笔记] Java语言基础(五):数组

    简介 数组可用用于存储存储多个数据,Java的数组要求所有的数组元素具有一种相同的数据类型.一旦数组初始化完成,数组在内存中的空间被固定下来,长度不可改变,即使把数组的元素清空,所占用的空间依然被保留 ...