I am using darknet to detect objects with YOLOv4 on my custom made dataset. For this detection on videos I use:
./darknet detector demo data/obj.data yolo-obj.cfg yolo-obj_best.weights -ext_output video.mp4 -out-filename video_results.mp4
This gives my the video with the bounding boxes printed for every detection. However, I want to create a .txt (or .csv) file with for each frame number the prediction(s).
I did find this answer, but this gives the output in a json file and I need a .txt or .csv file. I am not so familiar with C so I find it hard to modify this answer into the format I need.
I followed the suggestion by Rafael and wrote a some code to move from JSON to cvs. I'll put it here in case anyone wants to use it. This is for the case in which a video was analyzed, so each "image" is a frame in a video.
import json
import csv
# with and height of the video
WIDTH = 1920
HEIGHT = 1080
with open('~/detection_results.json', encoding='latin-1') as json_file:
data = json.load(json_file)
# open csv file
csv_file_to_make = open('~/detection_results.csv', 'w', newline='\n')
csv_file = csv.writer(csv_file_to_make)
# write the header
# NB x and y values are relative
csv_file.writerow(['Frame ID',
'class',
'x_center',
'y_center',
'bb_width',
'bb_heigth',
'confidence'])
for frame in data:
frame_id = frame['frame_id']
instrument = ""
center_x = ""
center_y = ""
bb_width = ""
bb_height = ""
confidence = ""
if frame['objects'] == []:
csv_file.writerow([frame_id,
class,
center_x,
center_y,
bb_width,
bb_height,
confidence
])
else:
for single_detection in frame['objects']:
instrument = single_detection['name']
center_x = WIDTH*single_detection['relative_coordinates']['center_x']
center_y = HEIGHT*single_detection['relative_coordinates']['center_y']
bb_width = WIDTH*single_detection['relative_coordinates']['width']
bb_height = HEIGHT*single_detection['relative_coordinates']['height']
confidence = single_detection['confidence']
csv_file.writerow([frame_id,
class,
center_x,
center_y,
bb_width,
bb_height,
confidence
])
csv_file_to_make.close()
Hope this helps! If you see a solution to optimize this code that's also welcome of course :)