刚结束一段实习,图像算法工程师。总结一下图像算法的几个基本的操作,图像操作算子各式各样,各显神通,光是滤波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. Egret白鹭H5小游戏开发入门(二)

    前言: 昨天的文章中简单的介绍了Egret白鹭引擎从安装到基本的使用配置等问题,今天着重介绍H5小游戏开发的起步阶段,如Wing面板的使用,素材的处理,类的说明,开始布局等等. 整体概况: 根据上一篇 ...

  2. list集合的排序Comparator和Collections.sort

    一个例子 package sortt; import java.util.ArrayList; import java.util.Collections; import java.util.Compa ...

  3. Android中GridView通过自定义适配器(未优化)实现图文视图排列

    Android中GridView组件用来以网格方式排列视图,与矩阵类似,当屏幕上有很多元素(文字.图片或其他元素)需要显示时,可以使用该组件.下面我们通过代码实现如下图例(为了方便截图,将事件处理(土 ...

  4. IOS开发之功能模块--输入框随着键盘的位置移动而移动

    废话不多说,先直接上效果图: 先熟悉一下在Cocoa框架中会用到的key键: 然后直接上Demo的源码截图: 看代码之前,补充说一句,Demo中的文本框以及文本框的背后灰色的View是通过storyb ...

  5. Storm基础

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

  6. [Java编程思想-学习笔记]第4章 控制执行流程

    4.1  return 关键字return有两方面的用途:一方面指定一个方法结束时返回一个值:一方面强行在return位置结束整个方法,如下所示: char test(int score) { if ...

  7. ansible使用文档

    假设A机器上安装ansible yum install ansible vim /etc/ansible/hosts 对每个主机加key认证ssh-copy-id -i ~/.ssh/id_rsa.p ...

  8. Replication-Replication Distribution Subsystem: agent xxxxxx failed. Column names in each table must be unique

    最近遇到一个关于发布订阅(Replication)的奇葩问题,特此记录一下这个案例.我们一SQL SERVER数据库服务器出现大量告警.告警信息如下所示: DESCRIPTION: Replicati ...

  9. .replace(R.id.container, new User()).commit();/The method replace(int, Fragment) in the type FragmentTransaction is not app

    提示错误:The method replace(int, Fragment) in the type FragmentTransaction is not applicable for the arg ...

  10. 解决webkit浏览器中js方法中使用window.event提示未定义的问题

    这实际上是一个浏览器兼容性问题,根源百度中一大堆,简要说就是ie中event对象是全局变量,所以哪里都能使用到,但是webkit内核的浏览器中却不存在这个全局变量event,而是以一个隐式的局部变量的 ...