《Opencv3计算机视觉》Python语言实现-第七章 目标检测与目标识别

目标检测与识别技术:
梯度直方图(Histogram of Oriented Gradient)
图像金字塔(image pyramid)
滑动窗口(sliding window)

HOG描述符

HOG不是基于颜色值而是基于梯度来计算直方图的。
关于图像直方图的理解: https://blog.csdn.net/qq_38701868/article/details/89215881.
HOG将图像分为小单元,每个单元包含了视觉表示(该视觉表示按照八个方向所计算的颜色梯度),每个单元的八个值为直方图,因此,每个单元都会有唯一的标识。首先计算每个单元的局部直方图,这些单元会合成较大的区域,称为块。(按块来构成特征向量是为了便于归一化)。仅比较两幅图像的单元是行不通的,除非这两幅图像相同(从大小和数据两方面而言)。还有两个主要的问题需要解决:位置和尺度。为了解决这些问题,需要熟悉图像金字塔和滑动窗口。

图像金字塔

图像金字塔是图像的多尺度表示,有利于解决不同尺度下的目标检测问题。如何构建图像金字塔?
(1)获取图像
(2)使用任意尺度的参数来调整(缩小)图像的大小
(3)平滑图像(使用高斯模糊)
(4)如果图像比最小尺寸还大,从第一步开始重复这个过程。

滑动窗口

滑动窗口会有一个问题:区域重叠。针对一组重叠区域,可以用最大评分来抑制所有未分类区域。

非极大抑制

实现非极大值抑制算法过程:
(1)一旦建立图像金字塔,为了检测目标,可采用滑动窗口来搜索图像。
(2)收集当前所含有目标的窗口(超出一定任意阈值),并得到最高响应的窗口W。
(3)消除所有与W有明显重叠的窗口
(4)移动到下一个有最高响应的窗口,在当前尺度下重复上述过程。

如何确定窗口的评分呢?这里采用支持向量机(SVM)来分类。

创建和训练目标检测器

除了上述的HOG和SVM的分类器之外,还有词袋(Bag-of-Word, BOW)技术。
BOW用来在一系列文档中计算每个词出现的次数,然后用这些次数构成向量来重新表示文档。
关于词袋模型的理解: https://blog.csdn.net/tanlangqie/article/details/83795207.

BOW方法的实现步骤如下:
(1)取一个样本数据集
(2)对数据集中的每幅图像提取描述符(采用SIFT/SURF等方法)。
(3)对每一个描述符都添加到BOW训练器中。
(4)将描述符聚类到k簇中(聚类的中心就是视觉单词)

Python代码实现(detect_hog_svm.py)

import cv2
import numpy as np
from os.path import join

# placeholder path
datapath = "/home/d3athmast3r/dev/python/CarData/TrainImages/"
def path(cls,i):
  return "%s/%s%d.pgm"  % (datapath,cls,i+1)

pos, neg = "pos-", "neg-"
#创建两个SIFT实例,一个是提取关键点,一个是提取特征
detect = cv2.xfeatures2d.SIFT_create()
extract = cv2.xfeatures2d.SIFT_create()

#创建FLANN匹配器的实例
flann_params = dict(algorithm = 1, trees = 5)
matcher = cv2.FlannBasedMatcher(flann_params, {})

bow_kmeans_trainer = cv2.BOWKMeansTrainer(40)#为BOW训练器指定的簇为40
extract_bow = cv2.BOWImgDescriptorExtractor(extract, matcher)#初始化BOW提取器,视觉词汇将作为BOW类的输入,在测试图像中会检测到这些视觉词汇

def extract_sift(fn):
  im = cv2.imread(fn,0)
  return extract.compute(im, detect.detect(im))[1]
  
for i in range(8):
  bow_kmeans_trainer.add(extract_sift(path(pos,i)))
  bow_kmeans_trainer.add(extract_sift(path(neg,i)))
  
voc = bow_kmeans_trainer.cluster()
extract_bow.setVocabulary( voc )

def bow_features(fn):
  im = cv2.imread(fn,0)
  return extract_bow.compute(im, detect.detect(im))

traindata, trainlabels = [],[]
for i in range(20): 
  traindata.extend(bow_features(path(pos, i))); trainlabels.append(1)
  traindata.extend(bow_features(path(neg, i))); trainlabels.append(-1)

svm = cv2.ml.SVM_create()
svm.train(np.array(traindata), cv2.ml.ROW_SAMPLE, np.array(trainlabels))

def predict(fn):
  f = bow_features(fn);  
  p = svm.predict(f)
  print(fn, "\t", p[1][0][0])
  return p

# again placeholder paths
car, notcar = "/home/d3athmast3r/dev/python/study/images/car.jpg", "/home/d3athmast3r/dev/python/study/images/bb.jpg"
car_img = cv2.imread(car)
notcar_img = cv2.imread(notcar)
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()

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值