- 可以对前景进行缩放
- 可以对前景进行平移
- import cv2
- import numpy as np
-
-
- def adjust_img(img, position_params, size_rate):
- """调整图像
- 必须先缩小-再平移
- :param img:
- :param position_params:
- :param size_rate:
- :return:
- """
- h, w = img.shape[:2]
-
- # 进行缩放
- new_size = [int(size_rate * h), int(size_rate * w)]
- img = cv2.resize(img, (new_size[1], new_size[0]))
- if w >= new_size[1]:
- pad_w = w - new_size[1]
- pad_h = h - new_size[0]
- top, bottom = pad_h // 2, pad_h - (pad_h // 2)
- left, right = pad_w // 2, pad_w - (pad_w // 2)
- img = cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_CONSTANT,
- None,
- (0, 0, 0))
- else:
- crop_w = (new_size[1] - w) // 2
- crop_h = (new_size[0] - h) // 2
-
- img = img[crop_h:crop_h + h, crop_w:crop_w + w]
-
- # 进行平移
- MAT = np.float32(
- [[1, 0, int(w * position_params[1])], [0, 1, int(h * position_params[0])]]) # 构造平移变换矩阵
- img = cv2.warpAffine(img, MAT, (w, h), borderValue=(0, 0, 0)) # 设置白色填充
-
- return img
-
-
- def video_compositing(video_root, mask_root, output_path, background_root, position_params,
- size_rate):
- """
- :param video_root:
- :param mask_root: mask path
- :param output_path: 输出位置
- :param background_root: 背景图像path
- :param position_params: [0.5, 0.5], [垂直,水平]控制人像在图像中的位置, 计算例如:水平移动像素数/水平像素总数
- :param size_rate: 控制缩放大小,1:原始大小
- :return:
- """
-
- video = cv2.VideoCapture(video_root)
- mask = cv2.VideoCapture(mask_root)
-
- if not video.isOpened():
- print(f"Failed to open video file: {video_root}")
- return
-
- if not mask.isOpened():
- print(f"Failed to open mask file: {mask_root}")
- return
-
- rval, frame = video.read()
- rval_mask, frame_mask = mask.read()
-
- fps = video.get(cv2.CAP_PROP_FPS)
- h, w = frame.shape[:2]
-
- fourcc = cv2.VideoWriter_fourcc(*'mp4v')
- video_writer = cv2.VideoWriter(output_path, fourcc, fps, (w, h))
- num_frame = video.get(cv2.CAP_PROP_FRAME_COUNT)
-
- # 是否加背景
- if background_root:
- background = cv2.imread(background_root)
- background = cv2.resize(background, (w, h))
- else:
- background = None
-
- for c in range(int(num_frame)):
- if (frame is None) or (frame_mask is None):
- continue
-
- # 计算前景
- foreground = frame * (frame_mask / 255)
- foreground = adjust_img(foreground, position_params, size_rate)
-
- # 是否加背景
- if background_root:
- frame_mask = adjust_img(frame_mask, position_params, size_rate)
- fg_com = foreground + background * (1 - frame_mask / 255)
- else:
- fg_com = foreground
-
- video_writer.write(fg_com.astype(np.uint8))
- rval, frame = video.read()
- rval_mask, frame_mask = mask.read()
-
- video_writer.release()
- video_compositing(
- 'data/video.mp4',
- 'data/mask.mp4',
- 'data/results.mp4',
- 'data/img.jpg',
- position_params=[0., 0.3], # 垂直,水平
- size_rate=1.8
- )