├── .github └── FUNDING.yml ├── 10_EdgeBoxes+SVM+NMS_cam.py ├── 1_HoG_extract_feature.py ├── 2_Train_SVM.py ├── 3_Test_SVM.py ├── 4_Train_PCA+SVM.py ├── 5_Test_PCA+SVM.py ├── 6_PSO+PCA.py ├── 7_Hard_Negative_Mining+SVM.py ├── 8_SlidingWindow+SVM+NMS_image.py ├── 9_SlidingWindow+SVM+NMS_cam.py ├── README.md └── example.gif /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: https://raw.githubusercontent.com/HansRen1024/HansRen1024.github.io/master/Get_paid_QR.jpg 13 | -------------------------------------------------------------------------------- /10_EdgeBoxes+SVM+NMS_cam.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Created on Tue Jul 4 15:10:57 2017 5 | 6 | @author: hans 7 | """ 8 | 9 | from imutils.object_detection import non_max_suppression 10 | from edge_boxes_python import edge_boxes_python 11 | import numpy as np 12 | from skimage.feature import hog 13 | from sklearn.externals import joblib 14 | import cv2 15 | import os 16 | import time 17 | 18 | 19 | 20 | def rgb2gray(im): 21 | gray = im[:, :, 0]*0.2989+im[:, :, 1]*0.5870+im[:, :, 2]*0.1140 22 | return gray 23 | 24 | def getFeat(data): 25 | normalize = True 26 | visualize = False 27 | block_norm = 'L2-Hys' 28 | cells_per_block = [2,2] 29 | pixels_per_cell = [20,20] 30 | orientations = 9 31 | gray = rgb2gray(data)/255.0 32 | fd = hog(gray, orientations, pixels_per_cell, cells_per_block, block_norm, visualize, normalize) 33 | return fd 34 | 35 | if __name__ == "__main__": 36 | model_path = './models/svm_pso_less_hnm_50.model' 37 | clf = joblib.load(model_path) 38 | c = cv2.VideoCapture(0) 39 | num = 0 40 | while 1: 41 | t0 = time.time() 42 | num += 1 43 | ret, image = c.read() 44 | rects = [] 45 | eb = edge_boxes_python(os.path.expanduser('~') + '/HoG_SVM/cup/sf.dat') 46 | bbs = eb.get_edge_boxes(image) 47 | for (xmin, ymin, width, height, hb) in bbs[0:10]: 48 | xmin = int(xmin) 49 | ymin = int(ymin) 50 | width = int(width) 51 | height = int(height) 52 | win = image[ymin:ymin + height, xmin:xmin + width] 53 | window = cv2.resize(win,(200,200),interpolation=cv2.INTER_CUBIC) 54 | win_fd = getFeat(window) 55 | win_fd.shape = 1,-1 56 | result = int(clf.predict(win_fd)) 57 | if result == 1: 58 | rects.append([xmin, ymin, xmin + width, ymin + height]) 59 | if len(rects) != 0: 60 | rects = np.array(rects) 61 | pick = non_max_suppression(rects, probs=None, overlapThresh=0.1) 62 | for (xA, yA, xB, yB) in pick: 63 | cv2.rectangle(image, (xA, yA), (xB, yB), (0, 255, 0), 2) 64 | font=cv2.FONT_HERSHEY_SIMPLEX 65 | t1 = time.time() 66 | cv2.putText(image,'%.2f' %(1/(t1-t0)),(0,30),font,0.9,(255,255,255),2) 67 | cv2.imshow("After NMS", image) 68 | cv2.waitKey(1) 69 | -------------------------------------------------------------------------------- /1_HoG_extract_feature.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Created on Tue Jun 13 10:24:50 2017 5 | 6 | @author: hans 7 | """ 8 | 9 | from skimage.feature import hog 10 | from sklearn.externals import joblib 11 | import xml.dom.minidom as xdm 12 | import numpy as np 13 | import Image 14 | import cv2 15 | import os 16 | import time 17 | 18 | # define parameter 19 | normalize = True 20 | visualize = False 21 | block_norm = 'L2-Hys' 22 | cells_per_block = [2,2] 23 | pixels_per_cell = [20,20] 24 | orientations = 9 25 | 26 | # xml path 27 | train_xml_filePath = r'./train/Annotation' 28 | 29 | 30 | def getBox(childDir): 31 | f_xml = os.path.join(train_xml_filePath, '%s.xml' %childDir.split('.')[0]) # organise path 32 | xml = xdm.parse(f_xml) # load xml file 33 | filename = xml.getElementsByTagName('filename') 34 | filename = filename[0].firstChild.data.encode("utf-8") # read file name 35 | xmin = xml.getElementsByTagName('xmin') # coordinate of top left pixel 36 | xmin = int(xmin[0].firstChild.data) 37 | ymin = xml.getElementsByTagName('ymin') 38 | ymin = int(ymin[0].firstChild.data) 39 | xmax = xml.getElementsByTagName('xmax') # coordinate of down right pixel 40 | xmax = int(xmax[0].firstChild.data) 41 | ymax = xml.getElementsByTagName('ymax') 42 | ymax = int(ymax[0].firstChild.data) 43 | box = (xmin,ymin,xmax,ymax) 44 | return box 45 | 46 | def getDataWithCrop(filePath,label): 47 | Data = [] 48 | num = 0 49 | for childDir in os.listdir(filePath): 50 | f_im = os.path.join(filePath, childDir) 51 | image = Image.open(f_im) # open the image 52 | box = getBox(childDir) 53 | region = image.crop(box) # cut off image 54 | data = np.asarray(region) # put the data of image into an N-dinimeter array 55 | data = cv2.resize(data,(200,200),interpolation=cv2.INTER_CUBIC) # resize image 56 | data = np.reshape(data, (200*200,3)) 57 | data.shape = 1,3,-1 58 | fileName = np.array([[childDir]]) 59 | datalebels = zip(data, label, fileName) # organise data 60 | Data.extend(datalebels) # pou the organised data into a list 61 | num += 1 62 | print "%d processing: %s" %(num,childDir) 63 | return Data,num 64 | 65 | def getData(filePath,label): # get the full image without cutting 66 | Data = [] 67 | num = 0 68 | for childDir in os.listdir(filePath): 69 | f = os.path.join(filePath, childDir) 70 | data = cv2.imread(f) 71 | data = cv2.resize(data,(200,200),interpolation=cv2.INTER_CUBIC) 72 | data = np.reshape(data, (200 * 200,3)) 73 | data.shape = 1,3,-1 74 | fileName = np.array([[childDir]]) 75 | datalebels = zip(data, label, fileName) 76 | Data.extend(datalebels) 77 | num += 1 78 | print "%d processing: %s" %(num,childDir) 79 | return Data,num 80 | 81 | def getFeat(Data,mode): # get and save feature valuve 82 | num = 0 83 | for data in Data: 84 | image = np.reshape(data[0], (200, 200, 3)) 85 | gray = rgb2gray(image)/255.0 # trans image to gray 86 | fd = hog(gray, orientations, pixels_per_cell, cells_per_block, block_norm, visualize) 87 | # fd = hog(gray, orientations, pixels_per_cell, cells_per_block, block_norm, visualize, normalize) 88 | fd = np.concatenate((fd, data[1])) # add label in the end of the array 89 | filename = list(data[2]) 90 | fd_name = filename[0].split('.')[0]+'.feat' # set file name 91 | if mode == 'train': 92 | fd_path = os.path.join('./features/train/', fd_name) 93 | else: 94 | fd_path = os.path.join('./features/test/', fd_name) 95 | joblib.dump(fd, fd_path,compress=3) # save data to local 96 | num += 1 97 | print "%d saving: %s." %(num,fd_name) 98 | 99 | def rgb2gray(im): 100 | gray = im[:, :, 0]*0.2989+im[:, :, 1]*0.5870+im[:, :, 2]*0.1140 101 | return gray 102 | 103 | if __name__ == '__main__': 104 | t0 = time.time() 105 | 106 | # deal with Positive test dataset and trainset with cutting 107 | Ptrain_filePath = r'./train/positive' 108 | Ptest_filePath = r'./test/positive' 109 | PTrainData,P_train_num = getDataWithCrop(Ptrain_filePath,np.array([[1]])) 110 | getFeat(PTrainData,'train') 111 | PTestData,P_test_num = getData(Ptest_filePath,np.array([[1]])) 112 | getFeat(PTestData,'test') 113 | 114 | # deal with positive trainset without cutting 115 | Pres_train_filePath = r'./train/positive_rest' 116 | PresTrainData,Pres_train_num = getData(Pres_train_filePath,np.array([[1]])) 117 | getFeat(PresTrainData,'train') 118 | 119 | # deal with negative test dataset and train dataset without cutting 120 | Ntrain_filePath = r'./train/negative' 121 | Ntest_filePath = r'./test/negative' 122 | NTrainData,N_train_num = getData(Ntrain_filePath,np.array([[0]])) 123 | getFeat(NTrainData,'train') 124 | NTestData,N_test_num = getData(Ntest_filePath,np.array([[0]])) 125 | getFeat(NTestData,'test') 126 | 127 | t1 = time.time() 128 | print "------------------------------------------------" 129 | print "Train Positive: %d" %(P_train_num + Pres_train_num) 130 | print "Train Negative: %d" %N_train_num 131 | print "Train Total: %d" %(P_train_num + Pres_train_num + N_train_num) 132 | print "------------------------------------------------" 133 | print "Test Positive: %d" %P_test_num 134 | print "Test Negative: %d" %N_test_num 135 | print "Test Total: %d" %(P_test_num+N_test_num) 136 | print "------------------------------------------------" 137 | print 'The cast of time is:%f'%(t1-t0) 138 | -------------------------------------------------------------------------------- /2_Train_SVM.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Created on Thu Jun 15 16:38:03 2017 5 | 6 | @author: hans 7 | """ 8 | import sklearn.svm as ssv 9 | from sklearn.externals import joblib 10 | import glob 11 | import os 12 | import time 13 | 14 | if __name__ == "__main__": 15 | model_path = './models/svm.model' 16 | train_feat_path = './features/train' 17 | fds = [] 18 | labels = [] 19 | num=0 20 | for feat_path in glob.glob(os.path.join(train_feat_path, '*.feat')): 21 | num += 1 22 | data = joblib.load(feat_path) 23 | fds.append(data[:-1]) 24 | labels.append(data[-1]) 25 | print "%d Dealing with %s" %(num,feat_path) 26 | t0 = time.time() 27 | #------------------------SVM-------------------------------------------------- 28 | clf = ssv.SVC(kernel='rbf') # for training initial model 29 | # clf = ssv.SVC(kernel='rbf', C=17.255220940030252, gamma=1.2943653125547475e-06) # for training svm_pso.model(origin model) 30 | print "Training a SVM Classifier." 31 | clf.fit(fds, labels) 32 | joblib.dump(clf, model_path) 33 | #------------------------SVM-------------------------------------------------- 34 | t1 = time.time() 35 | print "Classifier saved to {}".format(model_path) 36 | print 'The cast of time is :%f seconds' % (t1-t0) 37 | -------------------------------------------------------------------------------- /3_Test_SVM.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Created on Thu Jun 15 16:44:53 2017 5 | 6 | @author: hans 7 | """ 8 | from sklearn.externals import joblib 9 | import glob 10 | import os 11 | import time 12 | 13 | if __name__ == "__main__": 14 | model_path = './models/svm.model' 15 | test_feat_path = './features/test' 16 | total=0 17 | num=0 18 | t0 = time.time() 19 | clf = joblib.load(model_path) 20 | for feat_path in glob.glob(os.path.join(test_feat_path, '*.feat')): 21 | total += 1 22 | print "%d processing: %s" %(total, feat_path) 23 | data_test = joblib.load(feat_path) 24 | data_test_feat = data_test[:-1].reshape((1,-1)) 25 | result = clf.predict(data_test_feat) 26 | if int(result) == int(data_test[-1]): 27 | num += 1 28 | rate = float(num)/total 29 | t1 = time.time() 30 | print 'The classification accuracy is %f' %rate 31 | print 'The cast of time is :%f seconds' % (t1-t0) 32 | -------------------------------------------------------------------------------- /4_Train_PCA+SVM.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | #encoding:utf-8 3 | 4 | """ 5 | Created on Thu Jun 15 17:29:22 2017 6 | 7 | @author: hans 8 | """ 9 | 10 | import numpy as np 11 | import sklearn.svm as ssv 12 | from sklearn.externals import joblib 13 | import glob 14 | import os 15 | import time 16 | m = '20pixel' # HoG choses pixel per cell will gain different number of feature values. 17 | def zeroMean(dataMat): # zero normalisation 18 | meanVal=np.mean(dataMat,axis=0) # calculate mean value of every column. 19 | joblib.dump(meanVal,'./features/PCA/%s/meanVal_train_%s.mean' %(m,m)) # save mean value 20 | newData=dataMat-meanVal 21 | return newData,meanVal 22 | def pca(dataMat,n): 23 | print "Start to do PCA..." 24 | t1 = time.time() 25 | newData,meanVal=zeroMean(dataMat) 26 | covMat=np.cov(newData,rowvar=0) 27 | eigVals,eigVects=np.linalg.eig(np.mat(covMat)) # calculate feature value and feature vector 28 | joblib.dump(eigVals,'./features/PCA/%s/eigVals_train_%s.eig' %(m,m),compress=3) 29 | joblib.dump(eigVects,'./features/PCA/%s/eigVects_train_%s.eig' %(m,m),compress=3) 30 | # eigVals = joblib.load('./features/PCA/%s/eigVals_train_%s.eig' %(m,m)) 31 | # eigVects = joblib.load('./features/PCA/%s/eigVects_train_%s.eig' %(m,m)) 32 | eigValIndice=np.argsort(eigVals) # sort feature value 33 | n_eigValIndice=eigValIndice[-1:-(n+1):-1] # take n feature value 34 | n_eigVect=eigVects[:,n_eigValIndice] # take n feature vector 35 | joblib.dump(n_eigVect,'./features/PCA/%s/n_eigVects_train_%s_%s.eig' %(m,m,n)) 36 | lowDDataMat=newData*n_eigVect # calculate low dimention data 37 | # reconMat=(lowDDataMat*n_eigVect.T)+meanVal 38 | t2 = time.time() 39 | print "PCA takes %f seconds" %(t2-t1) 40 | return lowDDataMat 41 | if __name__ == "__main__": 42 | n = 100 # this is to define how dimentions u want 43 | model_path = './models/%s/svm_%s_pca_%s.model' %(m,m,n) 44 | train_feat_path = './features/train' 45 | fds = [] 46 | labels = [] 47 | num=0 48 | for feat_path in glob.glob(os.path.join(train_feat_path, '*.feat')): 49 | num += 1 50 | data = joblib.load(feat_path) 51 | fds.append(data[:-1]) 52 | labels.append(data[-1]) 53 | print "%d Dealing with %s" %(num,feat_path) 54 | #------------------------PCA-------------------------------------------------- 55 | fds = np.array(fds,dtype = int) #TODO, force to int format may damage the value to be all 0. 56 | fds.shape = 2327,-1 # 2327 is the number of trainset 57 | fds= pca(fds,n) 58 | #------------------------PCA-------------------------------------------------- 59 | t0 = time.time() 60 | #------------------------SVM-------------------------------------------------- 61 | clf = ssv.SVC(kernel='rbf') 62 | print "Training a SVM Classifier." 63 | clf.fit(fds, labels) 64 | joblib.dump(clf, model_path) 65 | #------------------------SVM-------------------------------------------------- 66 | t1 = time.time() 67 | print "Classifier saved to {}".format(model_path) 68 | print 'The cast of time is :%f seconds' % (t1-t0) 69 | -------------------------------------------------------------------------------- /5_Test_PCA+SVM.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Created on Thu Jun 15 17:29:22 2017 5 | 6 | @author: hans 7 | """ 8 | 9 | from sklearn.externals import joblib 10 | import glob 11 | import os 12 | import time 13 | 14 | m = '20pixel' 15 | n = 100 16 | 17 | if __name__ == "__main__": 18 | model_path = './models/%s/svm_%s_pca_%s.model' %(m,m,n) 19 | test_feat_path = './features/test' 20 | total=0 21 | num=0 22 | t0 = time.time() 23 | clf = joblib.load(model_path) 24 | for feat_path in glob.glob(os.path.join(test_feat_path, '*.feat')): 25 | total += 1 26 | print "%d processing: %s" %(total, feat_path) 27 | data_test = joblib.load(feat_path) 28 | data_test_feat = data_test[:-1].reshape((1,-1)) 29 | #------------------------PCA-------------------------------------------------- 30 | meanVal = joblib.load('./features/PCA/%s/meanVal_train_%s.mean' %(m,m)) 31 | data_test_feat = data_test_feat - meanVal 32 | n_eigVects = joblib.load('./features/PCA/%s/n_eigVects_train_%s_%s.eig' %(m,m,n)) 33 | data_test_feat = data_test_feat * n_eigVects 34 | #------------------------PCA-------------------------------------------------- 35 | result = clf.predict(data_test_feat) 36 | if int(result) == int(data_test[-1]): 37 | num += 1 38 | rate = float(num)/total 39 | t1 = time.time() 40 | print 'The classification accuracy is %f' %rate 41 | print 'The cast of time is :%f seconds' % (t1-t0) 42 | -------------------------------------------------------------------------------- /6_PSO+PCA.py: -------------------------------------------------------------------------------- 1 | from sklearn.externals import joblib 2 | import os 3 | from svmutil import svm_train 4 | import numpy as np 5 | import glob 6 | import random 7 | import copy 8 | 9 | n = 2000 10 | train_feat_path = './features/train' 11 | 12 | birds = 20 # size of population 13 | maxgen = 50 14 | pos = [] # population of class 15 | speed = [] 16 | bestpos = [] 17 | initpos = [] 18 | tempfit = [] 19 | birdsbestpos = [] 20 | fds = [] 21 | dict_fds = [] 22 | labels = [] 23 | allbestpos = [] 24 | w = 1 # best belongs to [0.8,1.2] 25 | c1 = 2 26 | c2 = 2 27 | r1 = random.uniform(0,1) 28 | r2 = random.uniform(0,1) 29 | m = 'pso' 30 | 31 | def zeroMean(dataMat): 32 | meanVal=np.mean(dataMat,axis=0) 33 | # joblib.dump(meanVal,'./features/PCA/meanVal_train_%s.mean' %m) 34 | newData=dataMat-meanVal 35 | return newData,meanVal 36 | 37 | def pca(dataMat,n): 38 | print "Start to do PCA..." 39 | newData,meanVal=zeroMean(dataMat) 40 | 41 | # covMat=np.cov(newData,rowvar=0) 42 | # eigVals,eigVects=np.linalg.eig(np.mat(covMat)) 43 | # joblib.dump(eigVals,'./features/PCA/eigVals_train_%s.eig' %m,compress=3) 44 | # joblib.dump(eigVects,'./features/PCA/eigVects_train_%s.eig' %m,compress=3) 45 | 46 | eigVals = joblib.load('./features/PCA/eigVals_train_%s.eig' %m) 47 | eigVects = joblib.load('./features/PCA/eigVects_train_%s.eig' %m) 48 | 49 | eigValIndice=np.argsort(eigVals) 50 | n_eigValIndice=eigValIndice[-1:-(n+1):-1] 51 | n_eigVect=eigVects[:,n_eigValIndice] 52 | # joblib.dump(n_eigVect,'./features/PCA/n_eigVects_train_%s_%s.eig' %(m,n)) 53 | lowDDataMat=newData*n_eigVect 54 | return lowDDataMat 55 | 56 | for feat_path in glob.glob(os.path.join(train_feat_path, '*.feat')): 57 | data = joblib.load(feat_path) 58 | fds.append(data[:-1]) 59 | labels.append(data[-1]) 60 | fds = np.array(fds,dtype = float) 61 | fds= pca(fds,n) 62 | fds = np.array(fds,dtype = float) 63 | 64 | for i in range(len(fds[:,0])): 65 | dict_data = dict(zip(range(len(data))[1:],fds[i,:])) 66 | dict_fds.append(dict_data) 67 | 68 | for i in range(birds): 69 | pos.append([]) 70 | speed.append([]) 71 | bestpos.append([]) 72 | initpos.append([]) 73 | tempfit.append([]) 74 | 75 | def CalDis(list): 76 | fitness=0.0 77 | param = '-t 2 -v 3 -c %s -g %s' %(list[0],list[1]) 78 | fitness = svm_train(labels, dict_fds, param) 79 | return fitness 80 | 81 | for i in range(birds): #initial all birds' pos,speed 82 | pos[i].append(random.uniform(10,30)) 83 | pos[i].append(random.uniform(0.5e-06, 1e-06)) # 1/num_features 84 | speed[i].append(float(0)) 85 | speed[i].append(float(0)) 86 | # speed[i].append(random.uniform(-10,10)) 87 | # speed[i].append(random.uniform(-0.00002,0.00002)) 88 | bestpos[i] = copy.deepcopy(pos[i]) 89 | initpos[i] = copy.deepcopy(pos[i]) 90 | 91 | def FindBirdsMostPos(): 92 | best=CalDis(bestpos[0]) 93 | index = 0 94 | for i in range(birds): 95 | print "\n>>>>>The %d'd time to find globel best pos. Total %d times.\n" %(i+1, birds) 96 | tempfit[i] = CalDis(bestpos[i]) 97 | if tempfit[i] > best: 98 | best = tempfit[i] 99 | index = i 100 | print '------- %d: %f' %(index, best) 101 | return best, bestpos[index] 102 | 103 | print "\n-------------------------Initial Globel Best Pos----------------------------------\n" 104 | best_predict, birdsbestpos = FindBirdsMostPos() #initial birdsbestpos 105 | print "\n-------------------------Done Globel Best Pos----------------------------------\n" 106 | 107 | def NumMulVec(num,list): #result is in list 108 | for i in range(len(list)): 109 | list[i] *= num 110 | return list 111 | 112 | def VecSubVec(list1,list2): #result is in list1 113 | for i in range(len(list1)): 114 | list1[i] -= list2[i] 115 | return list1 116 | 117 | def VecAddVec(list1,list2): #result is in list1 118 | for i in range(len(list1)): 119 | list1[i] += list2[i] 120 | return list1 121 | 122 | def UpdateSpeed(): 123 | #global speed 124 | for i in range(birds): 125 | temp1 = NumMulVec(w,speed[i][:]) 126 | temp2 = VecSubVec(bestpos[i][:],pos[i]) 127 | temp2 = NumMulVec(c1*r1,temp2[:]) 128 | temp1 = VecAddVec(temp1[:],temp2) 129 | temp2 = VecSubVec(birdsbestpos[:],pos[i]) 130 | temp2 = NumMulVec(c2*r2,temp2[:]) 131 | speed[i] = VecAddVec(temp1,temp2) 132 | 133 | def UpdatePos(): 134 | print "Update Pos." 135 | global bestpos,birdsbestpos,tempfit 136 | for i in range(birds): 137 | if pos[i][0]+speed[i][0] > 0 and pos[i][1]+speed[i][1] > 0: 138 | VecAddVec(pos[i],speed[i]) 139 | if CalDis(pos[i]) > tempfit[i]: 140 | bestpos[i] = copy.deepcopy(pos[i]) 141 | best_predict, birdsbestpos = FindBirdsMostPos() 142 | return best_predict, birdsbestpos 143 | 144 | for asd in range(maxgen): 145 | print "\n>>>>>>>>The %d'd time to update parameters. Total %d times\n" %(asd+1, maxgen) 146 | UpdateSpeed() 147 | best_predict, best_para = UpdatePos() 148 | 149 | allbestpos.append([best_para, best_predict]) 150 | f=open('result/PSO_%s-%s-%s.txt' %(birds,maxgen,n),'w') 151 | f.write(str(allbestpos)) 152 | f.close() 153 | 154 | print "After %d iterations\nthe best C is: %f\nthe best gamma is: %f" %(maxgen,best_para[0],best_para[1]) 155 | -------------------------------------------------------------------------------- /7_Hard_Negative_Mining+SVM.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | #encoding:utf-8 3 | 4 | import numpy as np 5 | import sklearn.svm as ssv 6 | from sklearn.externals import joblib 7 | from skimage.feature import hog 8 | import random 9 | import glob 10 | import os 11 | import cv2 12 | 13 | def trainSvm(datas, labels): 14 | clf = ssv.SVC(kernel='rbf', C=17.255220940030252, gamma=1.2943653125547475e-06) #20,50,500,0.842850 15 | print "Training a SVM Classifier." 16 | clf.fit(datas, labels) 17 | return clf 18 | 19 | def loadData(path): 20 | fds_all = [] 21 | # fds = [] 22 | # labels = [] 23 | num=0 24 | for feat_path in glob.glob(os.path.join(path, '*.feat')): 25 | num += 1 26 | data = joblib.load(feat_path) 27 | fds_all.append(data) 28 | # fds.append(data[:-1]) 29 | # labels.append(data[-1]) 30 | print "%d Dealing with %s" %(num,feat_path) 31 | return fds_all 32 | 33 | def sliding_window(image, stepSize, windowSize): 34 | for y in xrange(0, image.shape[0], stepSize): 35 | for x in xrange(0, image.shape[1], stepSize): 36 | yield (x, y, image[y:y + windowSize[1], x:x + windowSize[0]]) 37 | 38 | def rgb2gray(im): 39 | gray = im[:, :, 0]*0.2989+im[:, :, 1]*0.5870+im[:, :, 2]*0.1140 40 | return gray 41 | 42 | def savefeat(childDir, num_win, fd): 43 | fd_name = childDir.split('.')[0] + '_%d.feat' %num_win 44 | fd_path = os.path.join('./features/train_hnm/', fd_name) 45 | joblib.dump(fd, fd_path,compress=3) 46 | 47 | if __name__ == "__main__": 48 | normalize = True 49 | visualize = False 50 | block_norm = 'L2-Hys' 51 | cells_per_block = [2,2] 52 | pixels_per_cell = [20,20] 53 | orientations = 9 54 | new_model_path = './models/svm_pso_hnm.model' 55 | train_feat_path = './features/train_' 56 | fds_all = loadData(train_feat_path) 57 | 58 | model_path = './models/svm_pso.model' 59 | clf = joblib.load(model_path) 60 | 61 | #--------------------hard_negative_mining------------------------------------- 62 | negative_img_path = './train/negative' 63 | num = 0 64 | for childDir in os.listdir(negative_img_path): 65 | num += 1 66 | num_win = 0 67 | print "num: %d hard negative mining: %s" %(num,childDir) 68 | f = os.path.join(negative_img_path, childDir) 69 | data = cv2.imread(f) 70 | scales = [(100, 100), (200,200), (300,300), (400,400), (500, 500), (600,600), (800, 800)] 71 | for (winW,winH) in scales: 72 | for (x, y, window) in sliding_window(data, stepSize=100, windowSize=(winW,winH)): 73 | result = 0 74 | if window.shape[0] != winH or window.shape[1] != winW: 75 | continue 76 | if window.shape[0] != 200 or window.shape[1] != 200: 77 | window = cv2.resize(window,(200,200),interpolation=cv2.INTER_CUBIC) 78 | gray = rgb2gray(window)/255.0 79 | window_fd = hog(gray, orientations, pixels_per_cell, cells_per_block, block_norm, visualize, normalize) 80 | win_fd = window_fd.reshape(1, -1) 81 | result = int(clf.predict(win_fd)) 82 | if result == 1: 83 | num_win += 1 84 | fd = np.concatenate((window_fd, (float(0),))) 85 | fds_all.append(fd) 86 | 87 | savefeat(childDir, num_win, fd) 88 | 89 | # fds.append(window_fd) 90 | # labels.append(float(0)) 91 | 92 | random.shuffle(fds_all) 93 | fds = np.numpy(fds_all)[:, :-1] 94 | labels = np.numpy(fds_all)[:, -1] 95 | new_clf = trainSvm(fds, labels) 96 | #----------------------------------------------------------------------------- 97 | joblib.dump(new_clf, new_model_path) 98 | print "Classifier saved to {}".format(new_model_path) 99 | -------------------------------------------------------------------------------- /8_SlidingWindow+SVM+NMS_image.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Created on Tue Jul 4 15:10:57 2017 5 | 6 | @author: hans 7 | """ 8 | 9 | from imutils.object_detection import non_max_suppression 10 | import numpy as np 11 | from skimage.feature import hog 12 | from sklearn.externals import joblib 13 | import time 14 | import cv2 15 | 16 | normalize = True 17 | visualize = False 18 | block_norm = 'L2-Hys' 19 | cells_per_block = [2,2] 20 | pixels_per_cell = [20,20] 21 | orientations = 9 22 | 23 | def rgb2gray(im): 24 | gray = im[:, :, 0]*0.2989+im[:, :, 1]*0.5870+im[:, :, 2]*0.1140 25 | return gray 26 | 27 | def getFeat(data): 28 | gray = rgb2gray(data)/255.0 29 | fd = hog(gray, orientations, pixels_per_cell, cells_per_block, block_norm, visualize, normalize) 30 | return fd 31 | 32 | def sliding_window(image, stepSize, windowSize): 33 | # slide a window across the image 34 | for y in xrange(0, image.shape[0], stepSize): 35 | for x in xrange(0, image.shape[1], stepSize): 36 | # yield the current window 37 | yield (x, y, image[y:y + windowSize[1], x:x + windowSize[0]]) 38 | 39 | if __name__ == "__main__": 40 | # image_path = str(raw_input("Please enter the path of an image: ")) 41 | image_path = 'test/positive/n03147509_3599.JPEG' 42 | t0 = time.time() 43 | model_path = './models/svm_pso.model' 44 | clf = joblib.load(model_path) 45 | 46 | image = cv2.imread(image_path) 47 | image = cv2.resize(image,(500,500),interpolation=cv2.INTER_CUBIC) 48 | orig = image.copy() 49 | orig = cv2.resize(orig,(500,500),interpolation=cv2.INTER_CUBIC) 50 | rects = [] 51 | scales = [(200,200), (300,300), (400, 400), (image.shape[1],image.shape[0])] 52 | for (winW,winH) in scales: 53 | for (x, y, window) in sliding_window(image, stepSize=90, windowSize=(winW,winH)): 54 | result = 0 55 | if window.shape[0] != winH or window.shape[1] != winW: 56 | continue 57 | cv2.imshow("asd", window) 58 | cv2.waitKey(0) 59 | print window.shape 60 | if window.shape[0] != 200 or window.shape[1] != 200: 61 | window = cv2.resize(window,(200,200),interpolation=cv2.INTER_CUBIC) 62 | win_fd = getFeat(window) 63 | win_fd.shape = 1,-1 64 | result = int(clf.predict(win_fd)) 65 | print 'smamll image result is %d' %result 66 | if result == 1: 67 | rects.append([x, y, x + winW, y + winH]) 68 | cv2.rectangle(orig, (x, y), (x + winW, y + winH), (0, 0, 255), 2) 69 | rects = np.array(rects) 70 | pick = non_max_suppression(rects, probs=None, overlapThresh=0.65) 71 | for (xA, yA, xB, yB) in pick: 72 | cv2.rectangle(image, (xA, yA), (xB, yB), (0, 255, 0), 2) 73 | t1 = time.time() 74 | print 'The cast of time is :%f seconds' % (t1-t0) 75 | cv2.imshow("Before NMS", orig) 76 | cv2.imshow("After NMS", image) 77 | cv2.waitKey(0) 78 | -------------------------------------------------------------------------------- /9_SlidingWindow+SVM+NMS_cam.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Created on Tue Jul 4 15:10:57 2017 5 | 6 | @author: hans 7 | """ 8 | 9 | from imutils.object_detection import non_max_suppression 10 | import numpy as np 11 | from skimage.feature import hog 12 | from sklearn.externals import joblib 13 | import cv2 14 | 15 | def rgb2gray(im): 16 | gray = im[:, :, 0]*0.2989+im[:, :, 1]*0.5870+im[:, :, 2]*0.1140 17 | return gray 18 | 19 | def getFeat(data): 20 | normalize = True 21 | visualize = False 22 | block_norm = 'L2-Hys' 23 | cells_per_block = [2,2] 24 | pixels_per_cell = [20,20] 25 | orientations = 9 26 | gray = rgb2gray(data)/255.0 27 | fd = hog(gray, orientations, pixels_per_cell, cells_per_block, block_norm, visualize, normalize) 28 | return fd 29 | 30 | def sliding_window(image, stepSize, windowSize): 31 | for y in xrange(0, image.shape[0], stepSize): 32 | for x in xrange(0, image.shape[1], stepSize): 33 | yield (x, y, image[y:y + windowSize[1], x:x + windowSize[0]]) 34 | 35 | if __name__ == "__main__": 36 | model_path = './models/svm_pso_85_hnm_50.model' 37 | clf = joblib.load(model_path) 38 | c = cv2.VideoCapture(0) 39 | while 1: 40 | ret, image = c.read() 41 | rects = [] 42 | # image = cv2.resize(image,(500,500),interpolation=cv2.INTER_CUBIC) 43 | scales = [(200,200), (300,300)] 44 | # scales = [(200,200), (250, 250), (300,300)] 45 | for (winW,winH) in scales: 46 | for (x, y, window) in sliding_window(image, stepSize=100, windowSize=(winW,winH)): 47 | result = 0 48 | if window.shape[0] != winH or window.shape[1] != winW: 49 | continue 50 | if window.shape[0] != 200 or window.shape[1] != 200: 51 | window = cv2.resize(window,(200,200),interpolation=cv2.INTER_CUBIC) 52 | win_fd = getFeat(window) 53 | win_fd.shape = 1,-1 54 | result = int(clf.predict(win_fd)) 55 | if result == 1: 56 | rects.append([x, y, x + winW, y + winH]) 57 | rects = np.array(rects) 58 | pick = non_max_suppression(rects, probs=None, overlapThresh=0.1) 59 | minx = 10000 60 | miny = 10000 61 | maxx = 0 62 | maxy = 0 63 | for (xA, yA, xB, yB) in pick: 64 | if xA < minx: 65 | minx = xA 66 | if yA < miny: 67 | miny = yA 68 | if xB > maxx: 69 | maxx = xB 70 | if yB > maxy: 71 | maxy = yB 72 | if (abs(maxx - minx) < image.shape[1]) and (abs(maxy - miny) < image.shape[0]): 73 | cv2.rectangle(image, (minx, miny), (maxx, maxy), (0, 255, 0), 2) 74 | cv2.imshow("After NMS", image) 75 | cv2.waitKey(1) 76 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SVM-classification-detection (Python2.7) 2 | HoG, PCA, PSO, Hard Negative Mining, Sliding Window, NMS 3 | 4 | 5 | ![image](https://github.com/HansRen1024/SVM-classification-localization/blob/master/example.gif) 6 | 7 | 8 | Best way to do detection is: 9 | 10 | HoG(features) -> PCA(less features) + PSO(best C&gamma) -> origin SVM -> HNM(more features) -> better SVM -> SW -> NMS(bbox regression) 11 | 12 | Sorry for my laziness. 13 | 14 | I think I should clarify the steps for the program. 15 | 16 | 1. Extract HoG features (script 1) 17 | 18 | 2. Train an initial model for pso (script 2) 19 | 20 | 3. Do pca and pso for better parameters C and gamma (script 6) 21 | 22 | 4. Use no-pca features and the best parameters to train the second model (script 2) 23 | 24 | 5. In order to increase the accuracy, use the second model to do hnm and get the final model(script 7) 25 | 26 | 6. Finally, choose an algorithm you like to do location(script 8 or 9 or 10) 27 | 28 | **PS:** 29 | 30 | 1. The reason I use pca is to accelerate the speed of pso. To be honestly, pso is really slow. 31 | 32 | 2. For step 4, you can also use features processed by pca, but I strongly advise you to hold as possible as more features. Because more features, higher accuracy. 33 | 34 | 杯子数据集(Dataset): https://pan.baidu.com/s/18ho4UI50x4YP6lkrjPm7Kw 35 | 36 | -------------------------------------------------------------------------------- /example.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HansRen1024/SVM-classification-localization/a40c486893288a71eac84d8daac7414975fe2205/example.gif --------------------------------------------------------------------------------