毕业设计——基于OpenCV的视频中人脸替换技术的研究与实现

本文详细介绍了基于OpenCV的视频中人脸替换技术,涵盖了其研究背景、现状、关键的面部检测、关键点定位、图像融合以及深度学习的应用,展示了技术在影视特效和娱乐领域的潜力,同时讨论了未来的发展趋势和挑战。
摘要由CSDN通过智能技术生成

如需完整源码,可以联系博主获取。

一、引言

人脸替换技术,作为计算机视觉和图像处理领域的一个重要研究方向,近年来在影视特效、虚拟现实、娱乐应用等领域得到了广泛的应用。基于OpenCV的视频中人脸替换技术,旨在通过先进的算法和工具,实现对视频中人脸的精准识别和实时替换,从而创造出更加丰富和多样的视觉效果。本文综述了基于OpenCV的视频中人脸替换技术的研究背景、现状、关键技术以及应用前景,旨在为相关研究者和实践者提供有价值的参考和借鉴。

二、研究背景与现状

随着计算机视觉和图像处理技术的不断发展,人脸替换技术已经成为一个热门的研究课题。传统的人脸替换方法通常依赖于复杂的图像处理流程和手工操作,难以实现高效、精准的替换效果。而基于OpenCV的人脸替换技术,利用OpenCV强大的图像处理能力和灵活的编程接口,为研究者提供了一种更加便捷和高效的解决方案。

目前,基于OpenCV的人脸替换技术已经取得了一定的研究进展。研究者们通过结合人脸检测、人脸关键点定位、图像融合等技术,实现了对视频中人脸的自动识别和替换。同时,随着深度学习技术的发展,基于神经网络的人脸替换方法也逐渐成为研究的热点。这些方法通过训练深度神经网络模型,能够学习到更加复杂和精细的人脸特征,从而进一步提高人脸替换的准确性和自然度。

三、关键技术

基于OpenCV的视频中人脸替换技术涉及多个关键技术环节。首先是人脸检测与跟踪,这是实现人脸替换的前提和基础。通过采用Haar级联、dlib库等算法,可以实现对视频中人脸的精准定位和实时跟踪。其次是人脸关键点定位,通过对人脸关键点的提取和分析,可以进一步提高人脸替换的精度和稳定性。此外,图像融合技术也是实现自然、无缝人脸替换的关键。通过采用适当的融合算法和参数调整,可以使替换后的人脸与原始视频背景更好地融合在一起。

近年来,深度学习技术在人脸替换领域也取得了显著的进展。通过训练深度神经网络模型,可以学习到更加丰富和精细的人脸特征表示,从而进一步提高人脸替换的效果。同时,生成对抗网络(GAN)等新型深度学习模型也为人脸替换提供了新的思路和方法。

四、应用前景

基于OpenCV的视频中人脸替换技术具有广泛的应用前景。在影视特效领域,该技术可以用于实现演员面部的替换、虚拟角色的创建等,为电影、电视剧等作品带来更加丰富和多样的视觉效果。在娱乐应用方面,人脸替换技术可以用于制作搞笑视频、虚拟形象等,为用户提供更加有趣和个性化的体验。此外,该技术还可以应用于安全监控、身份认证等领域,为社会安全和隐私保护提供技术支持。

五、结论与展望

本文综述了基于OpenCV的视频中人脸替换技术的研究背景、现状、关键技术以及应用前景。通过对相关文献和实践案例的分析和总结,可以看出该技术已经取得了一定的研究进展,并在多个领域得到了广泛的应用。然而,仍存在一些挑战和问题需要进一步研究和解决,如提高人脸替换的准确性和自然度、优化算法性能等。未来,随着计算机视觉和深度学习技术的不断发展,相信基于OpenCV的视频中人脸替换技术将会取得更加显著的进展和突破。

通过本文的综述,我们希望能够为相关研究者和实践者提供有价值的参考和借鉴,推动基于OpenCV的视频中人脸替换技术的进一步发展和应用。

六、具体实现部分

将视频中的人脸更换为指定照片中的人脸,并且输出视频。

Dlib的安装 pip install dlib==19.6.1 这种最简单

预先训练好的模型,人脸库下载-> 参考

