栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

SVM深入理解&人脸特征提取

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SVM深入理解&人脸特征提取

SVM深入理解&人脸特征提取
  • 第一问:对照参考资料“支持向量机-课件-518.docx”,将其中的例子代码在Jupyter中重新做一遍
    • 一.多项式分类函数对鸢尾花、月亮数据集进行SVM训练
      • 1.SVM处理线性数据集(鸢尾花数据集)
        • (1)引入python库
        • (2)选取数据集的特征
        • (3)可视化
        • (4)定义绘制决策边界函数与绘制决策边界
        • (5)实例化SVC,并传入参数C值
      • 2.SVM处理非线性数据集(月亮数据集)
        • (1)引入python库
        • (2)构建月亮的特征数据并可视化
        • (3)生成噪声点并可视化
        • (4)定义非线性SVM分类函数
        • (5)调用PolynomialSVC函数进行分类可视化
    • 二.高斯核函数
      • 1.随机生成数据并可视化
      • 2.利用高斯核函数,进行数据的升维(一维升二维)
    • 三.核函数处理月亮数据集
      • 1.导入需要的python库
      • 2.导入月亮数据集并可视化
      • 3.定义RBF核的SVM分类函数
      • 4.实例化SVC并传递γ gammaγ参数
        • (1)令γ=200并可视化
        • (2)令γ=20并可视化
        • (3)令γ=0.并可视化
  • 第二问:以人脸识别(属于分类问题)为例,理解实际应用中的特征数据集提取
    • 一.用python3+opencv3.4+dlib库编程,打开摄像头,实时采集人脸并保存、绘制68个特征点
      • 1.绘制脸部特征点
      • 2.给人脸虚拟P上墨镜

第一问:对照参考资料“支持向量机-课件-518.docx”,将其中的例子代码在Jupyter中重新做一遍 一.多项式分类函数对鸢尾花、月亮数据集进行SVM训练 1.SVM处理线性数据集(鸢尾花数据集) (1)引入python库
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.preprocessing import StandardScaler
from sklearn.svm import LinearSVC

(2)选取数据集的特征
iris = datasets.load_iris()

X = iris.data
y = iris.target

X = X [y<2,:2] #只取y<2的类别,也就是0 1 并且只取前两个特征
y = y[y<2] # 只取y<2的类别

# 分别画出类别0和1的点
plt.scatter(X[y==0,0],X[y==0,1],color='red') 
plt.scatter(X[y==1,0],X[y==1,1],color='blue')
plt.show()

(3)可视化

(4)定义绘制决策边界函数与绘制决策边界

定义:

def plot_decision_boundary(model, axis):
    x0, x1 = np.meshgrid(
        np.linspace(axis[0], axis[1], int((axis[1]-axis[0])*100)).reshape(-1,1),
        np.linspace(axis[2], axis[3], int((axis[3]-axis[2])*100)).reshape(-1,1)
    )
    X_new = np.c_[x0.ravel(), x1.ravel()]
    
    y_predict = model.predict(X_new)
    zz = y_predict.reshape(x0.shape)
    
    from matplotlib.colors import ListedColormap
    custom_cmap = ListedColormap(['#EF9A9A','#FFF59D','#90CAF9'])    
    plt.contourf(x0, x1, zz, linewidth=5, cmap=custom_cmap)

绘制

# 绘制决策边界
plot_decision_boundary(svc,axis=[-3,3,-3,3]) # x,y轴都在-3到3之间
# 绘制原始数据
plt.scatter(X_standard[y==0,0],X_standard[y==0,1],color='red') 
plt.scatter(X_standard[y==1,0],X_standard[y==1,1],color='blue')
plt.show()

绘制结果

(5)实例化SVC,并传入参数C值

c=0.5

c=100000

容易看出在c=0.5时决策边界汇总,有一个红点是分类错误的,这意味着:C值越小容错空间越大,越容易出现错误

2.SVM处理非线性数据集(月亮数据集) (1)引入python库
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.preprocessing import PolynomialFeatures,StandardScaler
from sklearn.svm import LinearSVC
from sklearn.pipeline import Pipeline
from sklearn.svm import SVC

(2)构建月亮的特征数据并可视化

代码:

X, y = datasets.make_moons() #使用生成的数据
#print(X.shape) # (100,2)
#print(y.shape) # (100,)
plt.scatter(X[y==0,0],X[y==0,1]) 
plt.scatter(X[y==1,0],X[y==1,1])
plt.show()

可视化结果:

(3)生成噪声点并可视化

代码:

X, y = datasets.make_moons(noise=0.15,random_state=777) #随机生成噪声点,random_state是随机种子,noise是方差
plt.scatter(X[y==0,0],X[y==0,1]) 
plt.scatter(X[y==1,0],X[y==1,1])
plt.show()

