御神楽的学习记录之SVM深入理解&人脸特征提取

该博客介绍了使用OpenCV进行鸢尾花数据集的SVM分类,包括线性和高斯核函数的实现,并展示了决策边界的绘制。此外,还详细讲解了人脸特征提取的过程,通过dlib库标记特征点并应用简单的墨镜效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


前言

OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉和机器学习软件库,可以运行在Linux、Windows、AndroidMac OS操作系统上。 它轻量级而且高效–由一系列 C 函数和少量 C++ 类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。


一、鸢尾花数据集SVM分类

1.引入库和数据

引入库

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

导入鸢尾花数据

iris = datasets.load_iris()
x_iris = iris.data
y_iris = iris.target

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

# 分别画出类别0和1的点
plt.scatter(x_iris[y_iris==0,0],x_iris[y_iris==0,1]) 
plt.scatter(x_iris[y_iris==1,0],x_iris[y_iris==1,1])
plt.show()

数据集图像:
在这里插入图片描述

2.数据分类函数

1、非线性SVM分类,当degree为0表示线性,大于0为多项式

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

2、高斯核函数

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

3、绘制决策边界函数

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)

3.数据分类

1、多项式分类

poly_svc_iris = PolynomialSVC(degree=5,C=10)
#拟合
poly_svc_iris.fit(x_iris,y_iris)
# 绘制决策边界
plot_decision_boundary(poly_svc_iris,axis=[4,7.5,1,4.5]) # x,y轴都在-3到3之间
# 绘制原始数据
plt.scatter(x_iris[y_iris==0,0],x_iris[y_iris==0,1]) 
plt.scatter(x_iris[y_iris==1,0],x_iris[y_iris==1,1])
plt.show()

分类结果
在这里插入图片描述
2、高斯核分类

rbf_svc_iris = RBFKernelSVC(1)
#拟合
rbf_svc_iris.fit(x_iris,y_iris)
# 绘制决策边界
plot_decision_boundary(rbf_svc_iris,axis=[4,7.5,1,4.5])
# 绘制原始数据
plt.scatter(x_iris[y_iris==0,0],x_iris[y_iris==0,1]) 
plt.scatter(x_iris[y_iris==1,0],x_iris[y_iris==1,1])
plt.show()

分类结果
在这里插入图片描述
月亮数据集参考上一篇文章:https://blog.csdn.net/YuKaguraNe/article/details/121168739

二、人脸特征提取

1.特征点标记实现

1、库引入

import numpy as np
import cv2
import dlib
import os
import sys
import random

2、主要函数代码

# 存储位置
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("huaqiang2.mp4")
# camera = cv2.VideoCapture('mv.flv')
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),thickness=(1))
                
            # 利用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('vedio', img)
    k = cv2.waitKey(10)
    if k == 27:    # press 'ESC' to quit
        break
    
camera.release()
cv2.destroyAllWindows()

3、人脸特征识别结果
在这里插入图片描述

2.使用opencv函数简单墨镜效果

1、在函数中添加条件,只在特定点位画圈
眼睛点位从37开始到48结束

if idx in range(37,48):
                
                if idx==37:
                    pos_s1=(point[0, 0], point[0, 1])
                elif idx==38:
                    pos_s2=(point[0, 0], point[0, 1])
                    size=(pow(pow(pos_s2[1]-pos_s1[1],2)+pow(pos_s2[0]-pos_s1[0],2),0.5))
                elif idx ==39:
                    pos_1=(point[0, 0], point[0, 1])
                elif idx==42:
                    pos_2=(point[0, 0], point[0, 1])
                elif idx==41 or idx==46:
                    cv2.circle(img,pos,int(3*size),(0,0,0),-1)
            if idx>42:
                cv2.line(img, pos_1, pos_2, (0, 0, 0), 4)

替换掉原来的画圈标记即可
2、效果
在这里插入图片描述
给华强哥带上墨镜


参考

https://blog.csdn.net/qq_43279579/article/details/117637044

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值