目标检测
计算机视觉中有很多目标检测和识别的技术,这里主要学习三种:
- 梯度直方图
- 图像金字塔
- 滑动窗口
HOG描述符
HOG与之前提到的SURF,SIFT,ORB属于同一类型的描述符。HOG是基于梯度而非颜色来计算直方图。但是这种检测存在着尺度和位置问题,梯度特征的对比如果采用简单的暴力匹配,准确率很低,而且一张图片可以分为无数个区域,如何选取合适的区域也是个问题。图像金字塔和滑动窗口就是为此而生,这两个概念即便是基于深度学习的图像检测也是难以避开的。
这几种技术在PyTorch学习的时候已经接触过一遍了,不再赘述。
区别
OpenCV目标检测和神经网络中的利用卷积的目标识别主体流程差距不大,而细节框架部分,神经网络优化了许多,但也复杂很多。比如推荐区域生成,滑动窗被锚框取代,甚至到像素级别,分类也不再用传统的SVM向量机。
SVM支持向量机
对于带有标签的训练数据,通过一个优化的超平面来对这些数据进行分类。超平面的质量决定了分类的质量,如何使不同类别的物体在这个平面上的定位呈现明显的类别集聚将决定检测的准确性。
使用opencv自带的默认人检测器
效果图(效果不是很好):
import cv2
import numpy as np
# 判断框是否有包含关系
def is_inside(o, i):
ox, oy, ow, oh = o
ix, iy, iw, ih = i
return ox>ix and oy>iy and ox+ow<ix+iw and oy+oh<iy+ih
# 绘制方框包含检测到的人
def draw_person(image, person):
x, y, w, h = person
cv2.rectangle(image, (x,y), (x+w,y+h), (0,0,255), 2)
img = cv2.imread('people.jpg')
hog = cv2.HOGDescriptor()
hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())
found, w = hog.detectMultiScale(img)
found_filtered=[]
for ri, r in enumerate(found):
for qi, q in enumerate(found):
if ri != qi and is_inside(r, q):
break
else:
found_filtered.append(r)
for person in found_filtered:
draw_person(img, person)
cv2.imshow("people detection",img)
cv2.waitKey(0)
cv2.destoryAllWindows()
词袋
词袋(BOW)用来计算在一个文档中每个词出现的次数,然后用这些次数构成向量来重新表示文档,可以视为由字典的value组成的向量。
BOW的实现步骤:
- 取一个样本集
- 对数据集中的每幅图像提取描述符
- 将每一个描述符都添加到BOW训练器中
- 将描述符聚类到K个族中,聚类的中心为视觉单词
总结
使用内建函数可以很容易得到应用的简易模型,但是其效果并不是非常出色。通过构建自己的分类器可创建并训练自己的目标检测器。利用SVM和词袋技术构建分类器将是之后的主要工作。