可视化结果:

(4)定义非线性SVM分类函数

代码:

def PolynomialSVC(degree,C=1.0):
    return Pipeline([
        ("poly",PolynomialFeatures(degree=degree)),#生成多项式
        ("std_scaler",StandardScaler()),#标准化
        ("linearSVC",LinearSVC(C=C))#最后生成svm
    ])

(5)调用PolynomialSVC函数进行分类可视化

代码:

poly_svc = PolynomialSVC(degree=5)
poly_svc.fit(X,y)
plot_decision_boundary(poly_svc,axis=[-1.5,2.5,-1.0,1.5])
plt.scatter(X[y==0,0],X[y==0,1]) 
plt.scatter(X[y==1,0],X[y==1,1])
plt.show()

可视化结果:

总结:生成的边界不再是线性的直线了,因为月亮数据集提取的两个特征并不是线性的

二.高斯核函数 1.随机生成数据并可视化

代码:

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(-4,5,1)#生成测试数据
y = np.array((x >= -2 ) & (x <= 2),dtype='int')

plt.scatter(x[y==0],[0]*len(x[y==0]))# x取y=0的点, y取0,有多少个x,就有多少个y
plt.scatter(x[y==1],[0]*len(x[y==1]))
plt.show()

可视化结果:

2.利用高斯核函数,进行数据的升维(一维升二维)

高斯函数定义:

def gaussian(x,l):
    gamma = 1.0
    return np.exp(-gamma * (x -l)**2)

l1,l2 = -1,1
X_new = np.empty((len(x),2)) #len(x) ,2
for i,data in enumerate(x):
    X_new[i,0] = gaussian(data,l1)
    X_new[i,1] = gaussian(data,l2)
plt.scatter(X_new[y==0,0],X_new[y==0,1])
plt.scatter(X_new[y==1,0],X_new[y==1,1])
plt.show()

结果可以看出二维数据显然是线性可分的

三.核函数处理月亮数据集 1.导入需要的python库
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from sklearn.pipeline import Pipeline

2.导入月亮数据集并可视化

代码:

X,y = datasets.make_moons(noise=0.15,random_state=777)
plt.scatter(X[y==0,0],X[y==0,1])
plt.scatter(X[y==1,0],X[y==1,1])
plt.show()

可视化结果:

3.定义RBF核的SVM分类函数

代码:

def RBFKernelSVC(gamma=1.0):
    return Pipeline([
        ('std_scaler',StandardScaler()),
        ('svc',SVC(kernel='rbf',gamma=gamma))
    ])

4.实例化SVC并传递γ gammaγ参数 (1)令γ=200并可视化
svc = RBFKernelSVC(200)
svc.fit(X,y)
plot_decision_boundary(svc,axis=[-1.5,2.5,-1.0,1.5])
plt.scatter(X[y==0,0],X[y==0,1]) 
plt.scatter(X[y==1,0],X[y==1,1])
plt.show()

可视化结果:

(2)令γ=20并可视化

代码:

svc = RBFKernelSVC(20)
svc.fit(X,y)
plot_decision_boundary(svc,axis=[-1.5,2.5,-1.0,1.5])
plt.scatter(X[y==0,0],X[y==0,1]) 
plt.scatter(X[y==1,0],X[y==1,1])
plt.show()

结果:

(3)令γ=0.并可视化

代码:

svc = RBFKernelSVC(0.2)
svc.fit(X,y)
plot_decision_boundary(svc,axis=[-1.5,2.5,-1.0,1.5])
plt.scatter(X[y==0,0],X[y==0,1]) 
plt.scatter(X[y==1,0],X[y==1,1])
plt.show()

结果

结论:γ 取值越大,就是高斯分布的钟形图越窄,这里相当于每个样本点都形成了钟形图。

第二问:以人脸识别(属于分类问题)为例,理解实际应用中的特征数据集提取 一.用python3+opencv3.4+dlib库编程,打开摄像头,实时采集人脸并保存、绘制68个特征点 1.绘制脸部特征点

1.代码:

# -*- coding: utf-8 -*-
"""
Created on Wed Oct 27 03:15:10 2021

@author: GT72VR
"""
#导入库
import numpy as np#数据处理库
import cv2#图像处理库
import dlib#人脸识别的库
import os
import sys
import random
# 存储位置
output_dir = 'D/faces'
size = 64
 
if not os.path.exists(output_dir):
    os.makedirs(output_dir)
# 改变图片的亮度与对比度
 
