code: def run(
      self,
      source_image,
      driving_video,
      ratio,
      image_size,
      output_dir,
      filename,
  ):
      self.ratio = ratio
      self.image_size = image_size
      self.output = output_dir
      self.filename = filename
      if not os.path.exists(output_dir):
          os.makedirs(output_dir)
  
      def get_prediction(face_image):
          if self.find_best_frame or self.best_frame is not None:
              i = (
                  self.best_frame
                  if self.best_frame is not None
                  else self.find_best_frame_func(
                      source_image, driving_video
                  )
              )
  
              print("Best frame: " + str(i))
              driving_forward = driving_video[i:]
              driving_backward = driving_video[: (i + 1)][::-1]
              predictions_forward = self.make_animation(
                  face_image,
                  driving_forward,
                  self.generator,
                  self.kp_detector,
                  relative=self.relative,
                  adapt_movement_scale=self.adapt_scale,
              )
              predictions_backward = self.make_animation(
                  face_image,
                  driving_backward,
                  self.generator,
                  self.kp_detector,
                  relative=self.relative,
                  adapt_movement_scale=self.adapt_scale,
              )
              predictions = (
                  predictions_backward[::-1] + predictions_forward[1:]
              )
          else:
              predictions = self.make_animation(
                  face_image,
                  driving_video,
                  self.generator,
                  self.kp_detector,
                  relative=self.relative,
                  adapt_movement_scale=self.adapt_scale,
              )
          return predictions
  
      source_image = self.read_img(source_image)
      reader = imageio.get_reader(driving_video)
      fps = reader.get_meta_data()["fps"]
      driving_video = []
      try:
          for im in reader:
              driving_video.append(im)
      except RuntimeError:
          print("Read driving video error!")
          pass
      reader.close()
  
      driving_video = [
          cv2.resize(frame, (self.image_size, self.image_size)) / 255.0
          for frame in driving_video
      ]
      results = []
  
      bboxes = self.extract_bbox(source_image.copy())
      print(str(len(bboxes)) + " persons have been detected")
  
      # for multi person
      for rec in bboxes:
          face_image = source_image.copy()[
              rec[1] : rec[3], rec[0] : rec[2]
          ]
          face_image = (
              cv2.resize(face_image, (self.image_size, self.image_size))
              / 255.0
          )
          predictions = get_prediction(face_image)
          results.append(
              {
                  "rec": rec,
                  "predict": [
                      predictions[i]
                      for i in range(predictions.shape[0])
                  ],
              }
          )
          if len(bboxes) == 1 or not self.multi_person:
              break
      out_frame = []
  
      for i in range(len(driving_video)):
          frame = source_image.copy()
          for result in results:
              x1, y1, x2, y2, _ = result["rec"]
              h = y2 - y1
              w = x2 - x1
              out = result["predict"][i]
              out = cv2.resize(out.astype(np.uint8), (x2 - x1, y2 - y1))
              if len(results) == 1:
                  frame[y1:y2, x1:x2] = out
                  break
              else:
                  patch = np.zeros(frame.shape).astype("uint8")
                  patch[y1:y2, x1:x2] = out
                  mask = np.zeros(frame.shape[:2]).astype("uint8")
                  cx = int((x1 + x2) / 2)
                  cy = int((y1 + y2) / 2)
                  cv2.circle(
                      mask,
                      (cx, cy),
                      math.ceil(h * self.ratio),
                      (255, 255, 255),
                      -1,
                      8,
                      0,
                  )
                  frame = cv2.copyTo(patch, mask, frame)
  
          out_frame.append(frame)
      imageio.mimsave(
          os.path.join(self.output, self.filename),
          [frame for frame in out_frame],
          fps=fps,
      )
  
imports: import os
  import sys
  import math
  import pickle
  import yaml
  import imageio
  import numpy
  from tqdm import tqdm
  from scipy.spatial import ConvexHull
  import cv2
  import paddle
  from ppgan.utils.download import get_path_from_url
  from ppgan.utils.animate import normalize_kp
  from ppgan.modules.keypoint_detector import KPDetector
  from ppgan.models.generators.occlusion_aware import OcclusionAwareGenerator
  from ppgan.faceutils import face_detection
label_desc: Use image node_id 3 for calling the FirstOrderPredictor obj's underlying member method code with example usage: obj.run(source_image, driving_video, ratio, image_size, output_dir, filename) and returns: predictions