code: def test_perspective_valid_keypoints_after_transform(
      seed: int, scale: float, h: int, w: int
  ):
      random.seed(seed)
      np.random.seed(seed)
  
      image = np.zeros([h, w, 3], dtype=np.uint8)
      keypoints = [
          [0, 0],
          [0, h - 1],
          [w - 1, h - 1],
          [w - 1, 0],
      ]
  
      transform = A.Compose(
          [A.Perspective(scale=(scale, scale), p=1)],
          keypoint_params={"format": "xy", "remove_invisible": False},
      )
  
      res = transform(image=image, keypoints=keypoints)["keypoints"]
  
      x1, y1 = res[0]
      x2, y2 = res[1]
      x3, y3 = res[2]
      x4, y4 = res[3]
  
      assert (
          x1 < x3
          and x1 < x4
          and x2 < x3
          and x2 < x4
          and y1 < y2
          and y1 < y3
          and y4 < y2
          and y4 < y3
      )
  
imports: import random
  from typing import Dict, Tuple, Type
  import cv2
  import numpy
  import pytest
  import albumentations
  from .utils import get_dual_transforms, get_image_only_transforms, get_transforms
label_desc: Use image node_id 18 for calling a global function with example usage: test_perspective_valid_keypoints_after_transform(seed, scale, h, w) without return types