|
| 1 | +""" |
| 2 | +Python script to obtain IOU (aslo know as Jaccard index) for Tensorflow object detection. |
| 3 | +For defination of IOU, please see: https://en.wikipedia.org/wiki/Jaccard_index. |
| 4 | +Note: |
| 5 | +The bbox from Label Maker is organized as [xmin, ymin, xmax, ymax], |
| 6 | +but the bbox predection from TensorFlow Object Detection is [ymin, xmin, ymax, xmax], and it was |
| 7 | +normalized by the image size. For more, see: |
| 8 | +https://www.tensorflow.org/versions/r0.12/api_docs/python/image/working_with_bounding_boxes |
| 9 | +
|
| 10 | +Usage: |
| 11 | + python tf_iou.py --model_name=building_od_ssd \ |
| 12 | + --path_to_label=data/building_od.pbtxt\ |
| 13 | + --test_image_path=test_test |
| 14 | +""" |
| 15 | + |
| 16 | +import os |
| 17 | +from os import makedirs, path as op |
| 18 | +import sys |
| 19 | +import glob |
| 20 | +import six.moves.urllib as urllib |
| 21 | +import tensorflow as tf |
| 22 | +import tarfile |
| 23 | +import pandas as pd |
| 24 | + |
| 25 | +import numpy as np |
| 26 | +from collections import defaultdict |
| 27 | +from PIL import Image |
| 28 | + |
| 29 | +sys.path.append("..") |
| 30 | + |
| 31 | +from utils import label_map_util |
| 32 | + |
| 33 | +flags = tf.app.flags |
| 34 | +flags.DEFINE_string('model_name', '', 'Path to frozen detection graph') |
| 35 | +flags.DEFINE_string('path_to_label', '', 'Path to label file') |
| 36 | +flags.DEFINE_string('test_image_path', '', 'Path to test imgs and output diractory') |
| 37 | +FLAGS = flags.FLAGS |
| 38 | + |
| 39 | +def load_image_into_numpy_array(image): |
| 40 | + (im_width, im_height) = image.size |
| 41 | + return np.array(image.getdata()).reshape((im_height, im_width, 3)).astype(np.uint8) |
| 42 | + |
| 43 | +def bb_IOU(boxA, boxB): |
| 44 | + xA = max(boxA[0], boxB[0]) |
| 45 | + yA = max(boxA[1], boxB[1]) |
| 46 | + xB = min(boxA[2], boxB[2]) |
| 47 | + yB = min(boxA[3], boxB[3]) |
| 48 | + # compute the area of intersection rectangle |
| 49 | + interArea = max(0,(xB - xA + 1)) * max(0,(yB - yA + 1)) |
| 50 | + # compute the area of both the prediction and ground-truthrectangles |
| 51 | + boxAArea = (boxA[2] - boxA[0] + 1) * (boxA[3] - boxA[1] + 1) |
| 52 | + boxBArea = (boxB[2] - boxB[0] + 1) * (boxB[3] - boxB[1] + 1) |
| 53 | + iou = interArea / float(boxAArea + boxBArea - interArea) |
| 54 | + return iou |
| 55 | + |
| 56 | +def pred_bbox(): |
| 57 | + pred_bboxes = list() |
| 58 | + with detection_graph.as_default(): |
| 59 | + with tf.Session(graph=detection_graph) as sess: |
| 60 | + # Definite input and output Tensors for detection_graph |
| 61 | + image_tensor = detection_graph.get_tensor_by_name('image_tensor:0') |
| 62 | + # Each box represents a part of the image where a particular object was detected. |
| 63 | + detection_boxes = detection_graph.get_tensor_by_name('detection_boxes:0') |
| 64 | + # Each score represent how level of confidence for each of the objects. |
| 65 | + # Score is shown on the result image, together with the class label. |
| 66 | + detection_scores = detection_graph.get_tensor_by_name('detection_scores:0') |
| 67 | + detection_classes = detection_graph.get_tensor_by_name('detection_classes:0') |
| 68 | + num_detections = detection_graph.get_tensor_by_name('num_detections:0') |
| 69 | + for image_path in test_imgs: |
| 70 | + image = Image.open(image_path) |
| 71 | + image_np = load_image_into_numpy_array(image) |
| 72 | + # the array based representation of the image will be used later in order to prepare the |
| 73 | + # result image with boxes and labels on it. |
| 74 | + # Expand dimensions since the model expects images to have shape: [1, None, None, 3] |
| 75 | + image_np_expanded = np.expand_dims(image_np, axis=0) |
| 76 | + # Actual detection. |
| 77 | + (boxes, scores, classes, num) = sess.run( |
| 78 | + [detection_boxes, detection_scores, detection_classes, num_detections], |
| 79 | + feed_dict={image_tensor: image_np_expanded}) |
| 80 | + ### 256 here is the image size from Label Maker, ajust it according to your input image size. |
| 81 | + bboxe = (boxes*256).astype(np.int) |
| 82 | + bboxe = np.squeeze(bboxe) |
| 83 | + score = np.squeeze(((scores*100).transpose()).astype(np.int)) |
| 84 | + ### only keep the bbox that prediction score is higher than 50. |
| 85 | + bboxes = bboxe[score > 50] |
| 86 | + if bboxes.any(): |
| 87 | + bboxes_ls = bboxes.tolist() |
| 88 | + for bbox in bboxes_ls: |
| 89 | + # pred_bboxes.append([image_path[-18:],bbox]) |
| 90 | + pred_bboxes.append(bbox) |
| 91 | + return pred_bboxes |
| 92 | + |
| 93 | +def gr_bbox(): |
| 94 | + gr_data = np.load("labels.npz") |
| 95 | + tile_names = [tile for tile in gr_data.files] |
| 96 | + tiles = np.array(tile_names) |
| 97 | + |
| 98 | + gr_bboxes = list() |
| 99 | + for tile in tiles: |
| 100 | + bboxes = gr_data[tile].tolist() |
| 101 | + bbox_info = list() |
| 102 | + if bboxes: |
| 103 | + for bbox in bboxes: |
| 104 | + bbox = [max(0, min(255, x)) for x in bbox[:4]] |
| 105 | + # switching bbox from [xmin, ymin, xmax, ymax] to [ymin, xmin, ymax, xmax] |
| 106 | + bbox = [bbox[1], bbox[0], bbox[3], bbox[2]] |
| 107 | + gr_bboxes.append(bbox) |
| 108 | + return gr_bboxes |
| 109 | + |
| 110 | +def get_iou(): |
| 111 | + pred_bboxes = pred_bbox() |
| 112 | + gr_bboxes = gr_bbox() |
| 113 | + iou_out = list() |
| 114 | + for pred_box in pred_bboxes: |
| 115 | + for gr_box in gr_bboxes: |
| 116 | + try: |
| 117 | + iou = bb_IOU(pred_box, gr_box) |
| 118 | + ### If iou is large than 0.5, we assume this prediction is acceptable. |
| 119 | + if iou >=0.5: |
| 120 | + iou_out.append(iou) |
| 121 | + except: |
| 122 | + pass |
| 123 | + return iou_out |
| 124 | + |
| 125 | +if __name__ =='__main__': |
| 126 | + model_name = op.join(os.getcwd(), FLAGS.model_name) |
| 127 | + # Path to frozen detection graph. |
| 128 | + path_to_ckpt = op.join(model_name, 'frozen_inference_graph.pb') |
| 129 | + # Path to the label file |
| 130 | + path_to_label = op.join(os.getcwd(), FLAGS.path_to_label) |
| 131 | + #only train on buildings |
| 132 | + num_classes = 1 |
| 133 | + #Directory to test images path |
| 134 | + test_image_path = op.join(os.getcwd(), FLAGS.test_image_path) |
| 135 | + test_imgs = glob.glob(test_image_path + "/*.jpg") |
| 136 | + |
| 137 | + detection_graph = tf.Graph() |
| 138 | + with detection_graph.as_default(): |
| 139 | + od_graph_def = tf.GraphDef() |
| 140 | + with tf.gfile.GFile(path_to_ckpt, 'rb') as fid: |
| 141 | + serialized_graph = fid.read() |
| 142 | + od_graph_def.ParseFromString(serialized_graph) |
| 143 | + tf.import_graph_def(od_graph_def, name='') |
| 144 | + |
| 145 | + label_map = label_map_util.load_labelmap(path_to_label) |
| 146 | + categories = label_map_util.convert_label_map_to_categories(label_map, max_num_classes=num_classes, use_display_name=True) |
| 147 | + category_index = label_map_util.create_category_index(categories) |
| 148 | + iou_out = get_iou() |
| 149 | + pred_bboxes = pred_bbox() |
| 150 | + print("The IOU for your object detection is: {}".format(float(len(iou_out)/len(pred_bboxes)))) |
0 commit comments