深度伪造技术:AI的双刃剑

深度伪造技术是当今AI领域最引人入胜且令人担忧的应用之一。虽然深度伪造可以用于合法目的,但它也可能被用于散布虚假信息。有了轻易将某人的面孔替换到任何视频中的能力,真的能相信眼睛所看到的吗?一个看似真实的视频,显示政治家或演员做了或说了令人震惊的事情,可能根本不是真的。

在本系列文章中,将展示深度伪造是如何工作的,并展示如何从头开始实现它们。然后,将看看DeepFaceLab,这是一个常用的、由Tensorflow驱动的一站式工具,用于创建令人信服的深度伪造。

在之前的文章中,讨论了很多理论,但现在是时候进入实际代码,让这个项目工作了!在本文中,将指导完成将源(src)和目标(dst)视频转换为实际图像,准备输入到自动编码器中所需的步骤。如果不熟悉这些术语,建议快速阅读之前的文章以获得一些上下文。

数据集由四个带有创意共享署名许可的视频组成,因此可以重用或修改它们。这个数据集包含两个源个体的视频和两个目标个体的视频。可以在这里找到数据集。将要解释的笔记本在这里。在Kaggle笔记本上进行了这个阶段的预处理,但如果有一个强大的GPU,可以很容易地在本地运行项目。让深入代码!

在笔记本上设置基础

让从导入所需的库和创建将要使用的目录开始:

import cv2 import pandas as pd import os import matplotlib.pyplot as plt import matplotlib.image as mpimg !pip install mtcnn from mtcnn import MTCNN !cd /kaggle/working/ !mkdir frames_1 !mkdir frames_2 !mkdir frames_3 !mkdir frames_4 !mkdir results_1 !mkdir results_2

提取视频帧

正如在第一篇文章中可能记得的,提到需要将视频转换为图像,这样就可以提取个体帧中的面部,最后用它们来训练模型。在这一步中,将使用OpenCV,这是一个在这类任务中广泛使用的计算机视觉库,来提取组成视频的图像。让开始实践:

定义视频所在的位置以及输出将被保存的位置(如果需要,请修改它们):

input_1 = '/kaggle/input/presidentsdataset/presidents/trump1.mp4' input_2 = '/kaggle/input/presidentsdataset/presidents/trump2.mp4' input_3 = '/kaggle/input/presidentsdataset/presidents/biden1.mp4' input_4 = '/kaggle/input/presidentsdataset/presidents/biden2.mp4' output_1 = '/kaggle/working/frames_1/' output_2 = '/kaggle/working/frames_2/' output_3 = '/kaggle/working/frames_3/' output_4 = '/kaggle/working/frames_4/'

定义将用于提取帧的函数:

def extract_frames(input_path, output_path): videocapture = cv2.VideoCapture(input_path) success, image = videocapture.read() count = 0 while success: cv2.imwrite(output_path + "frame%d.jpg" % count, image) success, image = videocapture.read() count += 1 return count

提取帧:

total_frames_1 = extract_frames(input_1, output_1) total_frames_2 = extract_frames(input_2, output_2) total_frames_3 = extract_frames(input_3, output_3) total_frames_4 = extract_frames(input_4, output_4)

确定每个视频提取了多少帧:

print('Total frames extracted in video 1:', total_frames_1) print('Total frames extracted in video 2:', total_frames_2) print('Total frames extracted in video 3:', total_frames_3) print('Total frames extracted in video 4:', total_frames_4)

最后的输出意味着为源个体有1701和1875帧,第二个个体有1109和1530帧。这是一个很好的图像数量,可以训练模型。如果想绘制src个体的一帧,只需运行:

%matplotlib inline plt.figure() image = cv2.imread('/kaggle/working/frames_1/frame1.jpg') image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) image = image.astype('float32') image /= 255.0 plt.imshow(image) plt.show()

它将显示这个:

绘制目标个体的一帧:

%matplotlib inline plt.figure() image = cv2.imread('/kaggle/working/frames_3/frame1.jpg') image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) plt.imshow(image) plt.show()

现在已经获得了所有的帧,是时候从中提取面部了。为此,首先检测面部的位置,然后裁剪它以保存为新文件。将使用MTCNN检测器,这是一个专门为面部检测开发的Python库。

使用他们的一个示例,这是它的面部检测看起来的样子:

将使用他们的脚本作为基础代码,从帧中提取面部,但正如看到的,检测器并不考虑整个面部。下颌、部分前额和颧骨没有包括在内,所以将采取MTCNN检测,并添加一些额外的填充,以在裁剪之前得到整个面部在一个正方形中,然后生成一个新的图像。运行以下行:

def extract_faces(source_1, source_2, destination, detector): counter = 0 for dirname, _, filenames in os.walk(source_1): for filename in filenames: try: image = cv2.imread(os.path.join(dirname, filename)) image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) detections = detector.detect_faces(image) x, y, width, height = detections[0]['box'] x1, y1, x2, y2 = x-10, y+10, x-10+width+20, y+10+height face = image[y1:y2, x1:x2] face = cv2.resize(face, (120, 120), interpolation=cv2.INTER_LINEAR) plt.imsave(os.path.join(destination, str(counter)+'.jpg'), face) print('Saved:', os.path.join(destination, str(counter)+'.jpg')) except: pass counter += 1 for dirname, _, filenames in os.walk(source_2): for filename in filenames: try: image = cv2.imread(os.path.join(dirname, filename)) image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) detections = detector.detect_faces(image) x, y, width, height = detections[0]['box'] x1, y1, x2, y2 = x-10, y+10, x-10+width+20, y+10+height face = image[y1:y2, x1:x2] face = cv2.resize(face, (120, 120), interpolation=cv2.INTER_LINEAR) plt.imsave(os.path.join(destination, str(counter)+'.jpg'), face) print('Saved:', os.path.join(destination, str(counter)+'.jpg')) except: pass counter += 1 detector = MTCNN() extract_faces('/kaggle/working/frames_1/', '/kaggle/working/frames_2/', '/kaggle/working/results_1/', detector) extract_faces('/kaggle/working/frames_3/', '/kaggle/working/frames_4/', '/kaggle/working/results_2/', detector)

Python Saved: /kaggle/working/results_1/0.jpg Saved: /kaggle/working/results_1/1.jpg Saved: /kaggle/working/results_1/2.jpg Saved: /kaggle/working/results_1/3.jpg Saved: /kaggle/working/results_1/4.jpg ...

最终结果应该是在results_1和results_2中保存了几张面部图像,每个文件夹包含相应个体的面部。可能已经注意到将所有面部调整为120x120的尺寸。这是为了避免在构建模型和定义输入形状时发生任何冲突。

要绘制一张面部并给一个它被提取后的样子的想法,运行以下命令:

%matplotlib inline plt.figure() image = cv2.imread('/kaggle/working/results_1/700.jpg') image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) plt.imshow(image) plt.show()

它将绘制这个:

注意图像显示了个体面部的更广泛范围。这将对以后交换面部非常有帮助,但它也将帮助达到模型训练中更低的错误。如果像一样在Kaggle笔记本中遵循这些步骤,发出以下命令,然后更容易地下载文件:

!zip -r /kaggle/working/trump_faces.zip /kaggle/working/results_1/ !zip -r /kaggle/working/biden_faces.zip /kaggle/working/results_2/
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485