注意文件名不要修改,尤其是PythonCv2,具体请看 -> 参考

trump.mp4为被更换的视频,大家如果改换视频的话,代码中视频名称也需要更改。
1.jpg为替换照片,注意此张照片和视频中只能有一个面部,否则会报错。
由于人脸差异的原因,结果可能不会太理想,所以尽量找肤色相同,面容相似的两个人效果会好很多

思路:
首先使用opencv将一个视频分割为帧,将每一帧保存至origin文件夹内,然后利用transfer.py将每一帧图片转换并且保存至transfer文件夹内,然后继续使用opencv将每一帧的图片在转换为视频,最终保存新视频并且删除origin和 transfer内的缓存帧图。

算法:(以transfer为主)
在transfer.py里面主要使用了dlib库去提取人脸的68个特征点,通过特征点的重叠和转换以及色彩校正实现了换脸。
这个过程主要分以下四步:
1、检测脸部标记。
2、旋转、缩放、平移和第二张图片,以配合第一步。
3、调整第二张图片的色彩平衡,以适配第一张图片。
4、把第二张图像的特性混合在第一张图像中。

1、检测脸部标记:(准备工作)
读取图片:

def read_im_and_landmarks(fname):
    im = cv2.imread(fname, cv2.IMREAD_COLOR)
    im = cv2.resize(im, (im.shape[1] * SCALE_FACTOR,
                         im.shape[0] * SCALE_FACTOR))
    s = get_landmarks(im)
    return im, s

已经训练好的模型路径:(下载路径在上文)

PREDICTOR_PATH = "shape_predictor_68_face_landmarks.dat"

人脸检测器:

detector = dlib.get_frontal_face_detector()

预测器:

predictor = dlib.shape_predictor(PREDICTOR_PATH)

预测大致人脸:
预测器需要粗略的边界框作为算法的输入,这是由检测器提供的,该检测器返回矩形列表,每个矩形对应图像中的面部,代码如下:

def get_landmarks(im):
    rects = detector(im, 1)
    if len(rects) > 1:
        raise TooManyFaces
    if len(rects) == 0:
        raise NoFaces
    return numpy.matrix([[p.x, p.y] for p in predictor(im, rects[0]).parts()])

2.用 Procrustes 分析调整脸部:
现在我们已经有了两个标记矩阵,每行有一组坐标对应一个特定的面部特征(如第30行的坐标对应于鼻头)。我们现在要解决如何旋转、翻译和缩放第一个向量,使它们尽可能适配第二个向量的点。一个想法是可以用相同的变换在第一个图像上覆盖第二个图像,其实最终是一个正交矩阵的解决办法,代码如下:(参考文档,维基百科)

def transformation_from_points(points1, points2):
    points1 = points1.astype(numpy.float64)
    points2 = points2.astype(numpy.float64)
    c1 = numpy.mean(points1, axis=0)
    c2 = numpy.mean(points2, axis=0)
    points1 -= c1
    points2 -= c2
    s1 = numpy.std(points1)
    s2 = numpy.std(points2)
    points1 /= s1
    points2 /= s2
    U, S, Vt = numpy.linalg.svd(points1.T * points2)
    R = (U * Vt).T
    return numpy.vstack([numpy.hstack(((s2 / s1) * R,
                                       c2.T - (s2 / s1) * R * c1.T)),
                         numpy.matrix([0., 0., 1.])])

代码实现了这几步:
1.将输入矩阵转换为浮点数。这是后续操作的基础。
2.每一个点集减去它的矩心。一旦为点集找到了一个最佳的缩放和旋转方法,这两个矩心 c1 和 c2 就可以用来找到完整的解决方案。
3.同样,每一个点集除以它的标准偏差。这会消除组件缩放偏差的问题。
4.使用奇异值分解计算旋转部分。可以在维基百科上看到关于解决正交 Procrustes 问题的细节。
5.利用仿射变换矩阵返回完整的转化。

3、色彩校正
两幅图像之间不同的肤色和光线造成了覆盖区域的边缘不连续,若无此步,则制作的图片色彩不均匀。
此函数试图改变 im2(第二张图) 的颜色来适配 im1。它通过用 im2 除以 im2 的高斯模糊值,然后乘以im1的高斯模糊值。代码如下:

