def get_ground_truths_bbox(img_path, shpfile_path): allBoundingBoxes = BoundingBoxes() img_name = img_path.split("/")[-1][:-4] dataset = rasterio.open(img_path) polygons = gpd.read_file(shpfile_path) #bound of raster image tiff dataset_coords = [(dataset.bounds[0], dataset.bounds[1]), (dataset.bounds[2], dataset.bounds[1]), (dataset.bounds[2], dataset.bounds[3]), (dataset.bounds[0], dataset.bounds[3])] dataset_polygon = Polygon(dataset_coords) # import ipdb; ipdb.set_trace() df_bounds = polygons.bounds re = [ index for index, bbox in enumerate(df_bounds.values.tolist()) if bbox_is_in_img(bbox, dataset_polygon) ] for index in tqdm(re): # rowmax_colmax row_max, col_max = cvt_row_col(dataset, df_bounds, index, "max") row_min, col_min = cvt_row_col(dataset, df_bounds, index, "min") bb = BoundingBox(img_name, "tree", col_min, row_min, col_max, row_max, CoordinatesType.Absolute, None, BBType.GroundTruth, format=BBFormat.XYX2Y2) allBoundingBoxes.addBoundingBox(bb) return allBoundingBoxes
def __init__(self, anchors, size, detect_thresh: float = 0.3, nms_thresh: float = 0.3, images_per_batch: int = -1): self.anchors = anchors self.size = size self.detect_thresh = detect_thresh self.nms_thresh = nms_thresh # self.metric_names_original = 'Mitosis' self.metric_names = ['F1', 'F1-STN'] self.images_per_batch = images_per_batch self.evaluator = Evaluator() if (self.anchors.shape[-1] == 4): self.boundingObjects = BoundingBoxes() self.boundingObjectsSTN = BoundingBoxes() else: self.boundingObjects = BoundingCircles() self.boundingObjectsSTN = BoundingCircles()
def __init__(self, anchors, size, metric_names: list, detect_thresh: float = 0.3, nms_thresh: float = 0.3, images_per_batch: int = -1): self.ap = 'AP' self.anchors = anchors self.size = size self.detect_thresh = detect_thresh self.nms_thresh = nms_thresh self.images_per_batch = images_per_batch self.metric_names_original = metric_names self.metric_names = ["{}-{}".format(self.ap, i) for i in metric_names] self.evaluator = Evaluator() if (self.anchors.shape[-1] == 4): self.boundingObjects = BoundingBoxes() else: self.boundingObjects = BoundingCircles()
def calc_metrics(self, second_expert, iou_thresh: float = 0.25): boundingBoxes = BoundingBoxes() for image in self.images.values(): for bb in image.BB_Boxes: boundingBoxes.addBoundingBox(bb) for image in second_expert.images.values(): for bb in image.BB_Boxes: boundingBoxes.addBoundingBox(bb) evaluator = Evaluator() metricsPerClass = evaluator.GetPascalVOCMetrics( boundingBoxes, iou_thresh) return metricsPerClass
def getBoundingBoxes(): """Read txt files containing bounding boxes (ground truth and detections).""" allBoundingBoxes = BoundingBoxes() import glob import os # Read ground truths currentPath = os.path.dirname(os.path.abspath(__file__)) folderGT = os.path.join(currentPath, 'groundtruths') os.chdir(folderGT) files = glob.glob("*.txt") files.sort() # Class representing bounding boxes (ground truths and detections) allBoundingBoxes = BoundingBoxes() # Read GT detections from txt file # Each line of the files in the groundtruths folder represents a ground truth bounding box # (bounding boxes that a detector should detect) # Each value of each line is "class_id, x, y, width, height" respectively # Class_id represents the class of the bounding box # x, y represents the most top-left coordinates of the bounding box # x2, y2 represents the most bottom-right coordinates of the bounding box for f in files: nameOfImage = f.replace(".txt", "") fh1 = open(f, "r") for line in fh1: line = line.replace("\n", "") if line.replace(' ', '') == '': continue splitLine = line.split(" ") idClass = splitLine[0] # class x = float(splitLine[1]) # confidence y = float(splitLine[2]) w = float(splitLine[3]) h = float(splitLine[4]) bb = BoundingBox(nameOfImage, idClass, x, y, w, h, CoordinatesType.Absolute, (200, 200), BBType.GroundTruth, format=BBFormat.XYWH) allBoundingBoxes.addBoundingBox(bb) fh1.close() # Read detections folderDet = os.path.join(currentPath, 'detections') os.chdir(folderDet) files = glob.glob("*.txt") files.sort() # Read detections from txt file # Each line of the files in the detections folder represents a detected bounding box. # Each value of each line is "class_id, confidence, x, y, width, height" respectively # Class_id represents the class of the detected bounding box # Confidence represents confidence (from 0 to 1) that this detection belongs to the class_id. # x, y represents the most top-left coordinates of the bounding box # x2, y2 represents the most bottom-right coordinates of the bounding box for f in files: # nameOfImage = f.replace("_det.txt","") nameOfImage = f.replace(".txt", "") # Read detections from txt file fh1 = open(f, "r") for line in fh1: line = line.replace("\n", "") if line.replace(' ', '') == '': continue splitLine = line.split(" ") idClass = splitLine[0] # class confidence = float(splitLine[1]) # confidence x = float(splitLine[2]) y = float(splitLine[3]) w = float(splitLine[4]) h = float(splitLine[5]) bb = BoundingBox(nameOfImage, idClass, x, y, w, h, CoordinatesType.Absolute, (200, 200), BBType.Detected, confidence, format=BBFormat.XYWH) allBoundingBoxes.addBoundingBox(bb) fh1.close() return allBoundingBoxes
return pred_boxes, pred_class, pred_score if __name__ == "__main__": dataset_test = SatelliteDataset('validating_data/', get_transform(train=False)) data_loader_test = torch.utils.data.DataLoader(dataset_test, batch_size=1, shuffle=False, num_workers=4, collate_fn=utils.collate_fn) model = init_model() imgs = glob.glob(os.path.join('validating_data/', "*")) # rand_img = random.sample(imgs, 1) # import ipdb; ipdb.set_trace() myBoundingBoxes = BoundingBoxes() for idx in range(len(dataset_test)): img, target = dataset_test.__getitem__(idx) for i in range(len(target['boxes'])): gt_boundingBox = BoundingBox( imageName=target["img_name"], classId=CLASS_NAMES[target['labels'][i].item()], x=target['boxes'][i][0].item(), y=target['boxes'][i][1].item(), w=target['boxes'][i][2].item(), h=target['boxes'][i][3].item(), typeCoordinates=CoordinatesType.Absolute, bbType=BBType.GroundTruth, format=BBFormat.XYX2Y2) myBoundingBoxes.addBoundingBox(gt_boundingBox) image_path = glob.glob(
def getBoundingBoxes(directory, isGT, bbFormat, coordType, allBoundingBoxes=None, allClasses=None, imgSize=(0, 0)): """Read txt files containing bounding boxes (ground truth and detections).""" if allBoundingBoxes is None: allBoundingBoxes = BoundingBoxes() if allClasses is None: allClasses = [] # Read ground truths os.chdir(directory) files = glob.glob("*.txt") files.sort() # Read GT detections from txt file # Each line of the files in the groundtruths folder represents a ground truth bounding box # (bounding boxes that a detector should detect) # Each value of each line is "class_id, x, y, width, height" respectively # Class_id represents the class of the bounding box # x, y represents the most top-left coordinates of the bounding box # x2, y2 represents the most bottom-right coordinates of the bounding box for f in files: nameOfImage = f.replace(".txt", "") fh1 = open(f, "r") for line in fh1: line = line.replace("\n", "") if line.replace(' ', '') == '': continue splitLine = line.split(" ") if isGT: # idClass = int(splitLine[0]) #class idClass = (splitLine[0]) # class x = float(splitLine[1]) y = float(splitLine[2]) w = float(splitLine[3]) h = float(splitLine[4]) bb = BoundingBox(nameOfImage, idClass, x, y, w, h, coordType, imgSize, BBType.GroundTruth, format=bbFormat) else: # idClass = int(splitLine[0]) #class idClass = (splitLine[0]) # class confidence = float(splitLine[1]) x = float(splitLine[2]) y = float(splitLine[3]) w = float(splitLine[4]) h = float(splitLine[5]) bb = BoundingBox(nameOfImage, idClass, x, y, w, h, coordType, imgSize, BBType.Detected, confidence, format=bbFormat) allBoundingBoxes.addBoundingBox(bb) if idClass not in allClasses: allClasses.append(idClass) fh1.close() return allBoundingBoxes, allClasses
class MeanAveragePrecision: def __init__(self,category_index): self.allBoundingBoxes = BoundingBoxes() self.category_index = category_index def AddGroundTruth(self,row): #for row in groundTruthList: bb = BoundingBox( row.filename, row.classname, row.xmin, row.ymin, row.xmax, row.ymax, CoordinatesType.Absolute, (row.height, row.width), BBType.GroundTruth, format=BBFormat.XYX2Y2) self.allBoundingBoxes.addBoundingBox(bb) def AddDetectedVales(self,row,confidence): #for row in detectedValuesList: bb = BoundingBox( row.filename, row.classname, row.xmin, row.ymin, row.xmax, row.ymax, CoordinatesType.Absolute, (row.height, row.width), BBType.Detected, confidence, format=BBFormat.XYX2Y2) self.allBoundingBoxes.addBoundingBox(bb) def __call__(self,gtList,detections): detectionBoxes = detections['detection_boxes'][0].numpy() detectionClasses = (detections['detection_classes'][0].numpy() + 1).astype(int) #Adding one is mandatory detectionScores = detections['detection_scores'][0].numpy() detectionScores = list(filter(lambda x: x > 0.1, detectionScores)) for boxNormalised,classs,score in zip(detectionBoxes,detectionClasses,detectionScores): className = self.category_index[classs]["name"] groundTruthClass = list(filter(lambda x: x.classname == className, gtList)) iouList = [] box = [] for j in groundTruthClass: ymin = boxNormalised[0]*j.height xmin = boxNormalised[1]*j.width ymax = boxNormalised[2]*j.height xmax = boxNormalised[3]*j.width box = [xmin,ymin,xmax,ymax] iou = Evaluator.iou(box, [j.xmin,j.ymin,j.xmax,j.ymax]) iouList.append(iou) if(len(iouList) > 0): index, value = max(enumerate(iouList), key=operator.itemgetter(1)) gtTensor = groundTruthClass[index] else: continue #it is a case of true negative. hence ignored. #gtTensor = groundTruthClass[0] self.AddGroundTruth(gtTensor) self.AddDetectedVales(CustomTensors(gtTensor.filename,gtTensor.width,gtTensor.height,className,int(box[0]),int(box[1]),int(box[2]),int(box[3])),score) print("done") def CalculatemAP(self): evaluator = Evaluator() iouThresholds = [.25,.5,.75,.9] mAPTable = [] for iouThreshold in iouThresholds: metricsPerClass = evaluator.GetPascalVOCMetrics( self.allBoundingBoxes, # Object containing all bounding boxes (ground truths and detections) IOUThreshold=iouThreshold, # IOU threshold method=MethodAveragePrecision.EveryPointInterpolation) # As the official matlab code print("Average precision values per class:") # Loop through classes to obtain their metrics averagePrecision = [] for mc in metricsPerClass: # Get metric values per each class c = mc['class'] precision = mc['precision'] recall = mc['recall'] average_precision = mc['AP'] ipre = mc['interpolated precision'] irec = mc['interpolated recall'] # Print AP per class print('%s: %f' % (c, average_precision)) averagePrecision.append(average_precision) print("Mean Average Precision @"+ str(int(iouThreshold*100)) +" is:" + str(sum(averagePrecision)/len(averagePrecision))) mAPTable.append([int(iouThreshold*100),sum(averagePrecision)/len(averagePrecision)]) print(tabulate(mAPTable,headers=["IOU Threshold","Mean Average Precision"],tablefmt="fancy_grid"))
def __init__(self,category_index): self.allBoundingBoxes = BoundingBoxes() self.category_index = category_index
def getBoundingBoxes(directory, isGT, bbFormat, coordType, allBoundingBoxes=None, allClasses=None, imgSize=(0, 0)): """Read txt files containing bounding boxes (ground truth and detections).""" if allBoundingBoxes is None: allBoundingBoxes = BoundingBoxes() if allClasses is None: allClasses = [] # Read ground truths # files = [os.path.join(directory, f) for f in os.listdir(directory)] # files.sort() with open(directory, 'r', encoding="utf-8") as f: data_info = json.load(f) # Read GT detections from txt file # Each line of the files in the groundtruths folder represents a ground truth bounding box # (bounding boxes that a detector should detect) # Each value of each line is "class_id, x, y, width, height" respectively # Class_id represents the class of the bounding box # x, y represents the most top-left coordinates of the bounding box # x2, y2 represents the most bottom-right coordinates of the bounding box for f, v in data_info.items(): nameOfImage = str(f.split('/')[-1]).split('.')[0] # fh1 = open(f, "r") # for line in fh1: # line = line.replace("\n", "") # if line.replace(' ', '') == '': # continue # splitLine = line.split(" ") if isGT: # idClass = int(splitLine[0]) #class idClass = (v[0]) # class x = float(0) y = float(0) w = float(v[1]) h = float(v[2]) bb = BoundingBox(nameOfImage, idClass, x, y, w, h, coordType, imgSize, BBType.GroundTruth, format=bbFormat) else: # idClass = int(splitLine[0]) #class idClass = (v[0]) # class confidence = float(v[1]) x = float(0) y = float(0) w = float(v[2]) h = float(v[3]) bb = BoundingBox(nameOfImage, idClass, x, y, w, h, coordType, imgSize, BBType.Detected, confidence, format=bbFormat) allBoundingBoxes.addBoundingBox(bb) if idClass not in allClasses: allClasses.append(idClass) # fh1.close() return allBoundingBoxes, allClasses
def get_bboxes_and_classes(ground_truth_dir_path, prediction_dir_path, score_threshold, ios_threshold, iou_threshold): gt_dict = {} for file_path in glob.glob(os.path.join(ground_truth_dir_path, '*.txt')): image_name = os.path.splitext(os.path.basename(file_path))[0] gt_dict[image_name] = [] with open(file_path, 'r') as f: for line in f: obj_dict = {} class_name, sx, sy, ex, ey = line.split('\t') obj_dict['class_name'] = class_name obj_dict['bbox'] = [float(sx), float(sy), float(ex), float(ey)] gt_dict[image_name].append(obj_dict) predictions_dict = {} for file_path in glob.glob(os.path.join(prediction_dir_path, '*.txt')): image_name = os.path.splitext(os.path.basename(file_path))[0] predictions_dict[image_name] = [] with open(file_path, 'r') as f: for line in f: obj_dict = {} class_name, score, sx, sy, ex, ey = line.split('\t') obj_dict['class_name'] = class_name obj_dict['score'] = float(score) obj_dict['bbox'] = [float(sx), float(sy), float(ex), float(ey)] predictions_dict[image_name].append(obj_dict) allBoundingBoxes = BoundingBoxes() for img_filename, prediction in predictions_dict.items(): # BBox of groundTruth true_annotation = gt_dict[img_filename] for obj in true_annotation: bbox = obj["bbox"] class_name = obj['class_name'] bb = BoundingBox(img_filename, class_name, bbox[0], bbox[1], bbox[2], bbox[3], CoordinatesType.Absolute, None, BBType.GroundTruth, format=BBFormat.XYX2Y2) allBoundingBoxes.addBoundingBox(bb) # Non Maximum Suppression of predictions classes = [] boxes = [] scores = [] for obj in prediction: if obj["score"] >= score_threshold: classes.append(obj["class_name"]) boxes.append(obj["bbox"]) scores.append(obj["score"]) classes, boxes, scores = non_maximum_suppression( classes, boxes, scores, ios_threshold, iou_threshold) for class_name, bbox, score in zip(classes, boxes, scores): bb = BoundingBox(img_filename, class_name, bbox[0], bbox[1], bbox[2], bbox[3], CoordinatesType.Absolute, None, BBType.Detected, score, format=BBFormat.XYX2Y2) allBoundingBoxes.addBoundingBox(bb) return allBoundingBoxes