def relight(img, light=1, bias=0):
    w = img.shape[1]
    h = img.shape[0]
    #image = []
    for i in range(0,w):
        for j in range(0,h):
            for c in range(3):
                tmp = int(img[j,i,c]*light + bias)
                if tmp > 255:
                    tmp = 255
                elif tmp < 0:
                    tmp = 0
                img[j,i,c] = tmp
    return img
 
#使用dlib自带的frontal_face_detector作为我们的特征提取器
detector = dlib.get_frontal_face_detector()
# 打开摄像头 参数为输入流,可以为摄像头或视频文件
camera = cv2.VideoCapture(0)
#camera = cv2.VideoCapture('C:/Users/CUNGU/Videos/Captures/wang.mp4')
ok = True

detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')


while ok:
    # 读取摄像头中的图像,ok为是否读取成功的判断参数
    ok, img = camera.read()
    
    # 转换成灰度图像
    img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    rects = detector(img_gray, 0)
    
    for i in range(len(rects)):
        landmarks = np.matrix([[p.x, p.y] for p in predictor(img,rects[i]).parts()])
        for idx, point in enumerate(landmarks):
            # 68点的坐标
            pos = (point[0, 0], point[0, 1])
            print(idx,pos)
    
            # 利用cv2.circle给每个特征点画一个圈,共68个
            cv2.circle(img, pos, 2, color=(0, 255, 0))
            # 利用cv2.putText输出1-68
            font = cv2.FONT_HERSHEY_SIMPLEX
            cv2.putText(img, str(idx+1), pos, font, 0.2, (0, 0, 255), 1,cv2.LINE_AA)
    cv2.imshow('video', img)
    k = cv2.waitKey(1)
    if k == 27:    # press 'ESC' to quit
        break
    
camera.release()
cv2.destroyAllWindows()


2.给人脸虚拟P上墨镜

代码:

import numpy as np
import cv2
import dlib
import os
import sys
import random
def get_detector_and_predicyor():
    #使用dlib自带的frontal_face_detector作为我们的特征提取器
    detector = dlib.get_frontal_face_detector()
    """
    功能:人脸检测画框
    参数:PythonFunction和in Classes
    in classes表示采样次数,次数越多获取的人脸的次数越多,但更容易框错
    返回值是矩形的坐标,每个矩形为一个人脸(默认的人脸检测器)
    """
    #返回训练好的人脸68特征点检测器
    predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')
    return detector,predictor
#获取检测器
detector,predictor=get_detector_and_predicyor()

def painting_sunglasses(img,detector,predictor):   
    #给人脸带上墨镜
    rects = detector(img_gray, 0)  
    for i in range(len(rects)):
        landmarks = np.matrix([[p.x, p.y] for p in predictor(img,rects[i]).parts()])
        right_eye_x=0
        right_eye_y=0
        left_eye_x=0
        left_eye_y=0
        for i in range(36,42):#右眼范围
            #将坐标相加
            right_eye_x+=landmarks[i][0,0]
            right_eye_y+=landmarks[i][0,1]
        #取眼睛的中点坐标
        pos_right=(int(right_eye_x/6),int(right_eye_y/6))
        """
        利用circle函数画圆
        函数原型      
        cv2.circle(img, center, radius, color[, thickness[, lineType[, shift]]])
        img:输入的图片data
        center:圆心位置
        radius:圆的半径
        color:圆的颜色
        thickness:圆形轮廓的粗细(如果为正)。负厚度表示要绘制实心圆。
        lineType: 圆边界的类型。
        shift:中心坐标和半径值中的小数位数。
        """
        cv2.circle(img=img, center=pos_right, radius=30, color=(0,0,255),thickness=1)#红色边框
        cv2.circle(img=img, center=pos_right, radius=30, color=(0,0,0),thickness=-1)#黑色
        for i in range(42,48):#左眼范围
           #将坐标相加
            left_eye_x+=landmarks[i][0,0]
            left_eye_y+=landmarks[i][0,1]
        #取眼睛的中点坐标
        pos_left=(int(left_eye_x/6),int(left_eye_y/6))
        cv2.circle(img=img, center=pos_left, radius=30, color=(0,0,255),thickness=1)#红色边框
        cv2.circle(img=img, center=pos_left, radius=30, color=(0,0,0),thickness=-1)#黑色

camera = cv2.VideoCapture(0)#打开摄像头
ok=True
# 打开摄像头 参数为输入流,可以为摄像头或视频文件
while ok:
    ok,img = camera.read()
     # 转换成灰度图像
    img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    #display_feature_point(img,detector,predictor)
    painting_sunglasses(img,detector,predictor)#调用画墨镜函数
    cv2.imshow('video', img)
    k = cv2.waitKey(1)
    if k == 27:    # press 'ESC' to quit
        break
camera.release()
cv2.destroyAllWindows()

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/468419.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号