code: def render_serial(original_img, net_g, meta_brushes):
      patch_size = 32
      stroke_num = 8
      H, W = original_img.shape[-2:]
      K = max(math.ceil(math.log2(max(H, W) / patch_size)), 0)
  
      dilation = Dilation2d(m=1)
      erosion = Erosion2d(m=1)
      frames_per_layer = [20, 20, 30, 40, 60]
      final_frame_list = []
  
      with paddle.no_grad():
          # * ----- read in image and init canvas ----- *#
          final_result = paddle.zeros_like(original_img)
  
          for layer in range(0, K + 1):
              t0 = time.time()
              layer_size = patch_size * (2**layer)
  
              img = nn.functional.interpolate(
                  original_img, (layer_size, layer_size)
              )
              result = nn.functional.interpolate(
                  final_result, (layer_size, layer_size)
              )
              img_patch = nn.functional.unfold(
                  img,
                  [patch_size, patch_size],
                  strides=[patch_size, patch_size],
              )
              result_patch = nn.functional.unfold(
                  result,
                  [patch_size, patch_size],
                  strides=[patch_size, patch_size],
              )
              h = (img.shape[2] - patch_size) // patch_size + 1
              w = (img.shape[3] - patch_size) // patch_size + 1
              render_size_y = int(1.25 * H // h)
              render_size_x = int(1.25 * W // w)
  
              # * -------------------------------------------------------------*#
              # * -------------generate strokes on window type A---------------*#
              # * -------------------------------------------------------------*#
              param, decision = stroke_net_predict(
                  img_patch, result_patch, patch_size, net_g, stroke_num
              )
              expand_img = original_img
              (
                  wA_xid_list,
                  wA_yid_list,
                  wA_fore_list,
                  wA_alpha_list,
                  wA_error_list,
                  wA_params,
              ) = get_single_layer_lists(
                  param,
                  decision,
                  original_img,
                  render_size_x,
                  render_size_y,
                  h,
                  w,
                  meta_brushes,
                  dilation,
                  erosion,
                  stroke_num,
              )
  
              # * -------------------------------------------------------------*#
              # * -------------generate strokes on window type B---------------*#
              # * -------------------------------------------------------------*#
              # *----- generate input canvas and target patches -----*#
              wB_error_list = []
  
              img = nn.functional.pad(
                  img,
                  [
                      patch_size // 2,
                      patch_size // 2,
                      patch_size // 2,
                      patch_size // 2,
                  ],
              )
              result = nn.functional.pad(
                  result,
                  [
                      patch_size // 2,
                      patch_size // 2,
                      patch_size // 2,
                      patch_size // 2,
                  ],
              )
              img_patch = nn.functional.unfold(
                  img,
                  [patch_size, patch_size],
                  strides=[patch_size, patch_size],
              )
              result_patch = nn.functional.unfold(
                  result,
                  [patch_size, patch_size],
                  strides=[patch_size, patch_size],
              )
              h += 1
              w += 1
  
              param, decision = stroke_net_predict(
                  img_patch, result_patch, patch_size, net_g, stroke_num
              )
  
              patch_y = 4 * render_size_y // 5
              patch_x = 4 * render_size_x // 5
              expand_img = nn.functional.pad(
                  original_img,
                  [
                      patch_x // 2,
                      patch_x // 2,
                      patch_y // 2,
                      patch_y // 2,
                  ],
              )
              (
                  wB_xid_list,
                  wB_yid_list,
                  wB_fore_list,
                  wB_alpha_list,
                  wB_error_list,
                  wB_params,
              ) = get_single_layer_lists(
                  param,
                  decision,
                  expand_img,
                  render_size_x,
                  render_size_y,
                  h,
                  w,
                  meta_brushes,
                  dilation,
                  erosion,
                  stroke_num,
              )
              # * -------------------------------------------------------------*#
              # * -------------rank strokes and plot stroke one by one---------*#
              # * -------------------------------------------------------------*#
              numA = len(wA_error_list)
              numB = len(wB_error_list)
              total_error_list = wA_error_list + wB_error_list
              sort_list = list(np.argsort(total_error_list))
  
              sample = 0
              samples = np.linspace(
                  0, len(sort_list) - 2, frames_per_layer[layer]
              ).astype(int)
              for ii in sort_list:
                  ii = int(ii)
                  if ii < numA:
                      x_id = wA_xid_list[ii]
                      y_id = wA_yid_list[ii]
                      valid_foregrounds = wA_fore_list[ii]
                      valid_alphas = wA_alpha_list[ii]
                      sparam = wA_params[ii]
                      (
                          tmp_foreground,
                          tmp_alpha,
                      ) = get_single_stroke_on_full_image_A(
                          x_id,
                          y_id,
                          valid_foregrounds,
                          valid_alphas,
                          sparam,
                          original_img,
                          render_size_x,
                          render_size_y,
                          patch_x,
                          patch_y,
                      )
                  else:
                      x_id = wB_xid_list[ii - numA]
                      y_id = wB_yid_list[ii - numA]
                      valid_foregrounds = wB_fore_list[ii - numA]
                      valid_alphas = wB_alpha_list[ii - numA]
                      sparam = wB_params[ii - numA]
                      (
                          tmp_foreground,
                          tmp_alpha,
                      ) = get_single_stroke_on_full_image_B(
                          x_id,
                          y_id,
                          valid_foregrounds,
                          valid_alphas,
                          sparam,
                          original_img,
                          render_size_x,
                          render_size_y,
                          patch_x,
                          patch_y,
                      )
  
                  final_result = (
                      tmp_foreground * tmp_alpha
                      + (1 - tmp_alpha) * final_result
                  )
                  if sample in samples:
                      saveframe = (
                          final_result.numpy()
                          .squeeze()
                          .transpose([1, 2, 0])[:, :, ::-1]
                          * 255
                      ).astype(np.uint8)
                      final_frame_list.append(saveframe)
                      # saveframe = cv2.resize(saveframe, (ow, oh))
  
                  sample += 1
              print("layer %d cost: %.02f" % (layer, time.time() - t0))
  
          saveframe = (
              final_result.numpy()
              .squeeze()
              .transpose([1, 2, 0])[:, :, ::-1]
              * 255
          ).astype(np.uint8)
          final_frame_list.append(saveframe)
      return final_frame_list
  
file_path: PaddleHub/modules/image/Image_gan/style_transfer/paint_transformer/render_serial.py
imports: import paddle
  import paddle.nn
  import paddle.nn.functional
  import numpy
  from PIL import Image
  import math
  import cv2
  import time
  from .render_utils import param2stroke, Dilation2d, Erosion2d
label_desc: Use image node_id 6 for calling a global function with example usage: render_serial(original_img, net_g, meta_brushes) and returns: final_frame_list