This is the ipython notebook for the shiyanlou svm_cat
Reference: https://www.shiyanlou.com/courses/794
import numpy as np
import cv2
from os.path import dirname, join, basename
import os
import sys
from glob import glob
bin_n = 16 * 16
def hog(img):
x_pixel, y_pixel = 194, 259
gx = cv2.Sobel(img, cv2.CV_32F, 1, 0)
gy = cv2.Sobel(img, cv2.CV_32F, 0, 1)
mag, ang = cv2.cartToPolar(gx, gy)
bins = np.int32(bin_n*ang/(2*np.pi))
bin_cells = bins[:x_pixel/2, :y_pixel/2], bins[x_pixel/2:, :y_pixel/2], bins[:x_pixel/2, y_pixel/2:], bins[x_pixel/2:, y_pixel/2:]
mag_cells = mag[:x_pixel/2,:y_pixel/2], mag[x_pixel/2:,:y_pixel/2], mag[:x_pixel/2,y_pixel/2:], mag[x_pixel/2:,y_pixel/2:]
hists = [np.bincount(b.ravel(), m.ravel(), bin_n) for b, m in zip(bin_cells, mag_cells)]
hist = np.hstack(hists)
return hist
img = []
for name in os.listdir(os.getcwd() + '/cat/'):
pic = cv2.imread(os.getcwd() + '/cat/' + name, 0)
img.append(pic)
print len(img), ' num'
positive = len(img)
for name in os.listdir(os.getcwd() + '/other/'):
pic = cv2.imread(os.getcwd() + '/other/' + name, 0)
img.append(pic)
print len(img), ' num'
print positive, ' positive'
trainpic = []
for item in img:
trainpic.append(item)
svm_params = dict(kernel_type = cv2.SVM_LINEAR, svm_type = cv2.SVM_C_SVC, C = 2.67, gamma = 5.383)
# test
tmp = hog(img[0])
print tmp.shape
# data preprocessing
hogdata = map(hog, trainpic)
print np.float32(hogdata).shape, ' hogdata'
trainData = np.float32(hogdata).reshape(-1, bin_n*4)
print trainData.shape, ' trainData'
responses = np.float32(np.repeat(1.0, trainData.shape[0])[:, np.newaxis])
responses[positive:trainData.shape[0]] = -1.0
print responses.shape, ' responses'
print len(trainData)
print len(responses)
print type(trainData)
svm = cv2.SVM()
svm.train(trainData, responses, params=svm_params)
svm.save('svm_cat_data.dat')
svm = cv2.SVM()
svm.load('svm_cat_data.dat')
# test
img = cv2.imread('./predict/01.jpg', 0)
print img.shape, ' img_test0'
hogdata = hog(img)
testData = np.float32(hogdata).reshape(-1, bin_n*4)
print testData.shape, ' testData'
result = svm.predict(testData)
print result
if result > 0:
print ' this pic is a cat!'
# preprocess for prediction
test_tmp = []
for name in os.listdir(os.getcwd() + '/predict/'):
img = cv2.imread(os.getcwd() + '/predict/' + name, 0)
test_tmp.append(img)
print len(test_tmp), ' len(test_tmp)'
# predict
hogdata = map(hog, test_tmp)
testData = np.float32(hogdata).reshape(-1, bin_n*4)
print testData.shape, ' testData'
result = [svm.predict(item) for item in testData]
print result
use sklearn to build the svm models instead of opencv
import os
import cv2
import numpy as np
from skimage import feature as ft
from sklearn.svm import SVC
img = []
# positive
for name in os.listdir(os.getcwd() + '/cat/'):
pic = cv2.imread(os.getcwd() + '/cat/' + name, 0)
img.append(pic)
positive = len(img)
print "positive samples: {}".format(positive)
# negative
for name in os.listdir(os.getcwd() + '/other/'):
pic = cv2.imread(os.getcwd() + '/other/' + name, 0)
img.append(pic)
print "negative samples: {}".format(len(img) - positive)
# predict
predict_img = []
for name in os.listdir(os.getcwd() + '/predict/'):
pic = cv2.imread(os.getcwd() + '/predict/' + name, 0)
predict_img.append(pic)
print "prediction samples: {}".format(len(predict_img))
def myHog(img):
feature = ft.hog(img, orientations=8, pixels_per_cell=(16,16), cells_per_block=(1,1))
return feature
HOG_feature = map(myHog, img)
predict_feature = map(myHog, predict_img)
predict_vector = np.asarray(predict_feature)
vector = np.asarray(HOG_feature)
label = np.array(np.repeat(1, vector.shape[0]))
label[positive:] = 0
clf = SVC(kernel='linear', C=2.67, gamma=5.383)
clf.fit(vector, label)
predict_label = clf.predict(predict_vector)
predict_label
The process of these two solutions are almost the same, and the only difference is that skimage provides the hog function.