def correct_colors(im1, im2, landmarks1,landmarks2): #修改
    blur_amount = COLOUR_CORRECT_BLUR_FRAC * numpy.linalg.norm(
        numpy.mean(landmarks1[LEFT_EYE_POINTS], axis=0) -
        numpy.mean(landmarks2[RIGHT_EYE_POINTS], axis=0))
    blur_amount = int(blur_amount)
    if blur_amount % 2 == 0:
        blur_amount += 1
    im1_blur = cv2.GaussianBlur(im1, (blur_amount, blur_amount), 0)
    im2_blur = cv2.GaussianBlur(im2, (blur_amount, blur_amount), 0)
    # Avoid divide-by-zero errors:
    im2_blur += (128 * (im2_blur <= 1.0)).astype(im2_blur.dtype)
    return (im2.astype(numpy.float64) * im1_blur.astype(numpy.float64) /
            im2_blur.astype(numpy.float64))

4、第二张图特征混合在第一张图

def get_face_mask(im, landmarks):
    im = numpy.zeros(im.shape[:2], dtype=numpy.float64)
    for group in OVERLAY_POINTS:
        draw_convex_hull(im,
                         landmarks[group],
                         color=1)
    im = numpy.array([im, im, im]).transpose((1, 2, 0))
    im = (cv2.GaussianBlur(im, (FEATURE_AMOUNT, FEATURE_AMOUNT), 0) > 0) * 1.0
    im = cv2.GaussianBlur(im, (FEATURE_AMOUNT, FEATURE_AMOUNT), 0)
    return im

get_face_mask()的定义是为一张图像和一个标记矩阵生成一个遮罩,它画出了两个白色的凸多边形:一个是眼睛周围的区域,一个是鼻子和嘴部周围的区域。之后它由11个像素向遮罩的边缘外部羽化扩展,可以帮助隐藏任何不连续的区域。最终返回优化过后的图像。

其余的py算法较为简单,主要为opencv和os的使用,在此不再赘述。
最终我是使用的main.py去循环读取图片并且将其更改,最终合并视频删除缓存,大致流程和思想就是这样了

项目内容:
在这里插入图片描述
主程序:

from transfer import *
from newvideo import mergevideo
from PythonCv2 import video2img
from deletecache import del_file

import os 

count = 1

originpath = 'origin/'
transferpath = 'transfer/'  #原始帧的路径和转换后帧的路径 一定要加 / 
videofilepath = 'trump.mp4'    #文件路径可自己定义

video2img(videofilepath,originpath)

print('视频的每一帧分离完成,开始转换')
filelist=os.listdir(originpath)
num = len(filelist)

newlist = os.listdir(originpath)

print('视频一共有:'+ str(num) + '帧')

im2, landmarks2 = read_im_and_landmarks("1.jpg")  #人物模型,将要替换到视频中的人
                                            #在同级目录下,如果更换,请定义路径
                        #写到for循环外边 减少了建立模型的时间,稍微快了那么一丢丢

for i in newlist:  #获得文件数目进行逐帧转换
    
    im1, landmarks1 = read_im_and_landmarks(originpath + i )

    M = transformation_from_points(landmarks1[ALIGN_POINTS],
                                   landmarks2[ALIGN_POINTS])

    mask = get_face_mask(im2, landmarks2)
    warped_mask = warp_im(mask, M, im1.shape)
    combined_mask = numpy.max([get_face_mask(im1, landmarks1), warped_mask],axis=0)

    warped_im2 = warp_im(im2, M, im1.shape)
    warped_corrected_im2 = correct_colors(im1, warped_im2, landmarks1,landmarks2)

    output_im = im1 * (1.0 - combined_mask) + warped_corrected_im2 * combined_mask

    cv2.imwrite(transferpath + i, output_im)

    count = count + 1
    if (count%100 ==0):
        print('已完成'+str(count)+'帧')

print('逐帧转换完成,开始合并视频:')

mergevideo(transferpath)

print('视频转换完成,请确认是否清除图片缓存')

m = input('是否删除缓存 y/n')

if (m == 'y'):
    del_file(originpath)
    del_file(transferpath)
    print('删除成功')
else:
    print('缓存未删除')

print ('Done!!!')


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白话机器学习

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值