text: import numpy as np
  import time
  import cv2
  import socket
  import struct
  import json
  from input_reader import InputReader, VideoReader, DShowCaptureReader, try_int
  from tracker import Tracker, get_model_base_path
  from tqdm import tqdm
  import copy
  import os
  import sys
  import argparse
  import traceback
  import gc
  import math
  from math import cos, sin
  from scipy.spatial import distance as dist
  import imutils
  import pandas as pd
  from rt_gene.estimate_gaze_tensorflow import GazeEstimator
  from rt_gene.tracker_generic import GenericTracker
  import matplotlib.pyplot as plt
  from rt_gene.gaze_tools import get_phi_theta_from_euler, limit_yaw
  from rt_gene.gaze_tools_standalone import euler_from_matrix
  from imutils import paths
  
  parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
  parser.add_argument("-i", "--ip", help="Set IP address for sending tracking data", default="127.0.0.1")
  parser.add_argument("-p", "--port", type=int, help="Set port for sending tracking data", default=11573)
  if os.name == 'nt':
      parser.add_argument("-l", "--list-cameras", type=int, help="Set this to 1 to list the available cameras and quit, set this to 2 or higher to output only the names", default=0)
      parser.add_argument("-a", "--list-dcaps", type=int, help="Set this to -1 to list all cameras and their available capabilities, set this to a camera id to list that camera's capabilities", default=None)
      parser.add_argument("-W", "--width", type=int, help="Set camera and raw RGB width", default=640)
      parser.add_argument("-H", "--height", type=int, help="Set camera and raw RGB height", default=360)
      parser.add_argument("-F", "--fps", type=int, help="Set camera frames per second", default=24)
      parser.add_argument("-D", "--dcap", type=int, help="Set which device capability line to use or -1 to use the default camera settings", default=None)
      parser.add_argument("-B", "--blackmagic", type=int, help="When set to 1, special support for Blackmagic devices is enabled", default=0)
  else:
      parser.add_argument("-W", "--width", type=int, help="Set raw RGB width", default=640)
      parser.add_argument("-H", "--height", type=int, help="Set raw RGB height", default=360)
  parser.add_argument("-c", "--capture", help="Set camera ID (0, 1...) or video file", default="0")
  parser.add_argument("-m", "--max-threads", type=int, help="Set the maximum number of threads", default=1)
  parser.add_argument("-t", "--threshold", type=float, help="Set minimum confidence threshold for face tracking", default=None)
  parser.add_argument("-d", "--detection-threshold", type=float, help="Set minimum confidence threshold for face detection", default=0.02)
  parser.add_argument("-v", "--visualize", type=int, help="Set this to 1 to visualize the tracking, to 2 to also show face ids, to 3 to add confidence values or to 4 to add numbers to the point display", default=0)
  parser.add_argument("-P", "--pnp-points", type=int, help="Set this to 1 to add the 3D fitting points to the visualization", default=0)
  parser.add_argument("-s", "--silent", type=int, help="Set this to 1 to prevent text output on the console", default=0)
  parser.add_argument("--faces", type=int, help="Set the maximum number of faces (slow)", default=1)
  parser.add_argument("--scan-retinaface", type=int, help="When set to 1, scanning for additional faces will be performed using RetinaFace in a background thread, otherwise a simpler, faster face detection mechanism is used. When the maximum number of faces is 1, this option does nothing.", default=0)
  parser.add_argument("--scan-every", type=int, help="Set after how many frames a scan for new faces should run", default=3)
  parser.add_argument("--discard-after", type=int, help="Set the how long the tracker should keep looking for lost faces", default=10)
  parser.add_argument("--max-feature-updates", type=int, help="This is the number of seconds after which feature min/max/medium values will no longer be updated once a face has been detected.", default=900)
  parser.add_argument("--no-3d-adapt", type=int, help="When set to 1, the 3D face model will not be adapted to increase the fit", default=1)
  parser.add_argument("--try-hard", type=int, help="When set to 1, the tracker will try harder to find a face", default=0)
  parser.add_argument("--video-out", help="Set this to the filename of an AVI file to save the tracking visualization as a video", default=None)
  parser.add_argument("--video-scale", type=int, help="This is a resolution scale factor applied to the saved AVI file", default=1, choices=[1,2,3,4])
  parser.add_argument("--video-fps", type=float, help="This sets the frame rate of the output AVI file", default=24)
  parser.add_argument("--raw-rgb", type=int, help="When this is set, raw RGB frames of the size given with \"-W\" and \"-H\" are read from standard input instead of reading a video", default=0)
  parser.add_argument("--log-data", help="You can set a filename to which tracking data will be logged here", default="")
  parser.add_argument("--log-output", help="You can set a filename to console output will be logged here", default="")
  parser.add_argument("--ensamble", type=int, help="Set to 1 to use ensamble models(4 models)", default=0)
  parser.add_argument("--model", type=int, help="This can be used to select the tracking model. Higher numbers are models with better tracking quality, but slower speed, except for model 4, which is wink optimized. Models 1 and 0 tend to be too rigid for expression and blink detection. Model -2 is roughly equivalent to model 1, but faster. Model -3 is between models 0 and -1.", default=3, choices=[-3, -2, -1, 0, 1, 2, 3, 4])
  parser.add_argument("--model-dir", help="This can be used to specify the path to the directory containing the .onnx model files", default=None)
  parser.add_argument("--gaze-tracking", type=int, help="When set to 1, experimental blink detection and gaze tracking are enabled, which makes things slightly slower", default=1)
  parser.add_argument("--eye-gaze", type=int, help="When 1 eye gaze estimation will be calculated", default=0)
  parser.add_argument("--face-id-offset", type=int, help="When set, this offset is added to all face ids, which can be useful for mixing tracking data from multiple network sources", default=0)
  parser.add_argument("--repeat-video", type=int, help="When set to 1 and a video file was specified with -c, the tracker will loop the video until interrupted", default=0)
  parser.add_argument("--dump-points", type=str, help="When set to a filename, the current face 3D points are made symmetric and dumped to the given file when quitting the visualization with the \"q\" key", default="")
  parser.add_argument("--benchmark", type=int, help="When set to 1, the different tracking models are benchmarked, starting with the best and ending with the fastest and with gaze tracking disabled for models with negative IDs", default=0)
  if os.name == 'nt':
      parser.add_argument("--use-dshowcapture", type=int, help="When set to 1, libdshowcapture will be used for video input instead of OpenCV", default=1)
      parser.add_argument("--blackmagic-options", type=str, help="When set, this additional option string is passed to the blackmagic capture library", default=None)
      parser.add_argument("--priority", type=int, help="When set, the process priority will be changed", default=None, choices=[0, 1, 2, 3, 4, 5])
  args = parser.parse_args()
  
  os.environ["OMP_NUM_THREADS"] = str(args.max_threads)
  list_imgs = list(paths.list_images('C:\\Users\\huynh14\\DMS\\scripts\\facelandmarks\\OpenSeeFace\\WIDER_val\\WIDER_val\\images'))
  
  start = time.time()
  for img in tqdm(list_imgs):
      print(f"Processing image: {img}")
      fps = 24
      dcap = None
      use_dshowcapture_flag = False
      if os.name == 'nt':
          fps = args.fps
          dcap = args.dcap
          use_dshowcapture_flag = True if args.use_dshowcapture == 1 else False
          input_reader = InputReader(img, args.raw_rgb, args.width, args.height, fps, use_dshowcapture=use_dshowcapture_flag, dcap=dcap)
          if args.dcap == -1 and type(input_reader) == DShowCaptureReader:
              fps = min(fps, input_reader.device.get_fps())
      else:
          input_reader = InputReader(img, args.raw_rgb, args.width, args.height, fps, use_dshowcapture=use_dshowcapture_flag)
  
      if type(input_reader.reader) == VideoReader:
          fps = 0.0
  
      ret, frame = input_reader.read()
      height, width, channels = frame.shape
      tracker = Tracker(width, height, threshold=args.threshold, max_threads=args.max_threads, max_faces=args.faces, discard_after=args.discard_after, scan_every=args.scan_every, silent=False if args.silent == 0 else True, model_type=args.model, model_dir=args.model_dir, no_gaze=False if args.gaze_tracking != 0 and args.model != -1 else True, detection_threshold=args.detection_threshold, use_retinaface=args.scan_retinaface, max_feature_updates=args.max_feature_updates, static_model=True if args.no_3d_adapt == 1 else False, try_hard=args.try_hard == 1)
      faces = tracker.predict(frame)
      base_name = os.path.basename(img).split('.')[0]
      with open(f"C:\\Users\\huynh14\\DMS\\scripts\\facelandmarks\\OpenSeeFace\\widerface_evaluate\\widerface_txt_4_no_try_hard\\{base_name}.txt", 'w') as fd:
          file_name = base_name + "\n"
          bboxs_num = str(len(faces)) + "\n"
          fd.write(file_name)
          fd.write(bboxs_num)
          
          for face_num, f in enumerate(faces):
              x = int(f.bbox[0])
              y = int(f.bbox[1])
              w = int(f.bbox[2])
              h = int(f.bbox[3])
  
              confidence = str(round(f.conf, 4))
              line = str(x) + " " + str(y) + " " + str(w) + " " + str(h) + " " + confidence + " \n"
              fd.write(line)
  
  print(f"Total eval time: {time.time() - start}s")
  