code: def detect_face(img, minsize, pnet, rnet, onet, threshold, factor):
      # im: input image
      # minsize: minimum of faces' size
      # pnet, rnet, onet: model
      # threshold: threshold=[th1 th2 th3], th1-3 are three steps's threshold
      # factor: resize img to generate pyramid
      factor_count = 0
      total_boxes = np.empty((0, 9))
      points = []
      h = img.shape[0]
      w = img.shape[1]
      minl = np.amin([h, w])
      m = 12.0 / minsize
      minl = minl * m
      # creat scale pyramid
      scales = []
      while minl >= 12:
          scales += [m * np.power(factor, factor_count)]
          minl = minl * factor
          factor_count += 1
  
      # first stage
      for j in range(len(scales)):
          scale = scales[j]
          hs = int(np.ceil(h * scale))
          ws = int(np.ceil(w * scale))
          im_data = imresample(img, (hs, ws))
          im_data = (im_data - 127.5) * 0.0078125
          img_x = np.expand_dims(im_data, 0)
          img_y = np.transpose(img_x, (0, 2, 1, 3))
          out = pnet(img_y)
          out0 = np.transpose(out[0], (0, 2, 1, 3))
          out1 = np.transpose(out[1], (0, 2, 1, 3))
  
          boxes, _ = generateBoundingBox(
              out1[0, :, :, 1].copy(),
              out0[0, :, :, :].copy(),
              scale,
              threshold[0],
          )
  
          # inter-scale nms
          pick = nms(boxes.copy(), 0.5, "Union")
          if boxes.size > 0 and pick.size > 0:
              boxes = boxes[pick, :]
              total_boxes = np.append(total_boxes, boxes, axis=0)
  
      numbox = total_boxes.shape[0]
      if numbox > 0:
          pick = nms(total_boxes.copy(), 0.7, "Union")
          total_boxes = total_boxes[pick, :]
          regw = total_boxes[:, 2] - total_boxes[:, 0]
          regh = total_boxes[:, 3] - total_boxes[:, 1]
          qq1 = total_boxes[:, 0] + total_boxes[:, 5] * regw
          qq2 = total_boxes[:, 1] + total_boxes[:, 6] * regh
          qq3 = total_boxes[:, 2] + total_boxes[:, 7] * regw
          qq4 = total_boxes[:, 3] + total_boxes[:, 8] * regh
          total_boxes = np.transpose(
              np.vstack([qq1, qq2, qq3, qq4, total_boxes[:, 4]])
          )
          total_boxes = rerec(total_boxes.copy())
          total_boxes[:, 0:4] = np.fix(total_boxes[:, 0:4]).astype(
              np.int32
          )
          dy, edy, dx, edx, y, ey, x, ex, tmpw, tmph = pad(
              total_boxes.copy(), w, h
          )
  
      numbox = total_boxes.shape[0]
      if numbox > 0:
          # second stage
          tempimg = np.zeros((24, 24, 3, numbox))
          for k in range(0, numbox):
              tmp = np.zeros((int(tmph[k]), int(tmpw[k]), 3))
              tmp[dy[k] - 1 : edy[k], dx[k] - 1 : edx[k], :] = img[
                  y[k] - 1 : ey[k], x[k] - 1 : ex[k], :
              ]
              if (
                  tmp.shape[0] > 0
                  and tmp.shape[1] > 0
                  or tmp.shape[0] == 0
                  and tmp.shape[1] == 0
              ):
                  tempimg[:, :, :, k] = imresample(tmp, (24, 24))
              else:
                  return np.empty()
          tempimg = (tempimg - 127.5) * 0.0078125
          tempimg1 = np.transpose(tempimg, (3, 1, 0, 2))
          out = rnet(tempimg1)
          out0 = np.transpose(out[0])
          out1 = np.transpose(out[1])
          score = out1[1, :]
          ipass = np.where(score > threshold[1])
          total_boxes = np.hstack(
              [
                  total_boxes[ipass[0], 0:4].copy(),
                  np.expand_dims(score[ipass].copy(), 1),
              ]
          )
          mv = out0[:, ipass[0]]
          if total_boxes.shape[0] > 0:
              pick = nms(total_boxes, 0.7, "Union")
              total_boxes = total_boxes[pick, :]
              total_boxes = bbreg(
                  total_boxes.copy(), np.transpose(mv[:, pick])
              )
              total_boxes = rerec(total_boxes.copy())
  
      numbox = total_boxes.shape[0]
      if numbox > 0:
          # third stage
          total_boxes = np.fix(total_boxes).astype(np.int32)
          dy, edy, dx, edx, y, ey, x, ex, tmpw, tmph = pad(
              total_boxes.copy(), w, h
          )
          tempimg = np.zeros((48, 48, 3, numbox))
          for k in range(0, numbox):
              tmp = np.zeros((int(tmph[k]), int(tmpw[k]), 3))
              tmp[dy[k] - 1 : edy[k], dx[k] - 1 : edx[k], :] = img[
                  y[k] - 1 : ey[k], x[k] - 1 : ex[k], :
              ]
              if (
                  tmp.shape[0] > 0
                  and tmp.shape[1] > 0
                  or tmp.shape[0] == 0
                  and tmp.shape[1] == 0
              ):
                  tempimg[:, :, :, k] = imresample(tmp, (48, 48))
              else:
                  return np.empty()
          tempimg = (tempimg - 127.5) * 0.0078125
          tempimg1 = np.transpose(tempimg, (3, 1, 0, 2))
          out = onet(tempimg1)
          out0 = np.transpose(out[0])
          out1 = np.transpose(out[1])
          out2 = np.transpose(out[2])
          score = out2[1, :]
          points = out1
          ipass = np.where(score > threshold[2])
          points = points[:, ipass[0]]
          total_boxes = np.hstack(
              [
                  total_boxes[ipass[0], 0:4].copy(),
                  np.expand_dims(score[ipass].copy(), 1),
              ]
          )
          mv = out0[:, ipass[0]]
  
          w = total_boxes[:, 2] - total_boxes[:, 0] + 1
          h = total_boxes[:, 3] - total_boxes[:, 1] + 1
          points[0:5, :] = (
              np.tile(w, (5, 1)) * points[0:5, :]
              + np.tile(total_boxes[:, 0], (5, 1))
              - 1
          )
          points[5:10, :] = (
              np.tile(h, (5, 1)) * points[5:10, :]
              + np.tile(total_boxes[:, 1], (5, 1))
              - 1
          )
          if total_boxes.shape[0] > 0:
              total_boxes = bbreg(total_boxes.copy(), np.transpose(mv))
              pick = nms(total_boxes.copy(), 0.7, "Min")
              total_boxes = total_boxes[pick, :]
              points = points[:, pick]
  
      return total_boxes, points
  
imports: from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  import numpy
  import tensorflow
  import cv2
  import os
  import inspect
label_desc: Use image node_id 3 for calling a global function with example usage: detect_face(img, minsize, pnet, rnet, onet, threshold, factor) and returns: total_boxes,  points, np, np