Skip to content

Commit

Permalink
add YOLOv3 support
Browse files Browse the repository at this point in the history
  • Loading branch information
Cartucho committed Sep 12, 2018
1 parent c81ec34 commit 030cf2c
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 87 deletions.
8 changes: 4 additions & 4 deletions extra/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@

- ### convert YOLO to our format:

1) Add class list to the file `class_list.txt`
2) Insert predicted objects files into **predicted/**
3) Insert images into **images/**
4) Run the python script: `python convert_pred_yolo.py`
After runnuning darknet on a list of images, e.g.: `darknet.exe detector test data/voc.data yolo-voc.cfg yolo-voc.weights -dont_show -ext_output < data/train.txt > result.txt`

1) Copy the file `result.txt` to the folder `extra/`
2) Run the python script: `python convert_pred_yolo.py`

- ### convert keras-yolo3 to our format:

Expand Down
119 changes: 36 additions & 83 deletions extra/convert_pred_yolo.py
Original file line number Diff line number Diff line change
@@ -1,83 +1,36 @@
import sys
import os
import glob
import cv2


def convert_yolo_coordinates_to_voc(x_c_n, y_c_n, width_n, height_n, img_width, img_height):
## remove normalization given the size of the image
x_c = float(x_c_n) * img_width
y_c = float(y_c_n) * img_height
width = float(width_n) * img_width
height = float(height_n) * img_height
## compute half width and half height
half_width = width / 2
half_height = height / 2
## compute left, top, right, bottom
## in the official VOC challenge the top-left pixel in the image has coordinates (1;1)
left = int(x_c - half_width) + 1
top = int(y_c - half_height) + 1
right = int(x_c + half_width) + 1
bottom = int(y_c + half_height) + 1
return left, top, right, bottom

# read the class_list.txt to a list
with open("class_list.txt") as f:
obj_list = f.readlines()
## remove whitespace characters like `\n` at the end of each line
obj_list = [x.strip() for x in obj_list]
## e.g. first object in the list
#print(obj_list[0])

# change directory to the one with the files to be changed
path_to_folder = '../predicted'
#print(path_to_folder)
os.chdir(path_to_folder)

# old files (YOLO format) will be moved to a new folder (backup/)
## create the backup dir if it doesn't exist already
if not os.path.exists("backup"):
os.makedirs("backup")

# create VOC format files
txt_list = glob.glob('*.txt')
if len(txt_list) == 0:
print("Error: no .txt files found in predicted")
sys.exit()
for tmp_file in txt_list:
#print(tmp_file)
# 1. check that there is an image with that name
## get name before ".txt"
image_name = tmp_file.split(".txt",1)[0]
#print(image_name)
## check if image exists
for fname in os.listdir('../images'):
if fname.startswith(image_name):
## image found
#print(fname)
img = cv2.imread('../images/' + fname)
## get image width and height
img_height, img_width = img.shape[:2]
break
else:
## image not found
print("Error: image not found, corresponding to " + tmp_file)
sys.exit()
# 2. open txt file lines to a list
with open(tmp_file) as f:
content = f.readlines()
## remove whitespace characters like `\n` at the end of each line
content = [x.strip() for x in content]
# 3. move old file (YOLO format) to backup
os.rename(tmp_file, "backup/" + tmp_file)
# 4. create new file (VOC format)
with open(tmp_file, "a") as new_f:
for line in content:
## split a line by spaces.
## "c" stands for center and "n" stands for normalized
obj_id, conf, x_c_n, y_c_n, width_n, height_n = line.split()
obj_name = obj_list[int(obj_id)]
left, top, right, bottom = convert_yolo_coordinates_to_voc(x_c_n, y_c_n, width_n, height_n, img_width, img_height)
#print(obj_name + " " + str(conf) + " " + str(left) + " " + str(top) + " " + str(right) + " " + str(bottom))
new_f.write(obj_name + " " + str(conf) + " " + str(left) + " " + str(top) + " " + str(right) + " " + str(bottom) + '\n')
print("Conversion completed!")
import os
import re

IN_FILE = 'result.txt'
OUTPUT_DIR = os.path.join('..', 'predicted')

SEPARATOR_KEY = 'Enter Image Path:'
IMG_FORMAT = '.jpg'

outfile = None
with open(IN_FILE) as infile:
for line in infile:
if SEPARATOR_KEY in line:
if IMG_FORMAT not in line:
break
# get text between two substrings (SEPARATOR_KEY and IMG_FORMAT)
image_path = re.search(SEPARATOR_KEY + '(.*)' + IMG_FORMAT, line)
# get the image name (the final component of a image_path)
# e.g., from 'data/horses_1' to 'horses_1'
image_name = os.path.basename(image_path.group(1))
# close the previous file
if outfile is not None:
outfile.close()
# open a new file
outfile = open(os.path.join(OUTPUT_DIR, image_name + '.txt'), 'w')
elif outfile is not None:
# split line on first occurrence of the character ':' and '%'
class_name, info = line.split(':', 1)
confidence, bbox = info.split('%', 1)
# get all the coordinates of the bounding box
bbox = bbox.replace(')','') # remove the character ')'
# go through each of the parts of the string and check if it is a digit
left, top, width, height = [int(s) for s in bbox.split() if s.isdigit()]
right = left + width
bottom = top + height
outfile.write("{} {} {} {} {} {}\n".format(class_name, float(confidence)/100, left, top, right, bottom))
13 changes: 13 additions & 0 deletions extra/result.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Total BFLOPS 65.864

seen 64
Enter Image Path: data/horses.jpg: Predicted in 42.076185 seconds.
horse: 88% (left_x: 3 top_y: 185 width: 150 height: 167)
horse: 99% (left_x: 5 top_y: 198 width: 307 height: 214)
horse: 96% (left_x: 236 top_y: 180 width: 215 height: 169)
horse: 99% (left_x: 440 top_y: 209 width: 156 height: 142)
Enter Image Path: data/person.jpg: Predicted in 41.767213 seconds.
dog: 99% (left_x: 58 top_y: 262 width: 147 height: 89)
person: 100% (left_x: 190 top_y: 95 width: 86 height: 284)
horse: 100% (left_x: 394 top_y: 137 width: 215 height: 206)
Enter Image Path:

0 comments on commit 030cf2c

Please sign in to comment.