今天对python使用svm过程中出现的问题进行一下记录
先将代码插入进来
import cv2
import numpy as np
from os.path import join
datapath = r"D:/BaiduNetdiskDownload/opencv/CarData/TrainImages"
def path(cls,i):
return "%s/%s%d.pgm" % (datapath,cls,i+1)
pos, neg = "pos-","neg-"
detect = cv2.xfeatures2d.SIFT_create()
extract = cv2.xfeatures2d.SIFT_create()
flann_parms = dict(algorithm = 1,trees = 5)
flann = cv2.FlannBasedMatcher(flann_parms,{ })
bow_kmeans_trainer = cv2.BOWKMeansTrainer(40)
extract_bow = cv2.BOWImgDescriptorExtractor(extract, flann)
def extract_sift(fn):
im = cv2.imread(fn,0)
return extract.compute(im,detect.detect(im))[1]
for i in range(6):
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
car, notcar =r"D:/BaiduNetdiskDownload/opencv/car.jpg",r"D:/BaiduNetdiskDownload/opencv/2.png"# picture path
car_img = cv2.imread(car)
notcar_img = cv2.imread(notcar)
car_predict = predict(car)
not_car_predict = predict(notcar)
font = cv2.FONT_HERSHEY_DUPLEX
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()
首先出现的问题是路径问题,图片和训练集路径需要添加转转义符‘\’,或者将‘\’变成‘/’加入路径内。
例:D:/BaiduNetdiskDownload/opencv/car.jpg
出现的第二个问题:
OpenCV(3.4.2) C:\projects\opencv-python\opencv\modules\features2d\src\bagofwords.cpp:55: error: (-215:Assertion failed) !_descriptors.empty() in function ‘cv::BOWTrainer::add’
翻译后
fnOpenCV(3.4.2)C:\projects\opencv python\opencv\modules\feature2d\src\巴格沃兹。cpp:55:错误:(-215:断言失败)!_描述符。空()在函数“cv::BOWTrainer::add”中
是由语句traindata.extend(bow_features(path(pos,i)))
引起的。
说来也惭愧,在遍寻资料后才发现,是路径出问题了,导致找不到数据集文件。
大致有以下几种情况:
1.由图片属性内路径复制过来,可能会出现转码问题,复制过来是一串字符,但是由于复制过来后由IDE转码显示,在读取路径时读取源码不成功。
2.路径内包含中文字符
3.路径内并没有符合要求的数据集。
第三个问题是由函数
def predict(fn):
f = bow_features(fn);
p = svm.predict(f)
print (fn, "/t",p[1][0][0])
return p
引起的,主要是因为路径内数据集不符合要求。
第四个问题是由FONT_HERSHEY_SIMPLEX
引起的,这是opencv内置字体,当其报错时,是因为内部字体缺失,可以更换其他字体试一试。例:
CV_FONT_HERSHEY_SIMPLEX - 正常大小无衬线字体.
CV_FONT_HERSHEY_PLAIN - 小号无衬线字体.
CV_FONT_HERSHEY_DUPLEX - 正常大小无衬线字体比 CV_FONT_HERSHEY_SIMPLEX 更复杂)
CV_FONT_HERSHEY_COMPLEX - 正常大小有衬线字体.
CV_FONT_HERSHEY_TRIPLEX - 正常大小有衬线字体 ( 比 CV_FONT_HERSHEY_COMPLEX更复杂)
CV_FONT_HERSHEY_COMPLEX_SMALL - CV_FONT_HERSHEY_COMPLEX 的小译本.
CV_FONT_HERSHEY_SCRIPT_SIMPLEX - 手写风格字体.
CV_FONT_HERSHEY_SCRIPT_COMPLEX - 比 CV_FONT_HERSHEY_SCRIPT_SIMPLEX 更复杂.
参数能够由一个值和可选择的 CV_FONT_ITALIC 字体标记合成。就是斜体字.
参数vscale,和hscale分别表示行高、和字体宽度,当其值被设为1.0时,就为默认值,当其值被设为0.5时,就为原默认值的一半,shear参数表示字体的倾斜程度,当其值为0时,表示字体不倾斜,当其值为1时,文字倾斜45度.
最后要注意的是 SIFT 由专利法保护,在高版本中已经去除,如需使用,请安装低版本。具体方法见:from matplotlib import pyplot as plt 报错问题及matplotlib正确安装