class_docstr: Extractor to generate patches with or without padding.
  Turn on debug mode to see how it is done.
  
  Args:
      x         : input image, should be of shape HWC
      patch_size  : a tuple of (h, w)
      step_size : a tuple of (h, w)
  Return:
      a list of sub patches, each patch has dtype same as x
  
  Examples:
      >>> xtractor = PatchExtractor((450, 450), (120, 120))
      >>> img = np.full([1200, 1200, 3], 255, np.uint8)
      >>> patches = xtractor.extract(img, 'mirror')
docstr: Extracted patches without padding, only work in case patch_size > step_size.
  
  Note: to deal with the remaining portions which are at the boundary a.k.a
  those which do not fit when slide left->right, top->bottom), we flip
  the sliding direction then extract 1 patch starting from right / bottom edge.
  There will be 1 additional patch extracted at the bottom-right corner.
  
  Args:
      x         : input image, should be of shape HWC
      patch_size  : a tuple of (h, w)
      step_size : a tuple of (h, w)
  Return:
      a list of sub patches, each patch is same dtype as x
docstr_tok: ["Extracted","patches","without","padding",",","only","work","in","case","patch_size",">","step_size",".","Note",":","to","deal","with","the","remaining","portions","which","are","at","the","boundary","a.k.a","those","which","do","not","fit","when","slide","left-",">","right",",","top-",">","bottom",")",",","we","flip","the","sliding","direction","then","extract","1","patch","starting","from","right","\/","bottom","edge",".","There","will","be","1","additional","patch","extracted","at","the","bottom-right","corner",".","Args",":","x",":","input","image",",","should","be","of","shape","HWC","patch_size",":","a","tuple","of","(","h",",","w",")","step_size",":","a","tuple","of","(","h",",","w",")","Return",":","a","list","of","sub","patches",",","each","patch","is","same","dtype","as","x"]
code: def __extract_valid(self, x):
      """Extracted patches without padding, only work in case patch_size > step_size.
  
      Note: to deal with the remaining portions which are at the boundary a.k.a
      those which do not fit when slide left->right, top->bottom), we flip
      the sliding direction then extract 1 patch starting from right / bottom edge.
      There will be 1 additional patch extracted at the bottom-right corner.
  
      Args:
          x         : input image, should be of shape HWC
          patch_size  : a tuple of (h, w)
          step_size : a tuple of (h, w)
      Return:
          a list of sub patches, each patch is same dtype as x
  
      """
      im_h = x.shape[0]
      im_w = x.shape[1]
  
      def extract_infos(length, patch_size, step_size):
          flag = (length - patch_size) % step_size != 0
          last_step = math.floor((length - patch_size) / step_size)
          last_step = (last_step + 1) * step_size
          return flag, last_step
  
      h_flag, h_last = extract_infos(
          im_h, self.patch_size[0], self.step_size[0]
      )
      w_flag, w_last = extract_infos(
          im_w, self.patch_size[1], self.step_size[1]
      )
  
      sub_patches = []
      # Deal with valid block
      for row in range(0, h_last, self.step_size[0]):
          for col in range(0, w_last, self.step_size[1]):
              win = self.__get_patch(x, (row, col))
              sub_patches.append(win)
      # Deal with edge case
      if h_flag:
          row = im_h - self.patch_size[0]
          for col in range(0, w_last, self.step_size[1]):
              win = self.__get_patch(x, (row, col))
              sub_patches.append(win)
      if w_flag:
          col = im_w - self.patch_size[1]
          for row in range(0, h_last, self.step_size[0]):
              win = self.__get_patch(x, (row, col))
              sub_patches.append(win)
      if h_flag and w_flag:
          ptx = (im_h - self.patch_size[0], im_w - self.patch_size[1])
          win = self.__get_patch(x, ptx)
          sub_patches.append(win)
      return sub_patches
  
imports: import math
  import numpy
label_desc: Use image node_id 3 for calling the PatchExtractor obj's underlying member method code with example usage: obj.__extract_valid(x) and returns: sub_patches, flag,  last_step