002目标检测(Object Detection)原理与实现(一)~(三)

Post date: 2015/7/12 下午 01:38:37

目标检测(Object Detection)原理与实现(一)

基于阈值图像处理的目标检测

从今天起开始要写一些关于目标检测的文章,涵盖从简单的阈值图像处理检测、霍夫变换(hough transform)检测、模版匹配检测(刚体匹配)、AAM+ASM+ACM(非刚体)匹配检测到近代机器学习方法检测,尽量贴一些代码,这些很实用。本篇就从阈值图像处理检测开始。阈值顾名思义就是一个分界值,做图像处理的都明白阈值的用途,但是考虑到各种观众,干脆把OpenCV中的各种阈值标识符和对应代码示意都贴出来,如(图一)所示:

(图一)

仔细阅读下(图一)中的各种伪代码,就很容易明白阈值函数的工作机制,其中src(x,y)是图像像素点值。下面就给出一个处理答题卡的例子,(图二)是从网上找到的一个答题卡样图,我们的目标是检测到哪些选项被涂黑了,然后根据坐标判定是哪个数字,其实根据坐标是有依据的,因为答题卡四个角有一些对准线,对齐后用扫描仪扫描后紧跟着经过算法处理就可以判断出考生选项,本篇文章就简化流程,考虑到涂的选项是黑色的,因此我们使用第二个阈值方法,经过处理后如(图三)所示。

(图二) (图三)

几乎perfect,嘿嘿,下面把代码也贴出来,python版本的。

[python] view plaincopy

    1. import numpy as np
    2. import cv2
    3. img=cv2.imread('anwser_sheet.jpg')
    4. grey=cv2.cvtColor(img,cv2.cv.CV_BGR2GRAY)
    5. retval,grey=cv2.threshold(grey,90,255,cv2.cv.CV_THRESH_BINARY_INV)
    6. grey=cv2.erode(grey,None)
    7. grey=cv2.dilate(grey,None)
    8. contours,hierarchy=cv2.findContours(grey.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
    9. newimg=np.zeros_like(grey)
    10. cv2.drawContours(newimg, contours, -1, 255)
    11. cv2.imshow('test',newimg)
    12. cv2.imwrite("processed.jpg",newimg)
    13. cv2.waitKey()

代码流程先是读取图像文件,接着转成灰度图,接着做个开运算(腐蚀后再膨胀),接着阈值处理,最后把目标轮廓画出,根据目标块的坐标可以大概的推算出对应的数字,接着秀一下打印出某个涂项,比如最后一个,那么只需要把

cv2.drawContours(newimg, contours, -1, 255) 改成 cv2.drawContours(newimg, contours, 0, 255)

第三个参数为负数表示打印所有轮廓,0表示打印最后一个选项,打印是倒着数的。如(图四)所示:

(图四)

基于阈值图像处理的目标检测一般只适应于自己能控制颜色和亮度的项目中,这也为什么规定答题卡要尽量使用黑色的(同一颜色方便阈值处理),另外这种方法也可以用在目标的三维重建上,如(图五)所示,用阈值的方法找到汽车上的标定点对后续点云的获取很有帮助,进而完成整个汽车模型的三位重建,此方法虽然简单,但对这几种场景很实用,通过简单的图像处理(各个阶段去噪)后,然后简单的查找下各种闭合小轮廓就OK了,好了,今天就说到这,比较简单,后续会越来越复杂些,用到的数学知识也越来越多。

(图五)

转载请注明出处:http://blog.csdn.net/cuoqu/article/details/9058735

目标检测(Object Detection)原理与实现(二)

基于霍夫变换和广义霍夫变换的目标检测

上节讨论了基于阈值处理的目标检测,今天就来讨论下基于霍夫投票的目标检测,霍夫投票打算分成两个小节,第一个小节简单的说下霍夫变换和广义霍夫变换(generalized hough transform),他们投票的权重都是相等的,下一节讨论概率空间中的霍夫投票,顾名思义他们的投票权重是不确定的。

先来看下霍夫变换(hough transform),霍夫变换一般适用于有解析表达式的几何形状目标检测,例如直线、圆、椭圆等。用个统一的解析表达式来表达他们:f(x,alpha)=0,其中x 是图形上点,alpha则是解析表达式参数,比如欧式坐标系中直线的参数就是斜率m和截距c(或者极坐标系中的theta和ρ),圆的参数则是原点和半径。霍夫变换的核心就是把图像空间的直线变换到参数空间(也叫霍夫空间),比如一个直线y=mx+c,给定一个点(x’,y’),把它代入直线方程,得到y’=mx’+c,其实此时仍然是一条直线(在参数空间的直线,斜率是-x’,截距是y’),图像空间和霍夫空间的对应关系如(图一)所示:

(图一)

(图一)中左图是图像空间,右图是霍夫空间(参数空间),对于图像空间中线段pq上任意一点带入直线方程后,都可以在霍夫空间中得到另外一条直线,二者是对偶的,比如如(图一)所示,把两个端点带入后,在右图中得到的两个对偶直线,而且斜率是负的。现在问题来了,机器是怎么知道pq是一条直线(假设还有其他噪声点存在的话)?我们不知道斜率也不知道截距,我们要做的就先假设图像中有一条直线,其方程为y=mx+c,我们要求他的参数,然后把图像空间中的每个点都代入直线方程,然后在霍夫空间里都产生了一条对偶直线,因为图像空间中的那条直线上的点共用一个斜率m和截距c,因此他们的对偶直线必然相交于一点,也就是说m,c的值是唯一的,在右图中也能体现出来。

直线的霍夫变换检测核心思想就是这些,但是考虑到斜率截距式直线表示法不能表示所有直线,比如直线X=CONSTANT时,斜率无线大,霍夫空间里无法表示此点,因此我们把直线方程转换成极坐标表示的形式:,思想还是一样,区别就是把参数m,c转换成了theta和ρ),另外图像空间中的点对应的霍夫空间的几何形状不是直线,而是曲线,如(图二)所示:

