code: def estimate_partial_transform(matched_keypoints):
      """Wrapper of cv2.estimateRigidTransform for convenience in vidstab process
  
      :param matched_keypoints: output of match_keypoints util function; tuple of (cur_matched_kp, prev_matched_kp)
      :return: transform as list of [dx, dy, da]
      """
      prev_matched_kp, cur_matched_kp = matched_keypoints
      transform = cv2.estimateAffinePartial2D(
          np.array(prev_matched_kp), np.array(cur_matched_kp)
      )[0]
  
      if transform is not None:
          # translation x
          dx = transform[0, 2]
          # translation y
          dy = transform[1, 2]
          # rotation
          da = np.arctan2(transform[1, 0], transform[0, 0])
      else:
          dx = dy = da = 0
  
      return [dx, dy, da]
  
file_path: PaddleHub/modules/video/Video_editing/SkyAR/utils.py
imports: import cv2
  import numpy
  from sklearn.neighbors import KernelDensity
label_desc: Use image node_id 3 for calling a global function with example usage: estimate_partial_transform(matched_keypoints) and returns: list