用matlab+opncv做基于viola-Jones算法可以实现多人脸检测吗?

2021-01-28 10:48发布

用matlab+opncv做基于viola-Jones算法可以实现多人脸检测吗?和单人脸有什么不同吗,网上找到的好像都是单人脸

用matlab+opncv做基于viola-Jones算法可以实现多人脸检测吗?和单人脸有什么不同吗,网上找到的好像都是单人脸

1条回答
给你三个亿
2楼 · 2021-02-23 10:23





在计算机视觉领域中,人脸检测或者物体检测一直是一个非常受关注的领域,而在人脸检测中,Viola-Jones人脸检测算法可以说是非常经典的一个算法,所有从事人脸检测研究的人,都会熟悉了解这个算法,Viola-Jones算法在2001年的CVPR上提出,因为其高效而快速的检测即使到现在也依然被广泛使用,OpenCV和Matlab中都将这个算法写进了函数库可以很方便的直接调用。虽然VJ人脸检测算法最初都是用来检测正面的人脸图像,对于侧脸图像的检测不是很稳健,不过这个算法依然有值得研究的价值。

这个算法包含以下几个重要的部分:1 利用Haar特征描述人脸的共有属性;2 建立了一种称为积分图像的特征,并且基于积分图像,可以快速获取几种不同的矩形特征;3 利用Adaboost算法进行训练;4 建立层级分类器。

利用Haar特征描述人脸的共有属性 

一般来说,人脸会有一些基本的共性,比如眼睛区域会比脸颊区域要暗很多,鼻子一般属于脸部的高光区域,鼻子会比周围的脸颊要亮很多,一张正脸图像,眼睛,眉毛,鼻子,嘴巴等的相对位置是有规律可循的。Haar特征考虑的是某一特定位置相邻的矩形区域,把每个矩形区域的像素相加然后再相减,总得来说,基本对应以下几种情形:




[−1,1],[1,−1],[1,−1,1],[−1,1,−1]


[-1,1],[1,-1],[1,-1,1],[-1,1,-1]






[1−1−11]


\begin{bmatrix}

1&-1\\

-1&1

\end{bmatrix}


我们以前都是针对单一像素做,现在需要针对矩形区域,相当于是把单个像素变成矩形区域,所以要对每个矩形区域先求和,然后再利用上面的算子做运算,这种特征称之为Haar-like特征。

积分图像与矩形特征 

正如上一节所说,为了计算Haar-like特征,需要对矩形区域的所有像素求和,一个图像所能形成的矩形区域有大有小,如果每个矩形区域都用遍历所有像素再求和的运算方法,无疑这个运算负担将非常巨大,所有VJ人脸检测算法用到了一种非常巧妙的数据结构,称为integralimage(积分图像),积分图像的原理非常简单,总得来说,就是对于图像中的任何一点,该点的积分图像值等于位于该点左上角的所有像素之和,表达式如下:





I(x,y)=∑x′≤x∑y′≤yf(x′,y′)


I(x,y)=\sum_{x'\leqx}\sum_{y'\leqy}f(x',y')  


并且积分图像满足如下关系:





I(x,y)=f(x,y)+I(x−1,y)+I(x,y−1)−I(x−1,y−1)


I(x,y)=f(x,y)+I(x-1,y)+I(x,y-1)-I(x-1,y-1)


其中


I

I表示积分图像,ff表示原来的图像,


x,y,x′,y′

x,y,x',y'表示像素的位置。所以一张图像的积分图像记录了这张图像上每一个像素点其左上角所有像素的和,如果把一张图像的左上角看做坐标原点,那么上面的表达式就是原点到该像素点之间的所有像素点的离散求和,这可以看成是一种积分,所以这也是积分图像名称的由来。利用积分图像,我们可以计算一张图像上任意一个矩形区域的像素和,积分图像的计算matlab 有一个库函数integralImage可以直接调用,

I=intergralImage(img) 

