对图像处理一窍不通的我,竟然开始搞图像了!!!!话不多说,直接开干!
1、首先对视频逐帧读取图片
2、对读取的图片进行抠图
3、生成mask
4、读取mask、抠图、背景图片进行融合
5、将替换背景后的图片写入视频
代码完成:
1、逐帧读取图片函数
(1)计算视频的总帧数total_frames
(2)通过帧数截取视频图片
(3)使用cv2.imwrite()将帧数对应的图像写入文件夹
def make_frame_img(video_path, output_path):
"""
从视频文件中抽取帧数图片,保存到指定路径
参数:
video_path: 输入视频路径
output_path: 保存帧图片文件夹
return 无
"""
# 读取视频文件
cap = cv2.VideoCapture(video_path)
# 检查视频是否成功打开
if not cap.isOpened():
print("无法打开视频文件:", video_path)
return
# 获取视频帧率和总帧数
fps = cap.get(cv2.CAP_PROP_FPS)
total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
# 如果没有创建输出文件夹,则创建输出文件夹
if not os.path.exists(output_path):
os.makedirs(output_path)
# 分割视频为照片
for i in tqdm(range(total_frames)):
ret, frame = cap.read()
if ret:
# 保存照片
filename = f'frame_%04d.jpg' % i
filepath = os.path.join(output_path, filename)
cv2.imwrite(filepath, frame)
else:
break
2、对图片进行抠图,使用了P3M-Net算法实现对图像的抠图(GitHub - ViTAE-Transformer/P3M-Net: The official repo for [IJCV'23] "Rethinking Portrait Matting with Privacy Preserving"
或者是使用PIL中的Image:
from PIL import Image
from rembg import remove
import cv2
save_path = './image_save_path/' # 图像输出路径
# 先打开要抠图的图片
img = Image.open('./usings_img.jpg)
# 处理
img = remove(img)
# 保存
img = cv2.cvtColor(np.array(img), cv2.COLOR_RGBA2BGR)
cv2.imwrite(save_path , img)
3、4、对图像读取背景图像、创建mask
(1)mask的获取:由于P3M net生成的抠图已经完备,可以直接将foreground_img3个通道的sum>0作为mask,此时mask变为2维,再给mask增加第三维度,即通道数。
(2)背景图像与抠图融合:融合图像= 抠图*mask + 背景图*(1-mask)
(3)将获取的融合图像写入文件。
def change_background(foreground_path, background_path, output_path):
"""
将扣图与背景图片结合,得到新图片
参数:
foreground_path 抠图路径
background_path 背景图路径
output_path 输出路径
返回值:无
"""
image_files = [f for f in os.listdir(foreground_path) if f.endswith('.png')]
image_files.sort()
for i in tqdm(image_files):
foreground_img = cv2.imread(os.path.join(foreground_path, i))
background_img = cv2.imread(background_path)
background_img = cv2.resize(background_img, (720,1280))
mask = np.sum(foreground_img.astype("int64"), axis=-1) > 0
mask = np.tile(mask[:, :, None], (1, 1, 3))
filepath = os.path.join(output_path, f'new_{i}')
result = foreground_img *mask + background_img *(1-mask)
cv2.imwrite(filepath, result)
5、图象生成视频
cv2.imread()获取替换背景后的图象,cv2.imwrite()写入视频
def merge_to_video(img_path, output_video_path):
"""
将图片合成视频
参数:
img_path 输入图片路径
output_video_path 输出视频路径
return 无
"""
# 传入输入路径中的所有图像
image_files = [f for f in os.listdir(img_path) if f.endswith(".png")]
image_files.sort()
# 获取图像尺寸
img = cv2.imread(os.path.join(img_path, image_files[0]))
height, width, _ = img.shape
# 创建用于写入视频的VideoWriter对象
video_writer = cv2.VideoWriter(output_video_path, cv2.VideoWriter_fourcc(*"mp4v"), 30, (width, height))
# 逐个读取图像并将其写入视频
for image_file in tqdm(image_files):
img = cv2.imread(os.path.join(img_path, image_file))
video_writer.write(img)
video_writer.release()
文章评论