def main(_):
    # loading detection label map
    # PATH_TO_LABELS = '/home/hu/Downloads/tensorflow-models/research/VOCdevkit/VOC2012/data/cad_label_map.pbtxt'
    NUM_CLASSES = 3
    label_map = label_map_util.load_labelmap(FLAGS.detect_labels_path)
    categories = label_map_util.convert_label_map_to_categories(
        label_map, max_num_classes=NUM_CLASSES, use_display_name=True)
    category_index = label_map_util.create_category_index(categories)
    '''
  {1: {'id': 1, 'name': 'person'},
   2: {'id': 2, 'name': 'vanRear'},
   3: {'id': 3, 'name': 'plate'}}
  '''

    # loading classification label map
    node_lookup = NodeLookup(FLAGS.classify_labels_path)
    # human_string = node_lookup.id_to_string(node_id)

    if not FLAGS.video_file:
        raise ValueError('You must supply the video file name (--video_file)')

    ############################################################
    print("initializing...")
    ############################################################
    detect_inference = Detect_inference(FLAGS.detect_model_path)
    lr_inference = LR_inference(FLAGS.classify_model_path)
    alpr = Alpr('cn', 'OpenALPR_python/openalpr.conf',
                'OpenALPR_python/runtime_data')
    if not alpr.is_loaded():
        print('!!! Error loading OpenALPR')
    else:
        print('Using OpenALPR', alpr.get_version())
        # image = cv2.imread("../OpenALPR_python/5.png")
        # best = alpr.recognize_plate(image)
        # alpr.unload()
    ''' ##################test models########################
  img_to_detect = cv2.imread('/media/hu/186E61E86E61BF5E/video-analysis/test_images/35.jpg')
  img_to_classify = cv2.imread('/home/hu/Downloads/tensorflow-models/research/VOCdevkit/VOC2012/models/model/frozen_inference_graph/loadingRate/tesdata/93.png')
  (boxes, scores, classes, num) = detect_inference.predict(img_to_detect)
  classify_predictions = lr_inference.predict(img_to_classify)
  vis_util.visualize_boxes_and_labels_on_image_array(
          img_to_detect,
          np.squeeze(boxes),
          np.squeeze(classes).astype(np.int32),
          np.squeeze(scores),
          category_index,
          use_normalized_coordinates=True,
          line_thickness=2)
  cv2.imshow('test', img_to_detect)
  cv2.waitKey(0)

  classify_predictions = np.squeeze(classify_predictions)

  top_k = classify_predictions.argsort()[-2:][::-1]
  top_names = []
  for node_id in top_k:
    human_string = node_lookup.id_to_string(node_id)
    top_names.append(human_string)
    score = classify_predictions[node_id]
    print('id:[%d] name:[%s] (score = %.5f)' % (node_id, human_string, score))
    print(classify_predictions, top_k, top_names)
  '''

    ############################################################
    print("program launched...")
    ############################################################
    displayWidth = 1280
    extra_region = 100

    cap = cv2.VideoCapture(FLAGS.video_file)
    fps = cap.get(cv2.CAP_PROP_FPS)
    wd = cap.get(cv2.CAP_PROP_FRAME_WIDTH)
    ht = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
    left_bound = 1 / 3
    right_bound = 2 / 3
    # bottom_bound = None

    ratiorgb = ht / wd
    displayHeight = int(displayWidth * ratiorgb)

    fourcc = cv2.VideoWriter_fourcc(*'XVID')
    outfile = cv2.VideoWriter('output63_8_0.avi', fourcc, fps,
                              (displayWidth, displayHeight + extra_region))
    #cv2.namedWindow('test')

    state = -1  # -1 : unknown, 0 : noVan, 1 : van
    plate = None
    loadingRate = None
    plateNumber = 0
    vanRearCounter = 0
    noVanRearCounter = 0
    confirmVanRear = 5
    confirmNoVanRear_for_noVan = int(fps)
    confirmNoVanRear_for_van = int(2 * fps)
    vanRears = []
    plates = []
    min_score_thresh = 0.5
    x_center = 0
    van_is_moving = False
    hasVanRear = False
    bestPlate = None

    fontFace = cv2.FONT_HERSHEY_COMPLEX
    duration_displaying_loading_rate = int(10 * fps)
    counter_for_displaying = 0

    while True:
        ret, image_np = cap.read()
        if not ret:
            break
        (boxes, scores, classes, num) = detect_inference.predict(image_np)
        boxes = np.squeeze(boxes)
        classes = np.squeeze(classes).astype(np.int32)
        scores = np.squeeze(scores)
        if van_is_moving:
            hasVanRear = False
            for i in range(int(num[0])):
                if scores[i] >= min_score_thresh:
                    if classes[i] == 2:
                        x_center = (boxes[i][1] + boxes[i][3]) / 2
                        if x_center >= left_bound and x_center <= right_bound:
                            hasVanRear = True
                            # vanRearCounter += 1
                            # vanRears.append(image_np[int(boxes[i][0]*ht):int(boxes[i][2]*ht)+1, int(boxes[i][1]*wd):int(boxes[i][3]*wd)+1])
                            for j in range(int(num[0])):
                                if scores[j] >= min_score_thresh:
                                    if classes[j] == 3 and boxes[j][0] >= boxes[
                                            i][0] and boxes[j][1] >= boxes[i][
                                                1] and boxes[j][2] <= boxes[i][
                                                    2] and boxes[j][
                                                        3] <= boxes[i][3]:
                                        plates.append(image_np[
                                            int(boxes[j][0] *
                                                ht):int(boxes[j][2] * ht) + 1,
                                            int(boxes[j][1] *
                                                wd):int(boxes[j][3] * wd) + 1])
                                        vanRears.append(image_np[
                                            int(boxes[i][0] *
                                                ht):int(boxes[j][0] * ht) + 1,
                                            int(boxes[i][1] *
                                                wd):int(boxes[i][3] * wd) + 1])
                                        #cv2.imshow('plate', plates[-1])
                                        #cv2.imshow('vanRear', vanRears[-1])
                                        #cv2.waitKey(1)
                                        break  # already found plate, then break the loop
                                else:
                                    break
                            break
                else:
                    break
            if not hasVanRear:
                noVanRearCounter += 1
                if noVanRearCounter == confirmNoVanRear_for_noVan:  # and plates != []:
                    sum1 = vanRears[0].shape[1] + vanRears[1].shape[
                        1] + vanRears[2].shape[1]
                    sum2 = vanRears[-1].shape[1] + vanRears[-2].shape[
                        1] + vanRears[-3].shape[1]
                    if sum1 > sum2:
                        van_is_moving = False  # noVan confirmed
                        state = 0  # noVan
                        noVanRearCounter = 0
                        counter_for_displaying = 0
                        print(
                            '-----------------------noVan confirmed-------------------------------'
                        )
                        # evaluate loading rate and plate number
                        plateNumber = len(plates)
                        bestPlate = alpr.recognize_plate(
                            plates[int(0.1 * plateNumber) + 1])
                        plate = bestPlate['Plate']
                        #classify_predictions = lr_inference.predict(img_to_classify)
                        classify_predictions = lr_inference.predict(
                            vanRears[int(0.05 * plateNumber) + 1])
                        classify_predictions = np.squeeze(classify_predictions)

                        top_k = classify_predictions.argsort()[-1:][::-1]
                        top_names = []
                        for node_id in top_k:
                            human_string = node_lookup.id_to_string(node_id)
                            top_names.append(human_string)
                            score = classify_predictions[node_id]
                            loadingRate = human_string
                        vanRears.clear()
                        plates.clear()
                    else:
                        pass
                elif noVanRearCounter == confirmNoVanRear_for_van:  # and plates != []:
                    #sum1 = vanRears[5].shape[1] + vanRears[6].shape[1] + vanRears[7].shape[1]
                    #sum2 = vanRears[-6].shape[1] + vanRears[-7].shape[1] + vanRears[-8].shape[1]
                    #if sum1 < sum2:
                    van_is_moving = False  # van confirmed
                    state = 1  # van
                    noVanRearCounter = 0
                    counter_for_displaying = 0
                    print(
                        '+++++++++++++++++++++++++++van confirmed++++++++++++++++++++++++++++++++++'
                    )
                    # evaluate loading rate and plate number
                    plateNumber = len(plates)
                    cv2.imwrite('plate.png', plates[int(0.9 * plateNumber)])
                    bestPlate = alpr.recognize_plate(plates[int(0.9 *
                                                                plateNumber)])
                    plate = bestPlate['Plate']
                    classify_predictions = lr_inference.predict(vanRears[int(
                        0.95 * plateNumber)])
                    classify_predictions = np.squeeze(classify_predictions)

                    top_k = classify_predictions.argsort()[-1:][::-1]
                    top_names = []
                    for node_id in top_k:
                        human_string = node_lookup.id_to_string(node_id)
                        top_names.append(human_string)
                        score = classify_predictions[node_id]
                        loadingRate = human_string
                    vanRears.clear()
                    plates.clear()
            else:
                noVanRearCounter = 0  # van is still moving
        else:
            hasVanRear = False
            for i in range(int(num[0])):
                if scores[i] >= min_score_thresh:
                    if classes[i] == 2:
                        x_center = (boxes[i][1] + boxes[i][3]) / 2
                        if x_center >= left_bound and x_center <= right_bound:
                            hasVanRear = True
                            vanRearCounter += 1
                            # vanRears.append(image_np[int(boxes[i][0]*ht):int(boxes[i][2]*ht)+1, int(boxes[i][1]*wd):int(boxes[i][3]*wd)+1])
                            for j in range(int(num[0])):
                                if scores[j] >= min_score_thresh:
                                    if classes[j] == 3 and boxes[j][0] >= boxes[
                                            i][0] and boxes[j][1] >= boxes[i][
                                                1] and boxes[j][2] <= boxes[i][
                                                    2] and boxes[j][
                                                        3] <= boxes[i][3]:
                                        plates.append(image_np[
                                            int(boxes[j][0] *
                                                ht):int(boxes[j][2] * ht) + 1,
                                            int(boxes[j][1] *
                                                wd):int(boxes[j][3] * wd) + 1])
                                        vanRears.append(image_np[
                                            int(boxes[i][0] *
                                                ht):int(boxes[j][0] * ht) + 1,
                                            int(boxes[i][1] *
                                                wd):int(boxes[i][3] * wd) + 1])
                                        #cv2.imshow('plate', plates[-1])
                                        #cv2.imshow('vanRear', vanRears[-1])
                                        #cv2.waitKey(1)
                                        break  # already found plate, then break the loop
                                else:
                                    break  # confidence too low, then break the loop
                            break  # already found vanRear, then break the loop
                else:
                    break  # confidence too low, then break the loop

            if not hasVanRear:
                vanRearCounter = 0
                vanRears.clear()
                plates.clear()
                # van_is_moving = False
            elif vanRearCounter == confirmVanRear:
                if plates != []:
                    van_is_moving = True
                    vanRearCounter = 0
                    print(
                        '===================van is moving======================'
                    )
                else:
                    vanRearCounter = 0
            else:
                #van_is_moving = False # just continue to accumulate evidence for van_is_moving to be True
                pass

        vis_util.visualize_boxes_and_labels_on_image_array(
            image_np,
            boxes,
            classes,
            scores,
            category_index,
            use_normalized_coordinates=True,
            max_boxes_to_draw=None,
            min_score_thresh=.5,
            line_thickness=2)
        image_np = cv2.resize(image_np, (displayWidth, displayHeight))
        canvas = cv2.copyMakeBorder(image_np,
                                    0,
                                    extra_region,
                                    0,
                                    0,
                                    cv2.BORDER_CONSTANT,
                                    value=[0, 0, 0])
        if van_is_moving:
            cv2.putText(canvas, 'a van is moving', (int(
                0.1 * displayWidth), int(displayHeight + 0.7 * extra_region)),
                        fontFace, 2, (255, 255, 255), 2, 8)
        elif state == 0:
            # noVan confirmed
            # duration_displaying_loading_rate = int(10*fps)
            # counter_for_displaying = 0
            if counter_for_displaying < duration_displaying_loading_rate:
                # display
                cv2.putText(canvas, 'the van has departured',
                            (int(0.1 * displayWidth),
                             int(displayHeight + 0.3 * extra_region)),
                            fontFace, 1, (255, 255, 255), 2, 8)
                cv2.putText(
                    canvas,
                    u'loadingRate: %s, plateNumber: %s' % (loadingRate, plate),
                    (int(0.1 * displayWidth),
                     int(displayHeight + 0.8 * extra_region)), fontFace, 1,
                    (255, 255, 255), 2, 8)
                counter_for_displaying += 1
            else:
                # stop displaying
                # counter_for_displaying = 0
                pass
        elif state == 1:
            # van confirmed
            if counter_for_displaying < duration_displaying_loading_rate:
                # display
                cv2.putText(canvas, 'the van is in dock',
                            (int(0.1 * displayWidth),
                             int(displayHeight + 0.3 * extra_region)),
                            fontFace, 1, (255, 255, 255), 2, 8)
                cv2.putText(
                    canvas,
                    u'loadingRate: %s, plateNumber: %s' % (loadingRate, plate),
                    (int(0.1 * displayWidth),
                     int(displayHeight + 0.8 * extra_region)), fontFace, 1,
                    (255, 255, 255), 2, 8)
                counter_for_displaying += 1
            else:
                # stop displaying
                # counter_for_displaying = 0
                pass
        outfile.write(canvas)
        #cv2.imshow('test', canvas)
        #if cv2.waitKey(1) == ord('q'):
        #break

    cap.release()
    outfile.release()
    alpr.unload()
    cv2.destroyAllWindows()