show_cut.py 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. import os
  2. import numpy as np
  3. from concurrent.futures import ThreadPoolExecutor
  4. from .depth_img import depth_image_list
  5. from .rmbg import mask_image_list
  6. from .mask_depth import depth_apply_mask_pilimg_list
  7. from .read_folder import read_images_in_order
  8. from .frame_extract import frame_extractor
  9. from modules.video_processing.image_qa_doubao import show_detect_doubao
  10. from .common import filter_json_files_for_show, find_show_cut
  11. from modules.video_processing.video_cut import moviepy_cut
  12. from .add_music import add_music_to_video
  13. from .aide_cut import aide_cut
  14. from .path_config import PathConfig
  15. path_config = PathConfig()
  16. from .logger_config import setup_logger
  17. logger = setup_logger(__name__)
  18. def depth_for_cut(image_list):
  19. """
  20. 定位走秀视频片段
  21. Args:
  22. image_list (list): 抽帧原图像列表
  23. Returns:
  24. masked_images: 深度图掩码图像列表
  25. depth_means: 深度图深度均值列表
  26. """
  27. depths = depth_image_list(image_list)
  28. masks = mask_image_list(image_list)
  29. masked_depths, depth_means = depth_apply_mask_pilimg_list(depths, masks, image_list)
  30. return masked_depths, depth_means
  31. def show_cut(audio_json):
  32. # 0、裁切助播讲品视频片
  33. video_path = aide_cut(audio_json)
  34. # 1、抽帧保存:每隔60秒抽一帧
  35. frame_extractor(video_path, interval_sec=3, output_dir=path_config.get_path('frame_for_show'))
  36. logger.info("抽帧:done!")
  37. # 2、单帧理解:图像是否有人,多少个人,在图像中的位置
  38. images = read_images_in_order(path_config.get_path('frame_for_show'))
  39. show_detect_doubao(images)
  40. logger.info("帧理解:done!!!")
  41. # 3、筛选:找到一个人站在画面中央的图像
  42. filter_images = filter_json_files_for_show(str(path_config.get_path('caption_for_show')))
  43. # files = read_images_in_order("./data/key_frame/for_show/")
  44. # filter_images = files
  45. logger.info("查找人站中央:done!")
  46. print(f"{filter_images}")
  47. # 4、计算筛选图像的深度均值
  48. masked_depths, depth_means = depth_for_cut(filter_images)
  49. logger.info("计算深度均值")
  50. # 5、基于深度均值查找裁切图像索引
  51. logger.info(f"深度图差值阈值:{int(np.mean(depth_means) / 8)}")
  52. cut_index = find_show_cut(depth_means, n = int(np.mean(depth_means) / 8))
  53. # 6、计算裁切时间戳
  54. cut_start = int(filter_images[cut_index[0]].split('_')[-1].split('.')[0])
  55. cut_end = int(filter_images[cut_index[1]].split('_')[-1].split('.')[0])
  56. logger.info(f"定位走秀时间戳:{cut_start} - {cut_end}")
  57. # 7、裁切出走秀片段
  58. output_path = f"output/video_clips/show-{os.path.splitext(os.path.basename(video_path))[0]}.mp4"
  59. moviepy_cut(video_path, output_path, cut_start, cut_end)
  60. logger.info(f"裁切走秀片段:{output_path}")
  61. # 8、添加背景音乐
  62. music_video = output_path.replace("show", "music-show")
  63. add_music_to_video(output_path, "data/music_file/music.mp3", fadein_duration=1, fadeout_duration=1, output_path=music_video)
  64. logger.info(f"添加背景音乐:{music_video}")
  65. return music_video
  66. if __name__ == "__main__":
  67. show_cut("data/sub_video/clip.mp4")
  68. # TODO:是否手拿衣服,是否手拿平板?