前言:
如今咱们对“python中imageshape”大致比较注重,姐妹们都需要知道一些“python中imageshape”的相关资讯。那么小编在网摘上收集了一些有关“python中imageshape””的相关内容,希望同学们能喜欢,兄弟们快快来学习一下吧!前言
当下,视频内容火爆,带有争议性或反差大的换脸视频总能吸引人视线。虽然AI换脸在市面上已经流行了许久,相关制作工具或移动应用也是数不胜数。但是多数制作工具多数情况下不是会员就是收费,而且替换模板有限。以下在实战的角度,用ModelScope的图像人脸融合实现一下AI视频换脸。
流程
提供一段视频和一张替换的人脸图片,用opencv-python将视频根据帧率拆成图片,用FFmpeg提取视频里的音频为单独文件(mp3)。遍历目录下的每一帧的图片,通过ModelScope的人脸融合模型,传入新的人脸和帧率图片,得到替换过人脸的帧图片。最后再通过opencv-python将替换的人脸图片组合成新视频,FFmpeg添加提取出的音频文件。
环境
1. Python 3.7.16
2. ModelScope 1.4.2
3. OpenCV-Python 4.7.0
4. FFmpeg 12.2.0
环境安装
1. Python虚拟环境添加
conda create -n modelscope python=3.7 && conda activate modelscope
2. 安装ModelScope,使用了国内镜像源
pip install modelscope --upgrade -i
3. 安装OpenCV
pip install opencv-python -i
4. 安装FFmpeg
因为单是图片用不上,所以安装方法放在下面视频换脸里
图片换脸
1. 素材准备
我这里分别准备了一个画面里出现正脸,侧脸和两张脸的图片,然后分别用一张图片替换,最后运行代码查看效果。(可能是模型原因,感觉光看图片的换脸好像相差不大,倒有点像只是开了个美颜,也有可能是俩演员有点像,认真看还有有点不同)。
2. 代码部分
import cv2from modelscope.outputs import OutputKeysfrom modelscope.pipelines import pipelinefrom modelscope.utils.constant import Tasksimage_face_fusion = pipeline(Tasks.image_face_fusion, model='damo/cv_unet-image-face-fusion_damo')template_path = '181.jpg'user_path = 'face.jpg'result = image_face_fusion(dict(template=template_path, user=user_path))cv2.imwrite('result.png', result[OutputKeys.OUTPUT_IMG])print('finished!')
视频换脸
1. FFmpeg安装
如果是windows10可以按我下面的选择,shared是动态版本,不带的是静态版本,所有的功能都集合在一起。
2. FFmpeg环境配置
下载后解压会生成一下目录,将bin文件放入电脑环境变量中,然后通过ffmpeg -version查看是否安装成功。
3. FFmpeg用法
3.1. 从视频中抽取音频 (输入视频和输出音频的地址可以是相对路径)
ffmpeg -i videos\11.mp4 -q:a 0 -map a audio\audio.mp3
3.2. 将独立音频文件添加到视频里(接收输入视频,输入音频,输出新视频)
ffmpeg -i videos/ldh.mp4 -i audio/audio.mp3 -c:v copy -c:a aac -strict experimental videos/new_ldh.mp4
4. 开始编码
from pathlib import Pathimport cv2import osdef video2mp3_img(video_path, save_path): def video_split(video_path, save_path): if not os.path.exists(save_path): os.makedirs(save_path) cap = cv2.VideoCapture(video_path) i = 0 while True: ret, frame = cap.read() if ret: cv2.imwrite(save_path + '/' + str(i) + '.jpg', frame) i += 1 else: break cap.release() if not os.path.exists(save_path): os.makedirs(save_path) # 视频分割 video_split(video_path, save_path) # 视频转音频 os.system("ffmpeg -i {} -q:a 0 -map a {}/audio.mp3".format(video_path, save_path))def face_replace(user_path=""): from pathlib import Path import cv2 from modelscope.outputs import OutputKeys from modelscope.pipelines import pipeline from modelscope.utils.constant import Tasks import os os.environ['KMP_DUPLICATE_LIB_OK'] = 'True' def my_function(img_path): image_face_fusion = pipeline(Tasks.image_face_fusion, model='damo/cv_unet-image-face-fusion_damo') template_path = img_path filename = os.path.splitext(os.path.basename(img_path))[0] # 替换面部依赖 result = image_face_fusion(dict(template=template_path, user=user_path)) cv2.imwrite(f'video_imgout/{filename}.jpg', result[OutputKeys.OUTPUT_IMG]) threads = [] BASE_PATH = os.path.dirname(__file__) for dirpath, dirnames, filenames in os.walk(r"D:\3code\3Python\modelscope\mv_face_change-main"): for filename in filenames: print(filename) if filename.endswith('.jpg'): file_path = Path(os.path.join(dirpath, filename)) print(file_path) my_function(str(file_path))def img2mp4(video_path, save_name): BASE_PATH = "D:\3code\3Python\modelscope\mv_face_change-main" img = cv2.imread("video_img/0.jpg") imgInfo = img.shape size = (imgInfo[1], imgInfo[0]) files = [] for dirpath, dirnames, filenames in os.walk(r"D:\3code\3Python\modelscope\mv_face_change-main\video_imgout"): for filename in filenames: fileName = Path(os.path.join(dirpath, filename)) files.append(os.path.join(dirpath, filename)) files = [file.replace('\\', '/') for file in files] files.sort(key=lambda x: int(x.split('/')[-1].split('.')[0])) fourcc = cv2.VideoWriter_fourcc(*'mp4v') videoWrite = cv2.VideoWriter(r"D:\3code\3Python\modelscope\mv_face_change-main\videos\ldh.mp4", fourcc, 25, size) # 写入对象 1 file name 3: 视频帧率 for i in files: print(i) img = cv2.imread(str(i)) videoWrite.write(img) # 将video_img中的音频文件添加到视频中 os.system("ffmpeg -i {} -i {} -c:v copy -c:a aac -strict experimental {}".format("videos/ldh.mp4", "audio/audio.mp3", "videos/newlest_ldh.mp4"))if __name__ == '__main__': BASE = os.path.dirname(__file__) video_path = os.path.join(BASE, "videos/demo.mp4") save_path = os.path.join(BASE, "video_img") # 视频 ==> imgs video2mp3_img(video_path, save_path) # 人脸替换 face_replace(user_path='zsy.jpg') # imgs ==> 视频 img2mp4(video_path, save_name='zsy')
5. 报错汇总
当运行上面代码,如果出现Output file does not contain any stream,那就是分离音频或追加音频到视频的这两个地方报的错误,大部分情况下输出路径不正确或命令参数不对。还有一个错误我没有记录,就是让视频压根没有声音,再执行分离操作时也会报错。这个是我上班时随便拿的视频测试(因为不能戴耳机,刚好视频就是没声音的),所以使劲测使劲报错,换了视频就好了,关键是错误提示也没说是视频没声音。
6. 效果演示
由于时间原因,没有用杨过的视频,就用没有声音的视频做了换脸演示。以后还要对换脸图片替换做多线程处理。
标签: #python中imageshape