Guest User

Untitled

a guest
Apr 24th, 2018
111
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.94 KB | None | 0 0
  1. from __future__ import absolute_import
  2. from __future__ import division
  3. from __future__ import print_function
  4. from __future__ import unicode_literals
  5.  
  6. import os
  7. import sys
  8. import argparse
  9. import json
  10. import subprocess
  11. import logging
  12. import numpy as np
  13. import matplotlib.image as mpimg
  14. from functools import partial
  15. from multiprocessing.pool import ThreadPool
  16.  
  17. from video_process_lib.ffmpeg import copy_ffmpeg_bin
  18.  
  19.  
  20. FORMAT = '[%(levelname)s: %(filename)s: %(lineno)4d]: %(message)s'
  21. logging.basicConfig(level=logging.INFO, format=FORMAT, stream=sys.stdout)
  22. logger = logging.getLogger(__name__)
  23. logger.setLevel(logging.INFO)
  24.  
  25.  
  26. def process_video(v_data, input_video_dir, output_video_dir):
  27. cwd = '/tmp'
  28. fps = 25
  29. border_thickness = 0.03
  30. youtubeID = v_data[0]
  31. video_fn = os.path.join(input_video_dir, youtubeID + '.mp4')
  32. FFPROBE_BIN = '{}/ffmpeg/ffmpeg-2.6.1/bin/ffprobe'.format(cwd)
  33. cmd = '{} -v quiet -print_format json -show_format -show_streams {}'.format(
  34. FFPROBE_BIN, video_fn
  35. )
  36. logger.info('ffprobe cmd: {}'.format(cmd))
  37. split_cmd = cmd.split(' ')
  38.  
  39. height, width = 0, 0
  40. try:
  41. video_info = json.loads(subprocess.check_output(split_cmd))
  42. for stream in video_info['streams']:
  43. if 'height' in stream and 'width' in stream:
  44. height = stream['height']
  45. width = stream['width']
  46. logger.info(
  47. '{} | Get video height/width: {}/{}'.format(
  48. video_fn, height, width)
  49. )
  50. break
  51. except BaseException as e:
  52. logger.warning(
  53. '{} | Fail to get height and width. Error: {}'.format(video_fn, e))
  54. return
  55. # decode video into images
  56. FFMPEG_BIN = '{}/ffmpeg/ffmpeg-2.6.1/bin/ffmpeg'.format(cwd)
  57. cmd = '{} -i {} -r {} /tmp/{}_%05d.png'.format(
  58. FFMPEG_BIN, video_fn, fps, youtubeID
  59. )
  60. logger.info('frame extraction cmd: {}'.format(cmd))
  61. ret_val = subprocess.call(cmd, shell=True)
  62. if ret_val == 0:
  63. print('video succeed: {}'.format(video_fn))
  64. else:
  65. print('video fails: {}'.format(video_fn))
  66.  
  67. if len(v_data[1]["annotation"]) == 0:
  68. logger.info("Completely negative video: {}. Return !".format(video_fn))
  69. return
  70.  
  71. # modify those images with ongoing actions so that border top border color is
  72. green = np.asarray([0., 1., 0.])
  73. for seg in v_data[1]["annotation"]:
  74. start, end = seg[0], seg[1]
  75. start_img = int(round(start * fps)) + 1
  76. end_img = int(round(end * fps)) + 1
  77. for img_id in range(start_img, end_img + 1):
  78. img_fn = "/tmp/{}_{:05d}.png".format(youtubeID, img_id)
  79. if os.path.exists(img_fn):
  80. im = mpimg.imread(img_fn)
  81. logger.info("img: {} shape: {}".format(img_fn, im.shape))
  82. height, width = im.shape[0], im.shape[1]
  83.  
  84. border_height_pix = int(round(border_thickness * height))
  85. border_width_pix = int(round(border_thickness * width))
  86.  
  87. green_border = np.tile(green, [border_height_pix, width, 1])
  88. im[:border_height_pix, :, :] = green_border
  89. im[-border_height_pix:, :, :] = green_border
  90.  
  91. green_border = np.tile(green, [height, border_width_pix, 1])
  92. im[:, :border_width_pix, :] = green_border
  93. im[:, -border_width_pix:, :] = green_border
  94.  
  95. logger.info("Modify {}".format(img_fn))
  96. mpimg.imsave(img_fn, im)
  97.  
  98. # assemble images into video and save it
  99. v_height = (height // 2) * 2
  100. v_width = (width // 2) * 2
  101. out_fn = os.path.join(output_video_dir, '{}.mp4'.format(youtubeID))
  102. cmd = '{} -framerate {} -i /tmp/{}_%05d.png -vcodec libx264 -pix_fmt yuv420p -s {}x{} {}'.format(
  103. FFMPEG_BIN, fps, youtubeID, v_width, v_height, out_fn
  104. )
  105. logger.info('video assembling cmd: {}'.format(cmd))
  106. ret_val = subprocess.call(cmd, shell=True)
  107. if ret_val == 0:
  108. print('video assembling succeed: {}'.format(out_fn))
  109. else:
  110. print('video assembling fails: {}'.format(out_fn))
  111.  
  112. # remove frame images
  113. cmd = "rm -f /tmp/{}*.png".format(youtubeID)
  114. ret_val = subprocess.call(cmd, shell=True)
  115.  
  116.  
  117. if __name__ == "__main__":
  118. parser = argparse.ArgumentParser()
  119. parser.add_argument('--input_video_dir',
  120. default='/mnt/vol/gfsai-oregon/ai-group/users/hangzhao'
  121. '/hac650k_export0828_val_videos')
  122. parser.add_argument('--input_annotation',
  123. default='/mnt/vol/gfsai-oregon/ai-group/users/hangzhao'
  124. '/annotation/full_annotation/full_annotation_v1_val.json')
  125. parser.add_argument('--output_video_dir',
  126. default='/mnt/vol/gfsai-oregon/ai-group/users/hangzhao'
  127. '/annotation/full_annotation/vis')
  128. parser.add_argument('--num_worker', default=36, type=int)
  129. parser.add_argument('--shard_id', default=0, type=int)
  130. parser.add_argument('--num_shard', default=2000, type=int)
  131.  
  132. args = parser.parse_args()
  133.  
  134. logger.info("Extract video meta info")
  135. copy_ffmpeg_bin(
  136. '/mnt/vol/gfsai-oregon/ai-group/users/hangzhao/ffmpeg.tar.gz')
  137.  
  138. with open(args.input_annotation) as fp:
  139. anno = json.load(fp)
  140. logger.info("{} videos".format(len(anno.keys())))
  141.  
  142. if not os.path.exists(args.output_video_dir):
  143. os.mkdir(args.output_video_dir)
  144. os.chmod(args.output_video_dir, 0o777)
  145.  
  146. list_anno = list(anno.items())[:5]
  147.  
  148. list_anno = []
  149. for item in list(anno.items()):
  150. if hash(item[0]) % args.num_shard == args.shard_id:
  151. list_anno.append(item)
  152. logger.info("{} videos in shard {}/{}".format(
  153. len(list_anno), args.shard_id, args.num_shard))
  154.  
  155. pool = ThreadPool(args.num_worker)
  156. handles = pool.map(
  157. partial(
  158. process_video,
  159. input_video_dir=args.input_video_dir,
  160. output_video_dir=args.output_video_dir,
  161. ),
  162. list_anno)
Add Comment
Please, Sign In to add comment