class_docstr: Implementation of the adversarial texture attack on object trackers in PyTorch.
  
  | Paper link: https://arxiv.org/abs/1904.11042
class_docstr_tok: ["Implementation","of","the","adversarial","texture","attack","on","object","trackers","in","PyTorch",".","|","Paper","link",":","https",":","\/\/arxiv.org\/abs\/1904.11042"]
docstr: Apply texture over background and overlay foreground.
  
  :param videos: Video samples.
  :param patch: Patch to apply.
  :param foreground: Foreground mask.
  :param patch_points: Array of shape (nb_frames, 4, 2) containing four pairs of integers (height, width)
                       corresponding to the coordinates of the four corners top-left, top-right, bottom-right,
                       bottom-left of the transformed image in the coordinate-system of the original image.
  :return: Patched videos.
docstr_tok: ["Apply","texture","over","background","and","overlay","foreground",".",":","param","videos",":","Video","samples",".",":","param","patch",":","Patch","to","apply",".",":","param","foreground",":","Foreground","mask",".",":","param","patch_points",":","Array","of","shape","(","nb_frames",",","4",",","2",")","containing","four","pairs","of","integers","(","height",",","width",")","corresponding","to","the","coordinates","of","the","four","corners","top-left",",","top-right",",","bottom-right",",","bottom-left","of","the","transformed","image","in","the","coordinate-system","of","the","original","image",".",":","return",":","Patched","videos","."]
code: def _apply_texture(
      self,
      videos: "torch.Tensor",
      patch: "torch.Tensor",
      foreground: Optional["torch.Tensor"],
      patch_points: Optional[np.ndarray],
  ) -> "torch.Tensor":
      """
      Apply texture over background and overlay foreground.
  
      :param videos: Video samples.
      :param patch: Patch to apply.
      :param foreground: Foreground mask.
      :param patch_points: Array of shape (nb_frames, 4, 2) containing four pairs of integers (height, width)
                           corresponding to the coordinates of the four corners top-left, top-right, bottom-right,
                           bottom-left of the transformed image in the coordinate-system of the original image.
      :return: Patched videos.
      """
      import torch
      import torchvision
  
      nb_samples = videos.shape[0]
      nb_frames = videos.shape[1]
      frame_height = videos.shape[2]
      frame_width = videos.shape[3]
  
      image_mask = self._get_patch_mask(nb_samples=nb_samples)
      image_mask = image_mask.float()
  
      patch = patch.float()
      padded_patch = torch.stack([patch] * nb_samples)
  
      if patch_points is None:
          pad_h_before = self.x_min
          pad_h_after = int(
              videos.shape[self.i_h + 1]
              - pad_h_before
              - image_mask.shape[self.i_h_patch + 1]
          )
  
          pad_w_before = self.y_min
          pad_w_after = int(
              videos.shape[self.i_w + 1]
              - pad_w_before
              - image_mask.shape[self.i_w_patch + 1]
          )
  
          image_mask = image_mask.permute(0, 3, 1, 2)
  
          image_mask = torchvision.transforms.functional.pad(
              img=image_mask,
              padding=[
                  pad_w_before,
                  pad_h_before,
                  pad_w_after,
                  pad_h_after,
              ],
              fill=0,
              padding_mode="constant",
          )
  
          image_mask = image_mask.permute(0, 2, 3, 1)
  
          image_mask = torch.unsqueeze(image_mask, dim=1)
          image_mask = torch.repeat_interleave(
              image_mask, dim=1, repeats=nb_frames
          )
          image_mask = image_mask.float()
  
          padded_patch = padded_patch.permute(0, 3, 1, 2)
  
          padded_patch = torchvision.transforms.functional.pad(
              img=padded_patch,
              padding=[
                  pad_w_before,
                  pad_h_before,
                  pad_w_after,
                  pad_h_after,
              ],
              fill=0,
              padding_mode="constant",
          )
  
          padded_patch = padded_patch.permute(0, 2, 3, 1)
  
          padded_patch = torch.unsqueeze(padded_patch, dim=1)
          padded_patch = torch.repeat_interleave(
              padded_patch, dim=1, repeats=nb_frames
          )
  
          padded_patch = padded_patch.float()
  
      else:
          startpoints = [
              [0, 0],
              [frame_width, 0],
              [frame_width, frame_height],
              [0, frame_height],
          ]
          endpoints = np.zeros_like(patch_points)
          endpoints[:, :, 0] = patch_points[:, :, 1]
          endpoints[:, :, 1] = patch_points[:, :, 0]
  
          image_mask = image_mask.permute(0, 3, 1, 2)
  
          image_mask = torchvision.transforms.functional.resize(
              img=image_mask,
              size=[int(videos.shape[2]), int(videos.shape[3])],
              interpolation=torchvision.transforms.InterpolationMode.BILINEAR,
          )
  
          image_mask_list = []
  
          for i_frame in range(nb_frames):
              image_mask_i = torchvision.transforms.functional.perspective(
                  img=image_mask,
                  startpoints=startpoints,
                  endpoints=endpoints[i_frame],
                  interpolation=torchvision.transforms.InterpolationMode.BILINEAR,
                  fill=0,
              )
  
              image_mask_i = image_mask_i.permute(0, 2, 3, 1)
  
              image_mask_list.append(image_mask_i)
  
          image_mask = torch.stack(image_mask_list, dim=1)
          image_mask = image_mask.float()
  
          padded_patch = padded_patch.permute(0, 3, 1, 2)
  
          padded_patch = torchvision.transforms.functional.resize(
              img=padded_patch,
              size=[int(videos.shape[2]), int(videos.shape[3])],
              interpolation=torchvision.transforms.InterpolationMode.BILINEAR,
          )
  
          padded_patch_list = []
  
          for i_frame in range(nb_frames):
              padded_patch_i = torchvision.transforms.functional.perspective(
                  img=padded_patch,
                  startpoints=startpoints,
                  endpoints=endpoints[i_frame],
                  interpolation=torchvision.transforms.InterpolationMode.BILINEAR,
                  fill=0,
              )
  
              padded_patch_i = padded_patch_i.permute(0, 2, 3, 1)
  
              padded_patch_list.append(padded_patch_i)
  
          padded_patch = torch.stack(padded_patch_list, dim=1)
          padded_patch = padded_patch.float()
  
      inverted_mask = (
          torch.from_numpy(
              np.ones(shape=image_mask.shape, dtype=np.float32)
          ).to(self.estimator.device)
          - image_mask
      )
  
      if foreground is not None:
          combined = (
              videos * inverted_mask
              + padded_patch * image_mask
              - padded_patch * ~foreground.bool()
              + videos * ~foreground.bool() * image_mask
          )
      else:
          combined = videos * inverted_mask + padded_patch * image_mask
  
      return combined
  
imports: import logging
  from typing import Dict, List, Optional, Union, TYPE_CHECKING
  import numpy
  from tqdm.auto import trange
  from art.attacks.attack import EvasionAttack
  from art.estimators.estimator import BaseEstimator, LossGradientsMixin
  from art.estimators.object_tracking.object_tracker import ObjectTrackerMixin
  from art.summary_writer import SummaryWriter
label_desc: Use image node_id 6 for calling the AdversarialTexturePyTorch obj's underlying member method code with example usage: obj._apply_texture(videos, patch, foreground, patch_points) and returns: combined