python 方向梯度直方图_人工智能人脸探测原理--方向梯度直方图

给计算机输入一套房的面积,位置,朝向,房间数目,计算机就可以自动给你算出它的价格;输入一个人的学历,住址,朋友数目,去过的地方,计算机也可以自动给你算出他/她的年收入;输入一种植物的花瓣数目,花瓣宽度/长度,叶子长度/宽度,花香描述等,计算机就可以告诉我们这种植物的名称;……  这些问题都可以通过选择一个机器学习算法,给它数据,然后等待输出结果. 人脸探测也是可以通过机器学习算法来做的.它的目的就是找出图片中的人脸.

人脸探测是人脸识别算法和图片审核中所用的算法. 在区分人脸之前,首先要找出人脸在照片中的位置! 近几年来的相机都有人脸探测的功能,它能找出人脸,以便可以对每张人脸对焦,从而得出更清晰的照片.我们这里用来做识别人脸,而非得到更清晰的照片.

注:自从Paul Viola和Michael Jones 发明了能应用在一般照相机上的快速探测人脸的方法,人脸探测在上个时代初就成为主流技术. 现在,人们有了更好的方法用于快速探测人脸.

我们将用的方法----方向梯度直方图(Histogram of Oriented Gradients, HOG, 2005). 首先将照片转成黑白照片,因为色彩的信息我们不需要.然后,我们依次关注照片中的每一个像素点. 对每个像素点, 我们想看看那些直接包围着它的像素点. 我们的目标:计算出当前像素相对于其周围的像素有多暗. 然后我们想画出像素由明到暗变化最快的方向:

对照片中的每一个像素点重复上述操作, 最终每一个像素都被一个箭头取代了. 这些箭头称为梯度 ,它们显示整张照片由明到暗变化最快的方向.

这样做有什么好处? 如果我们直接分析像素, 同一个人的非常暗的照片和非常亮的照片将具有完全不同的像素值. 但是考虑亮度改变的方向时,暗照片和两照片将有几乎一样的表示! 所以我们不直接处理像素值信息,而是处理像素明暗的变化信息.

我们可以用梯度来看一些基本模式,而不是所有细节!为了达到这目的,我们将照片分成小方格,每个方格的大小为16x16像素. 在每一个小方格中,我们将计算在每个主要方向有多少个梯度点 .例如,可以考虑有多少个指向(0°,60°)区间,有多少个指向(60°,120°),有多少个指向(120°,180°),等等. 接下来,我们可以统计每个区间内方向梯度的个数(可以为方向梯度的绝对值作为权重),个数最多的区间就"胜出"了.我们以这个区间的箭头方向去取代该小方格. 这样,我们就将原图片转化成了非常简单的表示. 它只以简单的方式描述人脸的基本结构.

为了在这张HOG图片中找到人脸, 我们只需找到我们的图片中最像已知HOG 模式的那部分.已知HOG模式由大量其他照片训练并提取出来,如图所示.

为了计算一个HOG描述器, 我们首先需要计算水平梯度和竖直梯度;然后可求得方向梯度直方图. 这可以由如下的核过滤该图片而得:

我们也可用OpenCV中的Sobel算符来达到同样的目的.

1. # Python gradient calculation

2. # Read image

3. im = cv2.imread('li.jpg')

4. im = np.float32(im) / 255.0

5.

6. # Calculate gradient

7. gx = cv2.Sobel(img, cv2.CV_32F, 1, 0, ksize=1)

8. gy = cv2.Sobel(img, cv2.CV_32F, 0, 1, ksize=1)

然后,我们可以用gx, gy来计算梯度的大小和方向.如果我们用OpenCV, 可以应用函数cartToPolar来计算这两个量.代码如下.

1.  # Python Calculate gradient magnitude and direction ( in degrees )

2. mag, angle = cv2.cartToPolar(gx, gy, angleInDegrees=True)

我们也可以用skimage模块来计算和显示一幅图的方向梯度直方图.示例代码如下:

1. # To calculate HOG and display the HOG image

2. import matplotlib.pyplot as plt

3. from skimage.feature import hog

4. from skimage import data, exposure

5. from skimage import color

6.

7. image = color.rgb2gray(data.astronaut()) #to change to gray, after importing color

8. #image = data.astronaut()

9.

10. fd, hog_image = hog(image, orientations=8, pixels_per_cell=(16, 16),

11.                 cells_per_block=(1, 1), visualise=True)

12. #fd, hog_image = hog(image, orientations=8, pixels_per_cell=(16, 16),

13. #                    cells_per_block=(1, 1), visualise=True, multichannel=True)

14. # Both visulaize or visualise is OK, but for this version of skimage, use 'visualise'.

15.

16. fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 4), sharex=True, sharey=True)

17. ax1.axis('off')

18. ax1.imshow(image, cmap=plt.cm.gray)

19. ax1.set_title('Input image')

20.

21. # Rescale histogram for better display

22. hog_image_rescaled = exposure.rescale_intensity(hog_image, in_range=(0, 10))

23.

24. ax2.axis('off')

25. ax2.imshow(hog_image_rescaled, cmap=plt.cm.gray)

26. ax2.set_title('Histogram of Oriented Gradients')

27. plt.show()

结果如下,左边为原图(已经转成黑白照片),右图为方向梯度直方图.

我们也可以利用io.imread()导入图片,使之称为numpy.ndarray型的数据. 然后也可对图片进行同样的操作,得到方向梯度直方图. 代码和上面的代码只在导入图片时有细微差别.代码和结果依次如下:

1. import matplotlib.pyplot as plt

2. from skimage import color

3. from skimage.feature import hog

4. from skimage import data, exposure

5.

6. from skimage import io

7.

8. image = io.imread('./li_00.jpg')

9. image = color.rgb2gray(image)

10.

11. print("type of image is:{}".format(type(image)))

12. print("image is:{}".format(image))

13. print("no. of columns of image is:{}".format(len(image[0])))

14. print("no. of rows of image is:{}".format(len(image)))

15.

16. fd, hog_image = hog(image, orientations=8, pixels_per_cell=(8, 8),

17.                 cells_per_block=(1, 1), visualise=True)

18.

19. fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 4), sharex=True, sharey=True)

20.

21. ax1.axis('off')

22. ax1.imshow(image, cmap=plt.cm.gray)

23. ax1.set_title('Input image')

24.

25. # Rescale histogram for better display

26. hog_image_rescaled = exposure.rescale_intensity(hog_image, in_range=(0, 10))

27.

28. ax2.axis('off')

29. ax2.imshow(hog_image_rescaled, cmap=plt.cm.gray)

30. ax2.set_title('Histogram of Oriented Gradients')

31. plt.show()

参考文献

1. Dalal, N. and Triggs, B., “Histograms of Oriented Gradients for Human Detection,” IEEE Computer Society Conference on Computer Vision and Pattern Recognition, 2005, San Diego, CA, USA.

2. David G. Lowe, “Distinctive image features from scale-invariant keypoints,” International Journal of Computer Vision, 60, 2 (2004), pp. 91-110.

感谢源码时代教学讲师提供此文章!

本文为原创文章,转载请注明出处!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值