图像处理之⽬标检测与识别
区别:⽬标检测是⽤来确定图像的某个区域是否含有要识别的对象,识别通常只处理已检测到对象的区域。
在计算机视觉中有很多⽬标检测和识别的技术:
梯度直⽅图(Histogram of Oriented Gradient, HOG)
图像⾦字塔
滑动窗⼝
四种技术
梯度直⽅图
是⼀个特征描述符,不是基于颜⾊值⽽是基于梯度来计算直⽅图的。但是这种特征会受到两个⽅⾯的影响:尺度问题、位置问题,为了解决这些问题,需要使⽤图像⾦字塔和滑动窗⼝。
图像⾦字塔
是图像的多尺度表⽰
滑动窗⼝
通过⼀个滑动窗⼝扫描较⼤图像的较⼩区域来解决定位问题,进⽽在同⼀图像的不同尺度下重复扫描。但是滑动窗⼝会遇到⼀个问题,区域重叠,⽐如在对⼈脸检测的时候可能对同⼀张⼈脸的四个不同位置进⾏匹配,但是我们只需要⼀个结果,所以我们需要使⽤⾮最⼤抑制来确定⼀个评价最⾼的图⽚区域。
⽀持向量机
SVM的最优超平⾯是⽬标检测的重要组成部分,⽤来区分哪些像素是⽬标,哪些像素不是⽬标
下⾯展⽰⼀些 内联代码⽚。
检测⼈案例(OpenCV⾃带的HOGDescriptor函数可检测⼈,下⾯见openCV有哪些功能)
import cv2
import numpy as np
def is_inside(o,i):#判断矩形o是不是在i矩形中
ox,oy,ow,oh = o # o:矩形o(x,y,w,h)
ix,iy,iw,ih = i#i:矩形i(x,y,w,h)
return ox > ix and oy > iy and ox + ow < ix + iw and oy + oh < iy +ih
def draw_person(image, person):#两个参数,图⽚和⼈物
'''
在img图像上绘制矩形框person
args:
img:图像img
person:⼈所在的边框位置(x,y,w,h)
'''
x,y,w,h = person
img = cv2.imread('images/timg (2).jpg')#读取图⽚
hog = cv2.HOGDescriptor()#特征提取
hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())#指定HOGDesricptor作为检测⼈的默认检测器.这可通过setSVMDetector()⽅法实现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)
lib库作⽤
opencv_core 包含了opencv库的核⼼函数,具体来说,还有⼀些基本的数据结构和算术函数(基本的数据结构,架构和线性代数,DFT,xml 和
yam i/o接⼝ 函数等)
opencv_imgproc 包含了主要的图像处理函数(滤波,⾼斯模糊,形态学膨胀/腐蚀,线性缩放图像⼤ ⼩,图像⼏何变化,颜⾊结构变化,计算直⽅图
等)
openCV
lib库作⽤
opencv_highgui包含了图⽚和视频的读写函数,还有其他⽤户交互函数
opencv_ml统计机器学习模型函数库(SVM,决策树,级联等)
opencv_features2d⼆维特征检测器和描述⼦函数库(SURF,FAST 等,包括⼀种新的特征 描述⼦匹配
结构)opencv_video包含了动作估计,特征跟踪和前景提取函数与类,包含了动作估计,特征跟踪和前景提取函数与类opencv_objdetect图像⽬标检测函数库(haar⼩波 & LBP⼈脸检测和识别,HOG⼈检测 等)
opencv_calib3d摄像头标定,视觉匹配和三维数据处理函数库
opencv_flann近似最近领域搜索库和OpenCV分装器
opencv_contrib最新贡献但不是很成熟的函数库
opencv_legacy过时代码,为了后续代码兼容性⽽存在
创建和训练⽬标检测器
1. 词袋技术
2. 汽车检测
3. 多⽬标汽车和位置检测
词袋
词袋(BOW)最早并不是针对计算机视觉的,⽽是⽤于语⾔分析和信息检索领域,BOW⽤来在⼀系列⽂档中计算每个词出现的次数,⽤这些次数构成向量来重新表⽰⽂档。词袋模型是⼀种⽤机器学习算法对⽂本进⾏建模时表⽰⽂本数据的⽅法。
⽽在计算机视觉中,BOW⽅法的实现步骤如下:
1. 取⼀个样本数据集
2. 对数据集中的每幅图像提取描述符(采⽤SIFT(尺度不变特征变换匹配算法Scale Invariant Feature Transform),SURF(SIFT改进
算法Speeded Up Robust Features)等⽅法)
3. 将每⼀个描述符都添加到BOW训练器中
4. 使⽤K-means聚类将描述符聚类到K簇中
汽车检测
1. 先下载
2. 实现代码:
下⾯展⽰⼀些 内联代码⽚。
import cv2
import numpy as np
from os.path import join
# 获取不同类别图像的路径
def path(cls, i):
return"%s/%s%d.pgm"%(datapath, cls, i +1)
# 以灰度格式读取图像,并从图像中提取SIFT特征,然后返回描述符
def extract_sift(fn):
im = cv2.imread(fn,0)
return extractpute(im, detect.detect(im))[1]
# 声明训练图像的基础路径,最新下载地址:
# /Data/Car/
datapath ="./data/at/CarData/TrainImages/"
datapath ="./data/at/CarData/TrainImages/"
# 查看下载的数据素材,发现汽车数据集中图像按:pos-x.pgm 和 neg-x.pgm 命名,其中x是⼀个数字。# 这样从path读取图像时,只需传递变量i的值即可
pos, neg ="pos-","neg-"
# 创建两个SIFT实例,⼀个提取关键点,⼀个提取特征;
detect = cv2.xfeatures2d.SIFT_create()
extract = cv2.xfeatures2d.SIFT_create()
# 创建基于FLANN匹配器实例
flann_params =dict(algorithm=1, trees=5)
flann = cv2.FlannBasedMatcher(flann_params,{})rectangle函数opencv
# 创建BOW训练器,指定簇数为40
bow_kmeans_trainer = cv2.BOWKMeansTrainer(40)
# 初始化BOW提取器,视觉词汇将作为BOW类输⼊,在测试图像中会检测这些视觉词汇
extract_bow = cv2.BOWImgDescriptorExtractor(extract, flann)
# 从每个类别中读取8个正样本和8个负样本,并增加到训练集的描述符
for i in range(8):
bow_kmeans_trainer.add(extract_sift(path(pos, i)))
bow_kmeans_trainer.add(extract_sift(path(neg, i)))
# cluster()函数执⾏k-means分类并返回词汇
# 并为BOWImgDescriptorExtractor指定返回的词汇,以便能从测试图像中提取描述符
voc = bow_kmeans_trainer.cluster()
extract_bow.setVocabulary(voc)
# 返回基于BOW描述符提取器计算得到的描述符
def bow_features(fn):
im = cv2.imread(fn,0)
return extract_bowpute(im, detect.detect(im))
# 创建两个数组,分别存放训练数据和标签
# 调⽤BOWImgDescriptorExtractor产⽣的描述符填充两个数组,⽣成正负样本图像的标签traindata, trainlabels =[],[]
for i in range(20):
trainlabels.append(1) # 1表⽰正匹配
trainlabels.append(-1) # -1表⽰负匹配
# 创建⼀个svm实例
svm = cv2.ml.SVM_create()
# 通过将训练数据和标签放到NumPy数组中来进⾏训练
'''
以上设置都是⽤于训练好的SVM,剩下要做的是给SVM⼀些样本图像
'''
# 显⽰predict⽅法结果,并返回结果信息
def predict(fn):
f =bow_features(fn)
p = svm.predict(f)
print(fn,"\t", p[1][0][0])
return p
# 定义两个样本图像的路径,并读取样本图像信息
car, notcar ="./images/car.jpg","./images/bb.jpg"
car_img = cv2.imread(car)
notcar_img = cv2.imread(notcar)
# 将图像传给已经训练好的SVM,并获取检测结果
car_predict =predict(car)
not_car_predict =predict(notcar)
# 以下⽤于屏幕上显⽰识别的结果和图像
font = cv2.FONT_HERSHEY_SIMPLEX
if(car_predict[1][0][0]==1.0):
cv2.putText(car_img,'Car Detected',(10,30), font,1,(0,255,0),2, cv2.LINE_AA)
if(not_car_predict[1][0][0]==-1.0):
cv2.putText(notcar_img,'Car Not Detected',(10,30), font,1,(0,0,255),2, cv2.LINE_AA)
cv2.imshow('BOW + SVM Success', car_img)
cv2.imshow('BOW + SVM Failure', notcar_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论