Skip to content

Commit

Permalink
improving code
Browse files Browse the repository at this point in the history
  • Loading branch information
Cartucho committed Mar 17, 2018
1 parent 0a760fd commit d90bd7a
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 23 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ In practice, a **higher mAP** value indicates a **better performance** of your n
## Explanation
The performance of your neural net will be judged using the mAP criterium defined in the [PASCAL VOC 2012 competition](http://host.robots.ox.ac.uk/pascal/VOC/voc2012/). We simply adapted the [official Matlab code](http://host.robots.ox.ac.uk/pascal/VOC/voc2012/#devkit) into Python (in our tests they both give the same results).

First (**1.**), we calculate the Average Precision (AP), for each of the classes present in the ground-truth. Then (**2.**), we calculate the mean of all the AP's, resulting in a mAP value.
First (**1.**), we calculate the Average Precision (AP), for each of the classes present in the ground-truth. Then (**2.**), we calculate the mean of all the AP's, resulting in an mAP value.

#### 1. Calculate AP for each Class

Expand Down Expand Up @@ -61,7 +61,7 @@ Step by step:

Optional (if you want to see the **animation**):

6. Insert the images in the folder **images/**
6. Insert the images into the folder **images/**


#### Create the ground-truth files
Expand Down
13 changes: 10 additions & 3 deletions extra/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
# Extra

### Convert YOLO to PASCAL VOC format:
## Ground-Truth:
- ### convert YOLO to PASCAL VOC format:

1) Add class list to the file `class_list.txt`
2) Run the python script and specify the path as an argument, e.g. `python convert_yolo_format_to_voc.py ../ground-truth`
1) Add class list to the file `class_list.txt`
2) Insert ground-truth files into **ground-truth/**
3) Insert images into **images/**
4) Run the python script: `python convert_yolo_format_to_voc.py`

## Find the files that contain a specific class of objects

1) Run the python script and specify the **class** and **path** as arguments, e.g. `python find_class.py chair ../ground-truth`
2 changes: 1 addition & 1 deletion extra/convert_yolo_format_to_voc.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#print(obj_list[0])

# change directory to the one with the files to be changed
path_to_folder = sys.argv[1]
path_to_folder = '../ground_truth'
#print(path_to_folder)
os.chdir(path_to_folder)

Expand Down
25 changes: 25 additions & 0 deletions extra/find_class.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import sys
import os
import glob

if len(sys.argv) != 3:
print("Error: wrong format.\nUsage: python find_class.py [class_name] [path]")
sys.exit(0)

searching_class_name = sys.argv[1]
path = sys.argv[2]

os.chdir(path)

# iterate through the text files
for txt_file in glob.glob('*.txt'):
# open txt file lines to a list
with open(txt_file) as f:
content = f.readlines()
# remove whitespace characters like `\n` at the end of each line
content = [x.strip() for x in content]
# go through each line of eache file
for line in content:
class_name = line.split()[0]
if class_name == searching_class_name:
print(txt_file)
60 changes: 43 additions & 17 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import os
import shutil
import operator
import sys
import argparse

parser = argparse.ArgumentParser()
Expand All @@ -17,15 +18,34 @@
group.add_argument('-fa', '--fast-animation', help="animation shown fast.", action="store_true")
args = parser.parse_args()

# if there are no classes to ignore then replace None by empty list
if args.ignore is None:
args.ignore = []

# if there are no images then no animation can be shown
img_path = 'images'
if os.path.exists(img_path):
for dirpath, dirnames, files in os.walk(img_path):
if not files:
# no image files found
args.no_animation = True
else:
args.no_animation = True

# try to import OpenCV if the user didn't choose the option --no-animation
if not args.no_animation:
import cv2
try:
import cv2
except ImportError:
args.no_animation = True

# try to import Matplotlib if the user didn't choose the option --no-plot
if not args.no_plot:
import matplotlib.pyplot as plt
import numpy as np
try:
import matplotlib.pyplot as plt
import numpy as np
except ImportError:
args.no_plot = True

MINOVERLAP = 0.5 # value defined in the PASCAL VOC2012 challenge

Expand Down Expand Up @@ -94,7 +114,7 @@ def file_lines_to_list(path):
"""
Ground-Truth
Load each of the ground-truth files into a temporary ".json" file.
Create a list with all the class names present in the ground-truth (unique_classes).
Create a list of all the class names present in the ground-truth (unique_classes).
"""
# get a list with the ground-truth files
ground_truth_files_list = glob.glob('ground-truth/*.txt')
Expand All @@ -104,10 +124,16 @@ def file_lines_to_list(path):
counter_per_class = {}
for txt_file in ground_truth_files_list:
#print(txt_file)
lines = file_lines_to_list(txt_file)
file_id = txt_file.split(".txt",1)[0]
file_id = file_id.split("/",1)[1]
# check if there is a correspondent predicted objects file
if not os.path.exists('predicted/' + file_id + ".txt"):
print("Error. File not found: predicted/" + file_id + ".txt")
sys.exit(0)
lines_list = file_lines_to_list(txt_file)
# create ground-truth dictionary
bounding_boxes = []
for line in lines:
for line in lines_list:
class_name, left, top, right, bottom = line.split()
# check if class is in the ignore list, if yes skip
if class_name in args.ignore:
Expand All @@ -122,8 +148,6 @@ def file_lines_to_list(path):
counter_per_class[class_name] = 1
unique_classes.add(class_name)
# dump bounding_boxes into a ".json" file
file_id = txt_file.split(".txt",1)[0]
file_id = file_id.split("/",1)[1]
with open(tmp_files_path + "/" + file_id + "_ground_truth.json", 'w') as outfile:
json.dump(bounding_boxes, outfile)

Expand Down Expand Up @@ -207,15 +231,17 @@ def file_lines_to_list(path):
fp = [0] * nd
for idx, prediction in enumerate(predictions_data):
file_id = prediction["file_id"]
# find ground truth image
ground_truth_img = glob.glob1("images", file_id + "*")
#tifCounter = len(glob.glob1(myPath,"*.tif"))
if len(ground_truth_img) == 0:
print("Error: unrecognized image " + file_id)
sys.exit(0)
elif len(ground_truth_img) > 1:
print("Error: multiple image " + file_id)
sys.exit(0)
# if show animation
if not args.no_animation:
# find ground truth image
ground_truth_img = glob.glob1(img_path, file_id + ".*")
#tifCounter = len(glob.glob1(myPath,"*.tif"))
if len(ground_truth_img) == 0:
print("Error. Image not found with id: " + file_id)
sys.exit(0)
elif len(ground_truth_img) > 1:
print("Error. Multiple image with id: " + file_id)
sys.exit(0)
# assign prediction to ground truth object if any
# open ground-truth with that file_id
gt_file = tmp_files_path + "/" + file_id + "_ground_truth.json"
Expand Down

0 comments on commit d90bd7a

Please sign in to comment.