前言
OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉和机器学习软件库,可以运行在Linux、Windows、Android和Mac 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、效果
给华强哥带上墨镜