1. 程式人生 > >py4CV例子2.5車牌識別和svm算法重構

py4CV例子2.5車牌識別和svm算法重構

技術分享 情況 return gpo car san jpg 公開 exc

1、什easypr數據集;
easyPR是一個開源的中文車牌識別系統,其目標是成為一個簡單、高效、準確的非限制場景(unconstrained situation)下的車牌識別庫。

相比於其他的車牌識別系統,EasyPR有如下特點:

  • 它基於openCV這個開源庫。這意味著你可以獲取全部源代碼,並且移植到opencv支持的所有平臺。
  • 它能夠識別中文。例如車牌為蘇EUK722的圖片,它可以準確地輸出std:string類型的"蘇EUK722"的結果。
  • 它的識別率較高。圖片清晰情況下,車牌檢測與字符識別可以達到80%以上的精度。

它以 General Data Share License形式公開了一些中文汽車圖片

技術分享圖片

因為我使用了交叉嚴重,所以不需要分目錄放,直接可以把pos和neg圖片各自放到一個目錄下面。

2、重構算法,運行於easypr;
import cv2import numpy as npfrom os.path import joinimport numpy as npimport osimport math#在carData建立svm模型並且k_fold測試,ratio=1表示全部數據用於測試RATIO = 0.2datapath = "D:/dl4cv/datesets/EasyPRresources/train/svm/"#分為has和no兩個文件夾,全部取jpg圖片
#根據Ratio獲得訓練和測試數據集的圖片地址和標簽
def get_files(file_dir, ratio): ‘‘‘ Args: file_dir: file directory Returns: list of images and labels ‘‘‘ pos = [] label_pos = [] neg = [] label_neg = [] for file in os.listdir(file_dir+"has/"): pos.append(file_dir + "has/"+file) label_pos.append(1
) for file in os.listdir(file_dir+"no/"): neg.append(file_dir + "no/"+file) label_neg.append(1)
print(‘數據集中有 %d pos \n以及 %d neg ‘ %(len(pos), len(neg))) #圖片list和標簽list #hstack 水平(按列順序)把數組給堆疊起來 image_list = np.hstack((pos, neg)) label_list = np.hstack((label_pos, label_neg)) temp = np.array([image_list, label_list]) temp = temp.transpose() #亂序的目的是為了讓正樣本和負樣本混在一起,這樣直接取其中百分之多少就可以來用了 np.random.shuffle(temp) all_image_list = temp[:, 0] all_label_list = temp[:, 1] n_sample = len(all_label_list) #根據比率,確定訓練和測試數量 n_val = math.ceil(n_sample*ratio) # number of validation samples n_train = n_sample - n_val # number of trainning samples tra_images = [] val_images = [] #按照0-n_train為tra_images,後面位val_images的方式來排序 tra_images = all_image_list[:n_train] tra_labels = all_label_list[:n_train] tra_labels = [int(float(i)) for i in tra_labels]
val_images = all_image_list[n_train:] val_labels = all_label_list[n_train:] val_labels = [int(float(i)) for i in val_labels] return tra_images,tra_labels,val_images,val_labels
#創建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訓練器bow_kmeans_trainer = cv2.BOWKMeansTrainer(40)extract_bow = cv2.BOWImgDescriptorExtractor(extract, matcher)#以灰度方式讀取圖像,提取sift,並返回結果def extract_sift(fn): im = cv2.imread(fn) try: cv2.cvtColor(im,im,cv2.COLOR_BGR2GRAY) except : pass return extract.compute(im, detect.detect(im))[1]#返回bow的描述符提取器計算得到的描述符def bow_features(fn): im = cv2.imread(fn,0) return extract_bow.compute(im, detect.detect(im))#返回預測的結果def predict(fn): f = bow_features(fn); p = svm.predict(f) print(fn, "\t", p[1][0][0]) return p############################################# main ################################################獲得訓練和測試數據集的圖片地址和標簽train_images, train_labels, val_images, val_labels = get_files(datapath, RATIO)traindata, trainlabels = [],[]#為feature模型輸入正負樣本for i in range(20): try: bow_kmeans_trainer.add(extract_sift(train_images[i])) except : pass#feature模型聚類,返回詞匯表voc = bow_kmeans_trainer.cluster()extract_bow.setVocabulary( voc )
#創建並訓練一個svm模型print("創建並訓練一個svm模型")for i in range(len(train_images)): try: traindata.extend(bow_features(train_images[i])) trainlabels.append(train_labels[i]) except : passsvm = cv2.ml.SVM_create()svm.train(np.array(traindata), cv2.ml.ROW_SAMPLE, np.array(trainlabels))print("在測試集上進行測試")#在測試集上進行測試result = []for i in range(len(val_images)): try: f = bow_features(val_images[i]); p = svm.predict(f) result.append(p[1][0][0]) except : result.append(0) np_val_labels = np.array(val_labels)[:,np.newaxis]np_result = np.array(result)[:,np.newaxis]matches = np_result == np_val_labels
correct = np.count_nonzero(matches)accuracy = correct*100.0/len(result)print(accuracy)這裏對相關算法進行了重構,主要是以下幾個方面1、將獲得交叉數據集的函數和創建features的幾個函數進行了重構,這樣實現算法流程清晰;2、添加了異常控制,避免錯誤;3、添加了一些流程控制。結果:數據集中有 1917 pos 以及 3978 neg 創建並訓練一個svm模型在測試集上進行測試96.09838846480068


來自為知筆記(Wiz)

附件列表

    py4CV例子2.5車牌識別和svm算法重構