text: #! /usr/bin/python
  
  # autogenerated on 2020-03-19 16:49
  
  # 2D image filtering
  
  import cv2
  import numpy as np
  
  from utils import *
  
  
  def propagate(x, offset, size):
      if x < offset:
          return 0
      elif x >= size:
          return size - 1
      return x - offset
  
  
  def mirror(x, offset, size):
      if x < offset:
          return offset - x
      elif x >= size:
          err = x % size
          tmp = size - err - offset - 1
          return tmp
      return x - offset
  
  
  def make_support(img, ker, func, out_type):
      ir, ic = img.shape
      kr, kc = ker.shape
      sx = ir + kr - 1
      sy = ic + kc - 1
      output = np.zeros((sx, sy), dtype=out_type)
  
      offset_x = kr // 2
      offset_y = kc // 2
      for i in range(sx):
          for j in range(sy):
              a = func(i, offset_x, ir)
              b = func(j, offset_y, ic)
              output[i, j] = img[a, b]
  
      return output
  
  
  def convolution_2D(image, kernel, out_type=np.uint8):
      ir, ic = image.shape
      kr, kc = kernel.shape
      sx = ir + kr - 1
      sy = ic + kc - 1
      c = np.zeros((sx, sy), dtype=out_type)
      image = image.astype(np.float)
  
      for i in range(ir):
          for j in range(kr):
              for h in range(ic):
                  for k in range(kc):
                      c[i + j][h + k] = c[i + j][h + k] + image[i][h] * kernel[j][k]
  
      c = c.astype(np.uint8)
  
      return c
  
  
  def crop(img, ker):
      sx, sy = ker.shape
      cut_x = sx // 2
      cut_y = sy // 2
  
      sx, sy = img.shape
      return img[cut_x : sx - cut_x, cut_y : sy - cut_y]
  
  
  def filter_2D(img, ker, border=None, out_type=np.uint8):
      if border:
          tmp = make_support(img, ker, border, out_type)
          out = convolution_2D(tmp, ker, out_type=out_type)
          out = crop(out, ker)
      else:
          out = convolution_2D(img, ker, out_type=out_type)
      return crop(out, ker)
  
  
  def make_kernel(size):
      tmp = np.ones((size, size))
      size *= size
      return tmp / size
  
  
  def main():
      img = load_image()
      ker = make_kernel(3)
  
      out = filter_2D(img, ker, border=mirror)
      assert img.shape == out.shape
  
  
  if __name__ == "__main__":
      main()
  