作业1内容:
# -*- coding: utf-8 -*-
from PIL import Image
import cv2
import numpy as np
import math
import os
cell_size = 8
bin_size = 9
angle_unit = 180 / bin_size
cell_gradient_vector = np.zeros((int(128/cell_size),int(128/cell_size), bin_size))
def cell_gradient(cell_mag, cell_angle):
'''Calculate Gradients in 8*8 cells'''
orientation_centers = [0] * bin_size
for k in range(cell_mag.shape[0]):
for l in range(cell_mag.shape[1]):
gradient_strength = cell_mag[k][l]
gradient_angle = cell_angle[k][l]
if gradient_angle<160:
min_angle = int(gradient_angle / angle_unit)%8
max_angle = (min_angle + 1) % bin_size
mod = gradient_angle % angle_unit
orientation_centers[min_angle] +=(gradient_strength*(1-(mod/angle_unit)))
orientation_centers[max_angle] +=(gradient_strength*(mod/angle_unit))
else:
mod = gradient_angle%angle_unit
orientation_centers[bin_size-1] +=(gradient_strength*(1-(mod/angle_unit)))
orientation_centers[0] +=(gradient_strength*(mod/angle_unit))
return orientation_centers
def preprocess(im):
'''Preprocessing'''
#im=Image.open(im)
#region=im.crop((159,68,328,229))
#region=region.resize((128, 128),Image.ANTIALIAS)
img=Image.open(im)
img=cv2.cvtColor(np.asarray(img),cv2.COLOR_RGB2BGR)
img=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
return img
def Gradient_Image(img):
'''Calculate the Gradient Images'''
gx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=1)
gy = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=1)
mag,angle=cv2.cartToPolar(gx,gy,angleInDegrees=True)
for i in range(128):
for j in range(128):
if (angle[i,j]>=180):
angle[i,j]=angle[i,j]-180
return mag,angle
def hog_vector(mag,angle):
'''Calculate Histogram of Gradients in 8*8 cells'''
cell_gradient_vector = np.zeros((int(128/cell_size),int(128/cell_size), bin_size))
for i in range(cell_gradient_vector.shape[0]):
for j in range(cell_gradient_vector.shape[1]):
cell_magnitude=mag[i*cell_size:(i+1)*cell_size,j*cell_size:(j+1)*cell_size]
cell_angle=angle[i*cell_size:(i+1)*cell_size,j*cell_size:(j+1)*cell_size]
cell_gradient_vector[i][j] = cell_gradient(cell_magnitude, cell_angle)
'''16*16 Block Normalization'''
hog_vector = []
for i in range(cell_gradient_vector.shape[0] - 1):
for j in range(cell_gradient_vector.shape[1] - 1):
block_vector = []
block_vector.extend(cell_gradient_vector[i][j])
block_vector.extend(cell_gradient_vector[i][j + 1])
block_vector.extend(cell_gradient_vector[i + 1][j])
block_vector.extend(cell_gradient_vector[i + 1][j + 1])
mag = lambda vector: math.sqrt(sum(i ** 2 for i in vector))
magnitude = mag(block_vector)
if magnitude != 0:
normalize = lambda block_vector, magnitude: [element / magnitude for element in block_vector]
block_vector = normalize(block_vector, magnitude)
hog_vector.append(block_vector)
hog_vector_final=[]
for i in hog_vector:
hog_vector_final.extend(i)
return np.array(hog_vector_final)
'''read image files and creat hog feature dataset'''
pos_im_file="./classifer/bounding box/posimage"
neg_im_file="./classifer/bounding box/negimage"
def loadimg_infile(imgdir):
imgname=[]
imgname_sorted=[]
filename=os.listdir(imgdir)
for file in filename:
if 'jpg' in file:
imgname.append(imgdir+file)
s=len(imgname)
for i in range(s):
imgname_sorted.append(imgdir+'/'+str(i+1)+'.jpg')
return imgname_sorted
pos_im_list=loadimg_infile(pos_im_file)
neg_im_list=loadimg_infile(neg_im_file)
xdata=[]
ydata=[]
for pos_im in pos_im_list:
mag,angle=Gradient_Image(preprocess(pos_im))
xdata.append(hog_vector(mag,angle))
ydata.append(1.0)
for neg_im in neg_im_list:
mag,angle=Gradient_Image(preprocess(neg_im))
xdata.append(hog_vector(mag,angle))
ydata.append(0.0)
'''split data to train and test'''
from sklearn.cross_validation import train_test_split
test_size=0.1
X_train,X_test,y_train,y_test=train_test_split(xdata,ydata,test_size=test_size,random_state=1)
'''different kinds of classifers'''
import matplotlib.pyplot as plt
from sklearn.naive_bayes import GaussianNB
from sklearn.naive_bayes import MultinomialNB
from sklearn.linear_model import LogisticRegression
from sklearn.neighbors import KNeighborsClassifier
from sklearn.svm import SVC
from sklearn import metrics
from sklearn.metrics import precision_recall_curve, roc_curve, auc
from sklearn.externals import joblib
#clf = GaussianNB()
#clf = MultinomialNB(alpha=0.01)
#clf = LogisticRegression()
#clf = SVC(kernel = 'linear')
#clf = KNeighborsClassifier()
clf = SVC(kernel='linear', gamma= 0.5, C = 2.0)
clf.fit(X_train,y_train)
pred = clf.predict(xdata)
s = metrics.confusion_matrix(ydata,pred,labels=None)
print(s)
pred_train = clf.predict(X_train)
pred_test = clf.predict(X_test)
s_train= metrics.confusion_matrix(y_train,pred_train,labels=None)
s_test= metrics.confusion_matrix(y_test,pred_test,labels=None)
accuracy_train=(s_train[0][0]+s_train[1][1])/(100-100*test_size)
accuracy_test=(s_test[0][0]+s_test[1][1])/(100*test_size)
print('accuracy_train:',accuracy_train)
print('accuracy_test:',accuracy_test)
#joblib.dump(clf, "train_model.m")#save trained model
#clf = joblib.load("train_model.m") #load existed trained model
'''Test the detector'''
testimg='./classifer/posimage/3.jpg'
truelabel=[159,68,328,229] #图片对应的真实标签
img2=Image.open(testimg)
'''
w_size和stride可调
'''
w_size=150#window_size
stride=8 #step_size
imgbgr=cv2.cvtColor(np.asarray(img2),cv2.COLOR_RGB2BGR)
imggray=cv2.cvtColor(imgbgr,cv2.COLOR_BGR2GRAY)
mag,angle=Gradient_Image(imggray)
iarray=[]#记录近奥巴马脸区域检测出很多框的左上角i
jarray=[]#记录近奥巴马脸区域检测出很多框的左上角j
for i in range(int((imggray.shape[0]-w_size)/stride)):
for j in range(int((imggray.shape[1]-w_size)/stride)):
imgcrop=imggray[i*stride:i*stride+w_size,j*stride:j*stride+w_size]
imgcrop=Image.fromarray(imgcrop)
imgcrop=imgcrop.resize((128, 128),Image.ANTIALIAS)
imgcrop=cv2.cvtColor(np.asarray(imgcrop),cv2.COLOR_BAYER_GR2GRAY)
recmag,recangle=Gradient_Image(imgcrop)
hogrec=hog_vector(recmag,recangle)
hogrec=hogrec.reshape(1,-1)
prediction=clf.predict(hogrec)
if int(prediction[0])==1:
#cv2.rectangle(imgbgr, (i,j), (i+128,j+128), (0,255,0), 1)
iarray.append(i*stride)
jarray.append(j*stride)
'''
蓝色为原先标签,绿色为检测出的奥巴马人脸区域,
红色为绿色的平均,
'''
#draw original labels
cv2.rectangle(imgbgr, (159,68), (328,229), (255,0,0), 2)
#draw detected Obama face by above code
if len(iarray)>0:
iarray_avg=int(sum(iarray)/len(iarray))
jarray_avg=int(sum(jarray)/len(jarray))
#画红色
cv2.rectangle(imgbgr, (jarray_avg,iarray_avg), (jarray_avg+w_size,iarray_avg+w_size), (0,0,255), 2)
for i in iarray:
for j in jarray:
cv2.rectangle(imgbgr, (j,i), (j+w_size,i+w_size), (0,255,0), 1)
cv2.imshow('Frame',imgbgr)
cv2.waitKey(0)
else:
print("Obama not in this picture under this window size and stride")
结果: