1.1必做题要求--人脸特征点检测
1:对实时的视频进行人脸检测功能、定位和标准。著名的深度学习库opencv和dlib均可检测出图像中的人脸。dlib更提供算法,从标注人脸特征点的数据集中训练模型,高效检测出人脸特征点,用于美颜、人脸位置摆正(人脸识别的前期步骤)、面部表情识别。实验室提供face_landmark_detection.py程序和68/194个人脸特征点检测模型,实现静止图像的人脸检测与标注。
2:在此基础上,加入dlib和opencv的目标跟踪算法,于持续视频播放中,每秒中的第1帧图像执行dlib人脸特征点检测,后续图像跟踪这些特征点。而非往届的所有帧图像均执行人脸特征点检测。
3:添加基于光流计算的目标跟踪技术,可以获得英伟达显卡的硬件加速。dlib.correlation_tracker()函数、 cv2.calcOpticalFlowFarneback()函数、 cv2.calcOpticalFlowPyrLK()函数
1.2代码实现
import dlib
import cv2
import numpy as np
import time
# 加载人脸特征点检测器
predictor_path = "shape_predictor_68_face_landmarks.dat"
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor(predictor_path)
# 打开摄像头
cam = cv2.VideoCapture(0)
cam.set(3, 1280) # 设置摄像头宽度
cam.set(4, 720) # 设置摄像头高度
# 设置绘图参数
color_white = (255, 255, 255) # 绘图颜色
line_width = 3 # 绘图线宽
# 设置光流法参数
lk_params = dict(winSize=(15, 15),
maxLevel=2,
criteria=(cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03))
# 初始化跟踪器列表和位置列表
tracker_list = []
pos_list = []
# 设置帧率和计数器
frame_rate = 30
counter = 0
# 获取计时器频率
tick_frequency = cv2.getTickFrequency()
# 开始循环
while True:
start_tick = cv2.getTickCount() # 获取当前计时器的值
ret_val, img = cam.read() # 读取一帧图像
if img is None: # 判断输入图像是否为空
continue # 如果为空,跳过本次循环
if counter % frame_rate == 0: # 每隔一定时间检测一次人脸
rgb_image = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # 转换颜色空间
dets = detector(rgb_image) # 检测人脸位置
tracker_list = [] # 清空跟踪器列表
for det in dets: # 对于每个检测到的人脸
tracker = dlib.correlation_tracker() # 创建跟踪器
tracker.start_track(rgb_image, det) # 开始跟踪
tracker_list.append(tracker) # 将跟踪器添加到列表中
cv2.rectangle(img, (det.left(), det.top()), (det.right(), det.bottom()), color_white, line_width) # 绘制人脸矩形框
shape = predictor(rgb_image, det) # 检测人脸特征点
for i in range(68): # 绘制人脸特征点
cv2.circle(img, (shape.part(i).x, shape.part(i).y), 2, (0, 255, 0), -1)
if len(pos_list) == 0: # 如果位置列表为空,则初始化为整个图像大小
pos_list = [dlib.rectangle(0, 0, img.shape[1], img.shape[0])] * len(tracker_list)
else: # 否则执行光流法跟踪
for i, tracker in enumerate(tracker_list):
ret_val, img = cam.read() # 读取一帧图像
if img is None: # 判断输入图像是否为空
continue # 如果为空,跳过本次循环
rgb_image = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # 转换颜色空间
# 检查 prev_image 和 pos 是否为空
if 'prev_image' not in locals() or prev_image is None:
prev_image = rgb_image.copy()
if len(pos_list) == 0 or pos_list[i] is None:
pos_list[i] = dlib.rectangle(0, 0, img.shape[1], img.shape[0])
prev_pos = tracker.get_position() # 获取上一帧跟踪器的位置
prev_pts = [[prev_pos.left(), prev_pos.top()], [prev_pos.right(), prev_pos.bottom()]]
prev_pts = np.array(prev_pts, dtype=np.float32).reshape(-1, 1, 2) # 将位置转换为数组形式
next_pts, status, err = cv2.calcOpticalFlowPyrLK(prev_image, rgb_image, prev_pts, None, **lk_params) # 计算光流
good_next_pts = next_pts[status == 1] # 选择有效的光流点
if len(good_next_pts) > 0: # 如果有有效的光流点
x_min, y_min = np.min(good_next_pts, axis=0).astype(np.int32) # 计算新位置的左上角坐标
x_max, y_max = np.max(good_next_pts, axis=0).astype(np.int32) # 计算新位置的右下角坐标
tracker.update(rgb_image, dlib.rectangle(x_min, y_min, x_max, y_max)) # 更新跟踪器
# 修正 pos 的计算
pos_list[i] = tracker.get_position() # 获取跟踪器的新位置
if pos_list[i] is not None: # 如果新位置不为空
left = int(pos_list[i].left()) # 获取新位置的左上角坐标
top = int(pos_list[i].top())
right = int(pos_list[i].right()) # 获取新位置的右下角坐标
bottom = int(pos_list[i].bottom())
# 检查 left、top、right、bottom 是否超出图像边界
if left < 0:
left = 0
if top < 0:
top = 0
if right > img.shape[1]:
right = img.shape[1]
if bottom > img.shape[0]:
bottom = img.shape[0]
try:
cv2.rectangle(img, (left, top), (right, bottom), color_white, line_width) # 绘制人脸矩形框
except cv2.error as e:
print(f"Error: {e}")
roi = dlib.rectangle(left, top, right, bottom) # 获取新位置的矩形框
shape = predictor(rgb_image, roi) # 检测人脸特征点
for j in range(68): # 绘制人脸特征点
cv2.circle(img, (shape.part(j).x, shape.part(j).y), 2, (0, 255, 0),-1)
else: # 如果没有有效的光流点,将位置设置为 None
pos_list[i] = None
prev_image = rgb_image.copy() # 将当前图像设置为上一帧图像
counter += 1 # 计数器加一
end_tick = cv2.getTickCount() # 获取当前计时器的值
tick_diff = end_tick - start_tick # 计算计时器的差值
time_diff = tick_diff / tick_frequency # 计算时间差值
sleep_ms = int(max(1, int(1000 / frame_rate - time_diff * 1000))) # 计算休眠时间
time.sleep(sleep_ms / 1000) # 休眠一定时间
cv2.imshow('Face Detection', img) # 显示图像
if cv2.waitKey(1) == 27: # 如果按下 ESC 键,退出程序
break
cam.release() # 释放摄像头
cv2.destroyAllWindows() # 销毁所有窗口
1.3重要流程!
import dlib
import cv2
import numpy as np
其实从代码就可以看出,主要用到的就是dlib,cv2,numpy。其中numpy还算好说,一般python都自带了。Cv2其实是属于opencv的函数,只不过导入的时候是叫做cv2,最麻烦的就是dlib了。而且,我们还得另外找那个68特征点的shape_predictor_68_face_landmarks.dat文件,还好我找到了,已把该代码和dat文件均上传GitHub。
链接:
1.下载并安装anaconda或者miniconda,为了后续的创建虚拟环境
2.windows搜索栏搜索anaconda prompt进入命令行
3.换源:其实就是不用外国的下载网址,我们换到清华源,快一点
在命令行里面输入:(直接CTRL CV就行)
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/msys2/
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/pytorch/
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/
conda config --set show_channel_urls yes
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
4.搭建虚拟环境
命令行输入:
conda create -n cv python==3.7.5 (遇到Proceed([y]/n)就输入y就行,只是在问询你是否确定下载并安装库而已)
activate cv (激活刚刚创建好的环境cv)
pip install opencv-python (安装opencv)
安装完毕后,可在命令行验证安装是否成功
python
import cv2
cv2.__version__
安装正常一般会显示
至此,opencv就安装好了,以后就可以调用了
然后,输入exit(),退出python,重新回到我们的cv虚拟环境。
命令行输入:
conda config --add channels conda-forge
conda install cmake (听说是dlib的前置包,不妨也安装上吧)
conda install dlib
通过这两行,就可以自动找到最适合python3.7.5版本的dlib包,从而,python文件就可以运行啦。虽然只是这两行代码,但是,当时可是找了3h才最终找到并确定可以成功的方法。
1.4运行结果----反正就是能够识别出人脸,用68个点标注出来了边框轮廓和主要特征点--需要一点算力
2.1实验要求----风格迁移
任务核心——深度学习,Python编程,深度学习框架(pytorch 或tensorflow)
图像风格迁移是将一张图像的风格转移到另一张图像上,使得完成风格转移后生成的图像在保持原有内容的基础上具有被转移图像的艺术风格。
基本要求:使用卷积神经网络编程进行图像风格迁移。
进阶要求:使用生成对抗网络进行动漫图像生成。
在设计报告中写出要求、相关技术原理(包括卷积神经网络和生成对抗网络的概括介绍)、方案设计、方框图表达代码流程、调试过程、运行情况(截图)、结论。
2.2代码实现
参考了GitHub上的代码,但原文件包缺少风格模型,故另外找到了6个模型进行调试。
已把完整代码和ckpt(模型)上传GitHub:
GitHub - YZYFZ2H/fast-style-transfer-master-with-ckpt: fast-style-transfer-master with ckpt!!!
用到的工具与包:
1.anaconda或miniconda----用来创建虚拟环境----miniconda其实就是anaconda的简化版,省却了1000+个可能用不着的包,仅保留了创建环境的功能
2.pycharm(其实用不着)----可以打开看看evaluate的内部函数、文件调用情况
3.tensorflow--python框架
4.pillow--python库
5.numpy--python库
6.moviepy--python库--虽然用不着
7.scipy--python库
8.六个ckpt风格模型----已经训练好了,在ckpt文件夹里面
2.3重要流程!(以下操作前,不要挂梯子!)
下载并解压GitHub上的文件夹fast-style-transfer-master
1.下载并安装anaconda或者miniconda,为了后续的创建虚拟环境
2.windows搜索栏搜索anaconda prompt进入命令行
3.换源:其实就是不用外国的下载网址,我们换到清华源,快一点
在命令行里面输入:(直接CTRL CV就行)
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/msys2/
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/pytorch/
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/
conda config --set show_channel_urls yes
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
4.搭建虚拟环境
命令行输入:
conda create -n s-t python=3.8 (这里的s-t其实就是自己命名的环境名字,然后规定了python版本为3.8,因为我在3.7尝试的时候总会出现某库与python版本不匹配,所以一气之下就选择了直接用3.8版本)(遇到Proceed([y]/n)就输入y就行,只是在问询你是否确定下载并安装库而已)
activate s-t (激活刚刚创建好的环境s-t)
pip install tensorflow moviepy (安装tensorflow和moviepy,他会自动安装当前python合适的最高版本的tensorflow和moviepy)
conda install scipy pillow(同理,安装scipy和pillow,自动安装最适合版本)
5.运行evaluate.py文件
这里提供两种做法
5.1一就是继续刚刚的步骤后,
5.1.1 在命令行输入:
cd 。。。。。(这里的。。。。。就是你把这个fast-style-transfer-master文件夹放在了哪里的路径,
比如我的fast-style-transfer-master文件夹路径为
C:\Users\vvvv\Desktop\fast-style-transfer-master
那么我就输入:cd C:\Users\vvvv\Desktop\fast-style-transfer-master ,意思是转到这个文件夹,再进行下一步操作
5.1.2接下来就可以输入:
python evaluate.py --checkpoint ckpt/xxxx.ckpt --in-path examples/content/yyyy.jpg --out-path output/zzzz.jpg
示例:python evaluate.py --checkpoint ckpt/la_muse.ckpt --in-path examples/content/stata.jpg --out-path output/sta.jpg
意思是:
通过python运行evaluate文件,
输入了参数checkpoint为ckpt文件夹下的la_muse.ckpt风格模型路径,
输入了--in-path参数为examples文件夹下的content文件夹下的state.jpg相片路径,
输入了--out-path参数为output文件夹下的zzzz.jpg路径(就是最终完成风格迁移后的文件保存路径)
正常的话就能在output文件夹看到结果啦
5.2法二,如果5.1的方法行不通,就可以尝试
在4的步骤完成后,在命令行输入:
jupyter notebook
这之后就会自动打开默认浏览器,到达jupyter notebook,
在该网站的偏右上的位置有New按钮,点击并选择Terminal,即命令行,他会自动创建新的页面进入命令行
在notebook的命令行里面,进行5.1.1的操作进入文件夹,然后再进行5.1.2的操作,
然后就应该能够正常进行风格迁移了。
2023.7.6检测5.1方法命令行可以正常运行输出(即展示里面的stata与st风格迁移)
2023.7.6检测5.2方法notebook命令行可以正常输出。(即结果展示里面的胡桃的风格迁移)
环境python版本3.8.16,tensorflow版本2.12.0,pillow版本10.0.0,scipy版本1.10.1