python3实例车代码_OpenCV3-Python基于BOW模型的车辆识别

上一篇博文《OpenCV3-Python基于HOG和BOW的目标识别》,在识别物体时,由于训练集太少导致结果不可靠,为了使结果的准确度在可接受范围内,需要一个足够大的数据集,对数据进行训练。

本节基于车辆检测的例子,介绍如何通过对大量数据集的训练,获取可靠的识别结果。

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 extract.compute(im, detect.detect(im))[1]

#声明训练图像的基础路径,最新下载地址:

#http://cogcomp.org/Data/Car/CarData.tar.gz

datapath = "./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, {})

#创建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_bow.compute(im, detect.detect(im))

#创建两个数组,分别存放训练数据和标签

#调用BOWImgDescriptorExtractor产生的描述符填充两个数组,生成正负样本图像的标签

traindata, trainlabels = [],[]

for i in range(20):

traindata.extend(bow_features(path(pos, i)));

trainlabels.append(1)   #1表示正匹配

traindata.extend(bow_features(path(neg, i)));

trainlabels.append(-1)  #-1表示负匹配

#创建一个svm实例

svm = cv2.ml.SVM_create()

#通过将训练数据和标签放到NumPy数组中来进行训练

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

'''

以上设置都是用于训练好的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 = "./car.jpg", "./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()

3. 实验结果

4. 另一个例程

本例程将汽车识别调用的.py文件作为一个独立的文件夹,方便以后不同项目间的移植。

相关函数全部位于car_detector(点击下载附件) 文件夹中,如下:

实际应用中,只需修改car_sliding_windows.py文件即可,附内容:import cv2

import numpy as np

from car_detector.detector import car_detector, bow_features

from car_detector.pyramid import pyramid

from car_detector.non_maximum import non_max_suppression_fast as nms

from car_detector.sliding_window import sliding_window

def in_range(number, test, thresh=0.2):

return abs(number - test) 

test_image = "./car.jpg"

svm, extractor = car_detector()

detect = cv2.xfeatures2d.SIFT_create()

w, h = 150, 80

img = cv2.imread(test_image)

rectangles = []

scaleFactor = 1.25

for resized in pyramid(img, scaleFactor):

scale = float(img.shape[1]) / float(resized.shape[1])

for (x, y, roi) in sliding_window(resized, 20, (w, h)):

if roi.shape[1] != w or roi.shape[0] != h:

continue

try:

bf = bow_features(roi, extractor, detect)

_, result = svm.predict(bf)

a, res = svm.predict(bf, flags=cv2.ml.STAT_MODEL_RAW_OUTPUT | cv2.ml.STAT_MODEL_UPDATE_MODEL)

#所有小于-1.0的窗口被视为一个好的结果

if result[0][0] == 1 and res[0][0] 

print ("Class: %d, Score: %f, a: %s" % (result[0][0], res[0][0], res))

#提取感兴趣区域(ROI)的特征,它与滑动窗口相对应

rx, ry, rx2, ry2 = int(x * scale), int(y * scale), int((x+w) * scale), int((y+h) * scale)

rectangles.append([rx, ry, rx2, ry2, abs(res[0][0])])

except:

pass

#将矩形数组转换为NumPy数组

windows = np.array(rectangles)

#非最大抑制nms,按打分最高到最低排序

boxes = nms(windows, 0.25)

#打印检测结果

for (x, y, x2, y2, score) in boxes:

print (x, y, x2, y2, score)

cv2.rectangle(img, (int(x),int(y)),(int(x2), int(y2)),(0, 255, 0), 1)

cv2.putText(img, "%f" % score, (int(x),int(y)), cv2.FONT_HERSHEY_PLAIN, 1, (0, 255, 0))

cv2.imshow("img", img)

cv2.waitKey(0)

cv2.destroyAllWindows()

5. 例程运行结果:

对于支持向量机(SVM)来说,不需要每次都训练检测器,可以保存训练结果到文件,以后需要用到时,使用load函数直接加载即可。svm.save('/svmxml')

注意:本站所有文章除特别说明外,均为原创,转载请务必以超链接方式并注明作者出处。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值