几个常用的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
几个常用的CV知识点的更多相关文章
- atitit 商业项目常用模块技术知识点 v3 qc29
atitit 商业项目常用模块技术知识点 v3 qc29 条码二维码barcodebarcode 条码二维码qrcodeqrcode 条码二维码dm码生成与识别 条码二维码pdf147码 条码二维码z ...
- JAVA项目中常用的异常知识点总结
JAVA项目中常用的异常知识点总结 1. java.lang.nullpointerexception这个异常大家肯定都经常遇到,异常的解释是"程序遇上了空指针",简单地说就是调用 ...
- Python常用基础语法知识点大全
记得我是数学系的,大二时候因为参加数学建模,学习Python爬虫,去图书馆借了一本Python基础书,不厚,因为有matlab和C语言基础,这本书一个星期看完了,学完后感觉Python入门很快,然后要 ...
- python基础之列表常用操作及知识点小结
列表(list) List(列表) 是 Python 中使用最频繁的数据类型.列表可以完成大多数集合类的数据结构实现.它支持字符,数字,字符串甚至可以包含列表(所谓嵌套).列表用[ ]标识,是pyth ...
- 开发中常用的JS知识点集锦
索引 1.对象深拷贝 2.网络图片转base64, 在线图片点击下载 3.常用CSS样式记录(超出宽高省略展示/播放icon/按钮背景颜色渐变...) 4.对象深拷贝 5.对象深拷贝 6.对象深拷贝 ...
- iOS一些常用的小知识点
//获取全局的Delegate对象,这样我们可以调用这个对象里的方法和变量 [[UIApplication sharedApplication] delegate]; //获得程序的主Bundle N ...
- 常用的.Net 知识点
1.Replace C#:(using System.Text.RegularExpressions;) string txt = Regex.Replace(txtLog.Text.ToString ...
- 会议管家——常用的JQ知识点
一.seTimeout时间延迟 $(".ticket_one table td a").eq(0).click(function(){ editOd('57503394363048 ...
- 开发常用的 JavaScript 知识点总结
No1.语法和类型 1.声明定义 变量类型:var,定义变量:let,定义块域(scope)本地变量:const,定义只读常量.变量格式:以字母.下划线“_”或者$符号开头,大小写敏感.变量赋值:声明 ...
随机推荐
- iOS之自动调节输入文本框的高度
//自动调节输入文本框的高度 - (void)textViewDidChange:(UITableView *)textView{ float height; if ([[[UIDevice curr ...
- iOS多线程之3.NSThread的线程间通信
我们把一些耗时操作放在子线程,例如下载图片,但是下载完毕我们不能在子线程更新UI,因为只有主线程才可以更新UI和处理用户的触摸事件,否则程序会崩溃.此时,我们就需要把子线程下载完毕的数据传递到主线 ...
- entity Framework codefirst Migrations
一次数据迁移的记录 首先在vs工具里面使用打开程序包管理器控制台 在控制台上面选择程序集为数据访问层 注意配置生成app里面的连接字符串 在控制台输入 Enable-Migrations 会自动生成一 ...
- IOS开发基础知识--碎片24
1:兼容字体大小6plue跟它以下的区别 #define FONT_COMPATIBLE_SCREEN_OFFSET(_fontSize_) [UIFont systemFontOfSize:(_fo ...
- IOS开发基础知识--碎片37
1:iOS 使用NJKWebViewProgress做webview进度条 引入头文件: #import "NJKWebViewProgressView.h" #import &q ...
- SDWebImage的使用
- setItem:(CustomItem *)item { _item = item; // 占位图片 UIImage *placeholder = [UIImage imageNamed:@&qu ...
- postgresql 服务器端编程之hello word
create or replace function addjifen( iuserid text, iamout INTEGER) returns text AS \[ BEGIN return ' ...
- T-SQL 将存储过程结果插入到表中
解决方案1: CREATE TABLE #tmpBus ( COL1 INT, COL2 INT ) INSERT INTO #tmpBus Exec SpGetRecords 'Pa ...
- jdbc连接数据库的步骤 (转)
1.加载JDBC驱动程序: 在连接数据库之前,首先要加载想要连接的数据库的驱动到JVM(Java虚拟机), 这通过java.lang.Class类的静态方法forName(String classN ...
- C++STL - 模板的其他特性
之前已经总结过函数模板和类模板了,对于模板还有一些其他的特性,这篇主要介绍这些特性.主要都是一些特殊情况. 模板的其他特性 1.缺省参数 (1)类模板的模板参数可以带有缺省值,实例化该模板时,如果提供 ...