如下图所示,左边的图表示人脸图像,右边的图表示归一化之后积分图像。

  

有了积分图像,就可以很方便的计算图像中任何一个矩形区域的像素和,如下图所示:

  

为了计算矩形ABCD的像素和,利用积分图像可以表示如下:





Sabcd=I(D)−I(B)−I(C)+I(A)


S_{abcd}=I(D)-I(B)-I(C)+I(A) 


这意味着,任何一个矩形区域的像素和,都可以由积分图像


I

I上面的四个点来表示。VJ人脸检测算法用到了三种不同的矩形特征,分别是二邻接,三邻接,四邻接矩形,如下图所示:




很显然一个矩形可以由四个点来表示,二邻接矩形需要六个点表示,三邻接矩形需要八个点,而四邻接矩形需要九个点。


下面我们来看看,给定一张图像,有多少个矩形特征,VJ算法里用到的是24×2424\times24的图像大小,我们可以计算一个


24×24

24\times24的图像可以产生多少矩形特征。考虑水平方向与垂直方向,二邻接矩形有两种情况


1×2

1\times2和


2×1

2\times1,三邻接矩形也有两种情况


1×3

1\times3和


3×1

3\times1,而四邻接矩形只有一种情况


2×2

2\times2。下面列出每种邻接矩形可能的size大小。二邻接矩形(


1×2

1\times2): 


1×2

1\times2,


1×4

1\times4,


1×6

1\times6,…


1×24

1\times24,


2×2

2\times2,


2×4

2\times4,


2×6

2\times6,…


2×24

2\times24…


24×24

24\times24矩形的长以2的倍数增加,宽逐渐增加。三邻接矩形(


1×3

1\times3): 


1×3

1\times3,


1×6

1\times6,


1×9

1\times9,…


24×24

24\times24矩形的长是以3的倍数增加,宽逐渐增加。四邻接矩形(


2×2

2\times2): 


2×2

2\times2,


2×4

2\times4,


2×8

2\times8,


2×16

2\times16,…


24×24

24\times24矩形的长宽都是以2的倍数增加。

根据卷积定理,我们知道一个


W×H

W\timesH的图像与


m×n

m\timesn的filter做卷积,新生成的图像大小为


(W−m+1)×(H−n+1)

(W-m+1)\times(H-n+1),新图像的每一个像素其实就是原图一个


m×n

m\timesn的localpatch与


m×n

m\timesn的filter的乘积和。新图像有多少个像素,就对应着原图多少个


m×n

m\timesn的矩形。

我们用一段代码来求一个


24×24

24\times24图像会产生多少个矩形特征:因为


1×2

1\times2和


2×1

2\times1的情形是一样的,


1×3

1\times3和


3×1

3\times1的情形也是一样,所以我们只要分别计算一种情况,再乘以2就行了。

importnumpyasnp


a=np.zeros((3,2),dtype=int)

Count=np.zeros(3,dtype=int)

a[0,:]=[1,2]

a[1,:]=[1,3]

a[2,:]=[2,2]

Img_size=24


foriiinrange(3):

rec_h=a[ii,0]

rec_w=a[ii,1]

forxxinrange(rec_h,Img_size+1,rec_h):

foryyinrange(rec_w,Img_size+1,rec_w):

Count[ii]=Count[ii]+(Img_size-xx+1)*(Img_size-yy+1)

printCount[ii]


Total=Count[0]*2+Count[1]*2+Count[2]

print("Total:",Total)


最后可以得到:


1×2

1\times2:43200


1×3

1\times3:27600


2×2

2\times2:20736所以最终总的矩形特征为


43200×2+27600×2+20736=162336

43200\times2+27600\times2+20736=162336可以看到,一个


24×24

24\times24的图像最终会产生162336个矩形特征,这个维度远远高于图像本身的维度。不可能将所有的矩形特征都用,所有需要做特征选择,下一篇,我们将探讨如何利用AdaBoost来做特征选择与训练。


