• [python opencv video抠图并更换背景]


     完整实现

    - 可以对前景进行缩放

    - 可以对前景进行平移

    1. import cv2
    2. import numpy as np
    3. def adjust_img(img, position_params, size_rate):
    4. """调整图像
    5. 必须先缩小-再平移
    6. :param img:
    7. :param position_params:
    8. :param size_rate:
    9. :return:
    10. """
    11. h, w = img.shape[:2]
    12. # 进行缩放
    13. new_size = [int(size_rate * h), int(size_rate * w)]
    14. img = cv2.resize(img, (new_size[1], new_size[0]))
    15. if w >= new_size[1]:
    16. pad_w = w - new_size[1]
    17. pad_h = h - new_size[0]
    18. top, bottom = pad_h // 2, pad_h - (pad_h // 2)
    19. left, right = pad_w // 2, pad_w - (pad_w // 2)
    20. img = cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_CONSTANT,
    21. None,
    22. (0, 0, 0))
    23. else:
    24. crop_w = (new_size[1] - w) // 2
    25. crop_h = (new_size[0] - h) // 2
    26. img = img[crop_h:crop_h + h, crop_w:crop_w + w]
    27. # 进行平移
    28. MAT = np.float32(
    29. [[1, 0, int(w * position_params[1])], [0, 1, int(h * position_params[0])]]) # 构造平移变换矩阵
    30. img = cv2.warpAffine(img, MAT, (w, h), borderValue=(0, 0, 0)) # 设置白色填充
    31. return img
    32. def video_compositing(video_root, mask_root, output_path, background_root, position_params,
    33. size_rate):
    34. """
    35. :param video_root:
    36. :param mask_root: mask path
    37. :param output_path: 输出位置
    38. :param background_root: 背景图像path
    39. :param position_params: [0.5, 0.5], [垂直,水平]控制人像在图像中的位置, 计算例如:水平移动像素数/水平像素总数
    40. :param size_rate: 控制缩放大小,1:原始大小
    41. :return:
    42. """
    43. video = cv2.VideoCapture(video_root)
    44. mask = cv2.VideoCapture(mask_root)
    45. if not video.isOpened():
    46. print(f"Failed to open video file: {video_root}")
    47. return
    48. if not mask.isOpened():
    49. print(f"Failed to open mask file: {mask_root}")
    50. return
    51. rval, frame = video.read()
    52. rval_mask, frame_mask = mask.read()
    53. fps = video.get(cv2.CAP_PROP_FPS)
    54. h, w = frame.shape[:2]
    55. fourcc = cv2.VideoWriter_fourcc(*'mp4v')
    56. video_writer = cv2.VideoWriter(output_path, fourcc, fps, (w, h))
    57. num_frame = video.get(cv2.CAP_PROP_FRAME_COUNT)
    58. # 是否加背景
    59. if background_root:
    60. background = cv2.imread(background_root)
    61. background = cv2.resize(background, (w, h))
    62. else:
    63. background = None
    64. for c in range(int(num_frame)):
    65. if (frame is None) or (frame_mask is None):
    66. continue
    67. # 计算前景
    68. foreground = frame * (frame_mask / 255)
    69. foreground = adjust_img(foreground, position_params, size_rate)
    70. # 是否加背景
    71. if background_root:
    72. frame_mask = adjust_img(frame_mask, position_params, size_rate)
    73. fg_com = foreground + background * (1 - frame_mask / 255)
    74. else:
    75. fg_com = foreground
    76. video_writer.write(fg_com.astype(np.uint8))
    77. rval, frame = video.read()
    78. rval_mask, frame_mask = mask.read()
    79. video_writer.release()

     运行测试

    1. video_compositing(
    2. 'data/video.mp4',
    3. 'data/mask.mp4',
    4. 'data/results.mp4',
    5. 'data/img.jpg',
    6. position_params=[0., 0.3], # 垂直,水平
    7. size_rate=1.8
    8. )

  • 相关阅读:
    OpenMLDB Airflow Connector:让 MLOps 工作流更自由
    轻量封装WebGPU渲染系统示例<22>- 渲染到纹理(RTT)(源码)
    spring boot 之 整合 knife4j 在线接口文档
    R语言ggplot2可视化分面图(facet):gganimate包基于transition_time函数创建动态散点图动画(gif)
    蛇岛狂蟒出没
    从SQL SERVER、MYSQL到ORACLE
    c++图解内存管理
    花椰菜的 8 大健康益处,为你一一盘点
    深度学习-第三章概率与信息论
    如何让 Go 反射变快,你学会了吗?
  • 原文地址:https://blog.csdn.net/qq_39749966/article/details/133052101