基于hog的人脸识别-作业1

作业1内容:


image.png

image.png

image.png

image.png
# -*- 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")


结果:


image.png

你可能感兴趣的:(基于hog的人脸识别-作业1)