相关问题推荐

  • 回答 3

    换行。比如,print hello\nworld效果就是helloworld\n就是一个换行符。\是转义的意思,'\n'是换行,'\t'是tab,'\\'是,\ 是在编写程序中句子太长百,人为换行后加上\但print出来是一整行。...

  • 回答 42

    十种常见排序算法一般分为以下几种:(1)非线性时间比较类排序:a. 交换类排序(快速排序、冒泡排序)b. 插入类排序(简单插入排序、希尔排序)c. 选择类排序(简单选择排序、堆排序)d. 归并排序(二路归并排序、多路归并排序)(2)线性时间非比较类排序:...

  • 回答 70
    已采纳

    前景很好,中国正在产业升级,工业机器人和人工智能方面都会是强烈的热点,而且正好是在3~5年以后的时间。难度,肯定高,要求你有创新的思维能力,高数中的微积分、数列等等必须得非常好,软件编程(基础的应用最广泛的语言:C/C++)必须得很好,微电子(数字电...

  • 回答 28

    迭代器与生成器的区别:(1)生成器:生成器本质上就是一个函数,它记住了上一次返回时在函数体中的位置。对生成器函数的第二次(或第n次)调用,跳转到函数上一次挂起的位置。而且记录了程序执行的上下文。生成器不仅记住了它的数据状态,生成器还记住了程序...

  • 回答 9

    python中title( )属于python中字符串函数,返回’标题化‘的字符串,就是单词的开头为大写,其余为小写

  • 回答 6

    第一种解释:代码中的cnt是count的简称,一种电脑计算机内部的数学函数的名字,在Excel办公软件中计算参数列表中的数字项的个数;在数据库( sq| server或者access )中可以用来统计符合条件的数据条数。函数COUNT在计数时,将把数值型的数字计算进去;但是...

  • 回答 1

    head是方法,所以需要取小括号,即dataset.head()显示的则是前5行。data[:, :-1]和data[:, -1]。另外,如果想通过位置取数据,请使用iloc,即dataset.iloc[:, :-1]和dataset.iloc[:, -1],前者表示的是取所有行,但不包括最后一列的数据,结果是个DataFrame。...

  • Python入门简单吗2021-09-23 13:21
    回答 45

    挺简单的,其实课程内容没有我们想象的那么难、像我之前同学,完全零基础,培训了半年,直接出来就工作了,人家还在北京大公司上班,一个月15k,实力老厉害了

  • 回答 4

    Python针对众多的类型,提供了众多的内建函数来处理(内建是相对于导入import来说的,后面学习到包package时,将会介绍),这些内建函数功用在于其往往可对多种类型对象进行类似的操作,即多种类型对象的共有的操作;如果某种操作只对特殊的某一类对象可行,Pyt...

  • 回答 8

     相当于 ... 这里不是注释

  • 回答 4

    还有FIXME

  • 回答 3

    python的两个库:xlrd和xlutils。 xlrd打开excel,但是打开的excel并不能直接写入数据,需要用xlutils主要是复制一份出来,实现后续的写入功能。

  • 回答 8

    单行注释:Python中的单行注释一般是以#开头的,#右边的文字都会被当做解释说明的内容,不会被当做执行的程序。为了保证代码的可读性,一般会在#后面加一两个空格然后在编写解释内容。示例:#  单行注释print(hello world)注释可以放在代码上面也可以放在代...

  • 回答 2

    主要是按行读取,然后就是写出判断逻辑来勘测行是否为注视行,空行,编码行其他的:import linecachefile=open('3_2.txt','r')linecount=len(file.readlines())linecache.getline('3_2.txt',linecount)这样做的过程中发现一个问题,...

  • 回答 4

    或许是里面有没被注释的代码

  • 回答 26

    自学的话要看个人情况,可以先在B站找一下视频看一下

没有解决我的问题,去提问