(图二)

(图二)中右图的亮点就是我们要求的参数,但是怎么求的,求交点?那也太麻烦了,霍夫投票方法此时就要登场了,你霍夫空间中的曲线也是个图像嘛,我有的是内存,对于个曲线上的每个点我都用一个字典来表示你们,字典索引就用霍夫空间的坐标(theta和ρ)来检索,字典的值表示该坐标上有多少个曲线点(字典的学名叫累加器:accumulator)。对于(图二)中的那个亮点对应的字典值肯定很大,其实我们就是找大的最大值,峰值表示图像空间中的很多点共用一个参数。该算法的实现步骤如下伪代码所示:

For each edge pixel (x,y) in image

For θ= -90 to 90

ρ= x cosθ+ y sin θ

++ H(iθ, jρ);

end

end

直观来说就是你给我一个图像空间中的点,我就在霍夫空间中计算很多字典,然后相同位置上加1,简单的说就是把霍夫空间分割了,分割的越精细越好,但是分的越细计算量也越大,毕竟图像点很多,这个平衡读者根据情况自己把握吧。累加器的示意图如(图三)所示:

(图三)

圆和椭圆也都是类似步骤,只不过圆有三个参数,而椭圆有5个参数,计算量更大。此算法实现在opencv里也有,直接调用一个函数即可,在此不多说,直接给一个OpenCV自带的图像进行检测直线的结果和他的霍夫空间示意图,如(图四)和(图五)所示:

(图四)

(图五)

(图五)霍夫空间中的峰值点可能不严格的在同一个坐标上,也就说图像空间中直线上的点并不严格的在同一直线上,我们要容许一部分误差的存在,判断峰值点是个技巧活。

下面进入广义霍夫变换(Generalized Hough Transform)。

前面也说了,霍夫变换只适用于具有解析表达式的形状,对于一般形状则无能为力,一般形状没有解析表达式,没有解析表达式,那我们怎么进入霍夫空间里呢?没有霍夫空间,那我们怎么投票?不投票怎么来检测物体?有条件就上,没条件创造条件也要上

。一般物体虽然没有解析表达式,但是他们有边缘,说的多一些,MARR教授一开始就说边缘是人眼检测判断物体的重要条件之一,所以计算机视觉早期出现了很多边缘检测算法。有了边缘就可以创造出切向量,切向量可以做参数吗?仔细考虑一下,信息太少,ballard在1980年提出了广义霍夫变换(generalized hough transform),它利用了如(图六)所示的参数:

(图六)

(图六)中的alpha表示参数,可以看出参数很多,参数空间肯定是高维的,不过不管他多少维,方法和上面类似,参数空间中投票嘛,考虑到这个方法选择了一个参考点,把图像中的点到参考点的距离和相对方位信息作为参数来检测物体,细心的同学可能感觉出来了,他和Hu moment(Hu矩)有些相似的地方,他们都需要一些模版来提取形状参数,但是它比Hu moment用到的信息多,而且是在霍夫空间中投票,可以抵抗一些噪声、遮挡因素的影响,因此他的鲁棒性更好。投票流程如(图七)所示,其中A[a]为投票字典(累加器):

(图七)

它的检测效果如(图八)所示:

(图八)

这节算是做个铺垫吧,为下节的霍夫投票在计算机视觉中的应用打下基础,因为今天的投票是“公平”的,每票的权重都一样,当遇到复杂问题时,比如部件的参数去投票时,权重需要区分对待,这些放在下个小节来说。广义霍夫变换的代码网上也有,如搜不到的同学想要的话,可以留言索取。

参考文献:

GENERALIZING THE HOUGH TRANSFORM TO DETECTARBITRARY SHAPES

目标检测(Object Detection)原理与实现(三)

基于霍夫森林的目标检测

上节说了霍夫变换(HT)和广义霍夫变换(GHT),今天就接着广义霍夫变换说下去,在广义霍夫变换中,每个投票元素(比如边缘像素中的点)在霍夫空间中累加投票的权重是相等的,每个元素投票的权重互不影响,这其实是假设了图像空间中的每个像素点是独立的,但现实是这样的吗?答案:不是,尤其是牵扯到我们今天的基于部件的投票时,这种投票元素互相独立的观点更站不脚,学过概率图模型(probabilistic graphic model)的都知道,图模型里有一种V结构,如(图一)所示:

(图一)

X1,X2是投票元素,Y是我们在霍夫空间中的投票,假设我们观察Y时,或者说给定Y时,就是观察图像空间中的目标,假设X1和X2是目标生成的,X1和X2是独立的吗?很明显不是,这些元素应该向Y投票的权重应该更大才说的通,而其他元素投更小的权重(图一也可以看出,当给定Y=1时,X1,X2的概率由0.25提高0.33)。这就是Judea peal提出的explain away问题(Even if two hidden causes are independent in the prior, they can become dependent when we observe an effect that they can both influence)。既然有现成的框架:概率图模型,或者严格的说概率模型,那我们就改进广义霍夫投票,进入概率空间。

先来说说霍夫森林吧,霍夫森林是Juergen Gall在2009发表在CVPR上的。它通过构建一个随机森林把图像块(patch appearance)直接映射成对目标重心位置的投票,找到了目标重心也就找到了目标,其他做法也有构建codebook来作为投票元素。无论用什么方法,我们都可以把他们看成像霍夫变换中图像空间里的像素点一样的投票元素,然后进入霍夫空间找峰值点来检测目标。别忘了今天的主题是进入概率空间进行投票,下面来看看作者是怎么进入概率空间的。作者构建一个随机森林模型,叉开一下,随机森林由N个决策树构成,这N个决策时互相独立,分别来对目标分类,最终由N个分类的数目类别多少来决定目标类别。每个决策树的训练样本是

,其中I是目标的一个局部图像块(patch),c是它的类标签(1表示是目标,0表示背景),d表示bouding box内图像块到目标中心的偏移(offset)矢量(2D),这个对后面的目标重心投票起着很大的作用;随机树生长的目的是使节点样本的类别和offset不纯度最小化,这两项的具体定义如(图二)中的公式(2)、(3)所示:

(图二)

节点上的分裂准则采用了像素值比较的方法,通过交替的最小化(公式一)来完成决策树的构建。

(公式一)

最后叶子节点记录两项重要的信息:CL表示正样本比例,DL样本偏移的集合,这两项(正样本比例和offset矢量)就是投票元素。另外,训练的时候作者也采用类似级联的方式,forest=5trees+5trees+5trees,即第一次5棵树生长完成后,一些分类比较困难的样本再用来训练下一批树。检测阶段,从图像上提取patch,然后在随机森林中的每个决策树上进行判处理,接着在霍夫空间中进行投票,对图像进行密集块采样,最后输出霍夫图像。不过话说回来,概率空间体现在何处?关键点就在于如何投票,假设E(X)表示目标重心在位置X的随机事件的话,

表示给定图像块时目标重心在位置X的概率,利用贝叶斯公式和一些等价替换,该概率可以分解如(公式二)所示:

(公式二)

(公式二)的最后一行有两项,第一项可以结合决策树叶子节点的DL用pazen窗来估计,而第二项则直接用叶子节点的CL来计算。这样(公式二)又可转换为(公式三):

(公式三)

不过(公式三)只是一个决策树的概率,考虑用到是随机森林,对所有决策树来个平均,计算下平均概率,如(公式四)所示:

(公式四)

这样就完成了一个patch在概率空间对其附近目标重心的投票,累加所有patch的投票如(公式五)所示:

(公式五)

检测结果如(图三)所示,不过要说的是,检测到重心并不能说明会严格的框住目标,对于不同尺度的目标,需要区分对待,换句话要增加一个参数scale,如果还想考虑bounding box的aspect ratio,那就在增加一个参数,不过计算量也会随着参数增加而指数增长。

(图三)

最后提下patch的构成,作者在实验中使用的patch成分为:3 channels were used (intensity, absolute valueof x- and y-derivatives),实验结果不错,但缺点也如上所述,实现代码Juergen Gall首页已挂出,还有一些细节实现请查阅参考文献。霍夫森林虽然进入了概率空间进行投票,但是毕竟是从随机森林中计算出来的,霍夫投票概率的好坏取决于随机森林获取的概率,而且投票元素和目标之间没有形成双向因果推理,这是他的瑕疵,结合着概率图模型,我们可以把概率空间中的霍夫投票理论整的更优美些,并且降低与随机森林之间的耦合度,使之可以扩展到任意概率获取方式,所以基于霍夫投票的目标检测打算再继续扩展一节。

参考文献:

Class-Specific Hough Forests for ObjectDetection. Juergen Gall

转载请注明来源:http://blog.csdn.net/cuoqu/article/details/9091555