Skip to content
This repository was archived by the owner on Apr 8, 2025. It is now read-only.
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
212 changes: 140 additions & 72 deletions Autonomous/YOLO/darknet/darknet_images.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,50 +6,83 @@
import time
import cv2
import numpy as np
import darknet


def parser():
parser = argparse.ArgumentParser(description="YOLO Object Detection")
parser.add_argument("--input", type=str, default="",
help="image source. It can be a single image, a"
"txt with paths to them, or a folder. Image valid"
" formats are jpg, jpeg or png."
"If no input is given, ")
parser.add_argument("--batch_size", default=1, type=int,
help="number of images to be processed at the same time")
parser.add_argument("--weights", default="yolov4.weights",
help="yolo weights path")
parser.add_argument("--dont_show", action='store_true',
help="windown inference display. For headless systems")
parser.add_argument("--ext_output", action='store_true',
help="display bbox coordinates of detected objects")
parser.add_argument("--save_labels", action='store_true',
help="save detections bbox for each image in yolo format")
parser.add_argument("--config_file", default="./cfg/yolov4.cfg",
help="path to config file")
parser.add_argument("--data_file", default="./cfg/coco.data",
help="path to data file")
parser.add_argument("--thresh", type=float, default=.25,
help="remove detections with lower confidence")
parser.add_argument(
"--input",
type=str,
default="",
help="image source. It can be a single image, a"
"txt with paths to them, or a folder. Image valid"
" formats are jpg, jpeg or png."
"If no input is given, ",
)
parser.add_argument(
"--batch_size",
default=1,
type=int,
help="number of images to be processed at the same time",
)
parser.add_argument("--weights", default="yolov4.weights", help="yolo weights path")
parser.add_argument(
"--dont_show",
action="store_true",
help="windown inference display. For headless systems",
)
parser.add_argument(
"--ext_output",
action="store_true",
help="display bbox coordinates of detected objects",
)
parser.add_argument(
"--save_labels",
action="store_true",
help="save detections bbox for each image in yolo format",
)
parser.add_argument(
"--config_file", default="./cfg/yolov4.cfg", help="path to config file"
)
parser.add_argument(
"--data_file", default="./cfg/coco.data", help="path to data file"
)
parser.add_argument(
"--thresh",
type=float,
default=0.25,
help="remove detections with lower confidence",
)
return parser.parse_args()


def check_arguments_errors(args):
assert 0 < args.thresh < 1, "Threshold should be a float between zero and one (non-inclusive)"
assert (
0 < args.thresh < 1
), "Threshold should be a float between zero and one (non-inclusive)"
if not os.path.exists(args.config_file):
raise(ValueError("Invalid config path {}".format(os.path.abspath(args.config_file))))
raise (
ValueError(
"Invalid config path {}".format(os.path.abspath(args.config_file))
)
)
if not os.path.exists(args.weights):
raise(ValueError("Invalid weight path {}".format(os.path.abspath(args.weights))))
raise (
ValueError("Invalid weight path {}".format(os.path.abspath(args.weights)))
)
if not os.path.exists(args.data_file):
raise(ValueError("Invalid data file path {}".format(os.path.abspath(args.data_file))))
raise (
ValueError(
"Invalid data file path {}".format(os.path.abspath(args.data_file))
)
)
if args.input and not os.path.exists(args.input):
raise(ValueError("Invalid image path {}".format(os.path.abspath(args.input))))
raise (ValueError("Invalid image path {}".format(os.path.abspath(args.input))))


def check_batch_shape(images, batch_size):
"""
Image sizes should be the same width and height
Image sizes should be the same width and height
"""
shapes = [image.shape for image in images]
if len(set(shapes)) > 1:
Expand All @@ -66,17 +99,18 @@ def load_images(images_path):
In other case, it's a folder, return a list with names of each
jpg, jpeg and png file
"""
input_path_extension = images_path.split('.')[-1]
if input_path_extension in ['jpg', 'jpeg', 'png']:
input_path_extension = images_path.split(".")[-1]
if input_path_extension in ["jpg", "jpeg", "png"]:
return [images_path]
elif input_path_extension == "txt":
with open(images_path, "r") as f:
return f.read().splitlines()
else:
return glob.glob(
os.path.join(images_path, "*.jpg")) + \
glob.glob(os.path.join(images_path, "*.png")) + \
glob.glob(os.path.join(images_path, "*.jpeg"))
return (
glob.glob(os.path.join(images_path, "*.jpg"))
+ glob.glob(os.path.join(images_path, "*.png"))
+ glob.glob(os.path.join(images_path, "*.jpeg"))
)


def prepare_batch(images, network, channels=3):
Expand All @@ -86,13 +120,14 @@ def prepare_batch(images, network, channels=3):
darknet_images = []
for image in images:
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
image_resized = cv2.resize(image_rgb, (width, height),
interpolation=cv2.INTER_LINEAR)
image_resized = cv2.resize(
image_rgb, (width, height), interpolation=cv2.INTER_LINEAR
)
custom_image = image_resized.transpose(2, 0, 1)
darknet_images.append(custom_image)

batch_array = np.concatenate(darknet_images, axis=0)
batch_array = np.ascontiguousarray(batch_array.flat, dtype=np.float32)/255.0
batch_array = np.ascontiguousarray(batch_array.flat, dtype=np.float32) / 255.0
darknet_images = batch_array.ctypes.data_as(darknet.POINTER(darknet.c_float))
return darknet.IMAGE(width, height, channels, darknet_images)

Expand All @@ -106,17 +141,21 @@ def image_detection(image_path, network, class_names, class_colors, thresh):

image = cv2.imread(image_path)
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
image_resized = cv2.resize(image_rgb, (width, height),
interpolation=cv2.INTER_LINEAR)
image_resized = cv2.resize(
image_rgb, (width, height), interpolation=cv2.INTER_LINEAR
)

darknet.copy_image_from_bytes(darknet_image, image_resized.tobytes())
detections = darknet.detect_image(network, class_names, darknet_image, thresh=thresh)
detections = darknet.detect_image(
network, class_names, darknet_image, thresh=thresh
)
darknet.free_image(darknet_image)
image = darknet.draw_boxes(detections, image_resized, class_colors)
return cv2.cvtColor(image, cv2.COLOR_BGR2RGB), detections

#The following two methods were actually created by SoRo
#This is the main function call that ARTracker needs

# The following two methods were actually created by SoRo
# This is the main function call that ARTracker needs
def simple_detection(image, network, class_names, thresh):
# Darknet doesn't accept numpy images.
# Create one with image we reuse for each detect
Expand All @@ -125,14 +164,18 @@ def simple_detection(image, network, class_names, thresh):
darknet_image = darknet.make_image(width, height, 3)

image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
image_resized = cv2.resize(image_rgb, (width, height),
interpolation=cv2.INTER_LINEAR)
image_resized = cv2.resize(
image_rgb, (width, height), interpolation=cv2.INTER_LINEAR
)

darknet.copy_image_from_bytes(darknet_image, image_resized.tobytes())
detections = darknet.detect_image(network, class_names, darknet_image, thresh=thresh)
detections = darknet.detect_image(
network, class_names, darknet_image, thresh=thresh
)
darknet.free_image(darknet_image)
return detections



def complex_detection(image, network, class_names, class_colors, thresh):
# Darknet doesn't accept numpy images.
# Create one with image we reuse for each detect
Expand All @@ -141,21 +184,43 @@ def complex_detection(image, network, class_names, class_colors, thresh):
darknet_image = darknet.make_image(width, height, 3)

image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
image_resized = cv2.resize(image_rgb, (width, height),
interpolation=cv2.INTER_LINEAR)
image_resized = cv2.resize(
image_rgb, (width, height), interpolation=cv2.INTER_LINEAR
)

darknet.copy_image_from_bytes(darknet_image, image_resized.tobytes())
detections = darknet.detect_image(network, class_names, darknet_image, thresh=thresh)
detections = darknet.detect_image(
network, class_names, darknet_image, thresh=thresh
)
darknet.free_image(darknet_image)
image = darknet.draw_boxes(detections, image_resized, class_colors)
return cv2.cvtColor(image, cv2.COLOR_BGR2RGB), detections

def batch_detection(network, images, class_names, class_colors,
thresh=0.25, hier_thresh=.5, nms=.45, batch_size=4):

def batch_detection(
network,
images,
class_names,
class_colors,
thresh=0.25,
hier_thresh=0.5,
nms=0.45,
batch_size=4,
):
image_height, image_width, _ = check_batch_shape(images, batch_size)
darknet_images = prepare_batch(images, network)
batch_detections = darknet.network_predict_batch(network, darknet_images, batch_size, image_width,
image_height, thresh, hier_thresh, None, 0, 0)
batch_detections = darknet.network_predict_batch(
network,
darknet_images,
batch_size,
image_width,
image_height,
thresh,
hier_thresh,
None,
0,
0,
)
batch_predictions = []
for idx in range(batch_size):
num = batch_detections[idx].num
Expand All @@ -173,8 +238,9 @@ def image_classification(image, network, class_names):
width = darknet.network_width(network)
height = darknet.network_height(network)
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
image_resized = cv2.resize(image_rgb, (width, height),
interpolation=cv2.INTER_LINEAR)
image_resized = cv2.resize(
image_rgb, (width, height), interpolation=cv2.INTER_LINEAR
)
darknet_image = darknet.make_image(width, height, 3)
darknet.copy_image_from_bytes(darknet_image, image_resized.tobytes())
detections = darknet.predict_image(network, darknet_image)
Expand All @@ -189,7 +255,7 @@ def convert2relative(image, bbox):
"""
x, y, w, h = bbox
height, width, _ = image.shape
return x/width, y/height, w/width, h/height
return x / width, y / height, w / width, h / height


def save_annotations(name, image, detections, class_names):
Expand All @@ -201,7 +267,11 @@ def save_annotations(name, image, detections, class_names):
for label, confidence, bbox in detections:
x, y, w, h = convert2relative(image, bbox)
label = class_names.index(label)
f.write("{} {:.4f} {:.4f} {:.4f} {:.4f} {:.4f}\n".format(label, x, y, w, h, float(confidence)))
f.write(
"{} {:.4f} {:.4f} {:.4f} {:.4f} {:.4f}\n".format(
label, x, y, w, h, float(confidence)
)
)


def batch_detection_example():
Expand All @@ -210,15 +280,16 @@ def batch_detection_example():
batch_size = 3
random.seed(3) # deterministic bbox colors
network, class_names, class_colors = darknet.load_network(
args.config_file,
args.data_file,
args.weights,
batch_size=batch_size
args.config_file, args.data_file, args.weights, batch_size=batch_size
)
image_names = ['data/horses.jpg', 'data/horses.jpg', 'data/eagle.jpg']
image_names = ["data/horses.jpg", "data/horses.jpg", "data/eagle.jpg"]
images = [cv2.imread(image) for image in image_names]
images, detections, = batch_detection(network, images, class_names,
class_colors, batch_size=batch_size)
(
images,
detections,
) = batch_detection(
network, images, class_names, class_colors, batch_size=batch_size
)
for name, image in zip(image_names, images):
cv2.imwrite(name.replace("data/", ""), image)
print(detections)
Expand All @@ -230,10 +301,7 @@ def main():

random.seed(3) # deterministic bbox colors
network, class_names, class_colors = darknet.load_network(
args.config_file,
args.data_file,
args.weights,
batch_size=args.batch_size
args.config_file, args.data_file, args.weights, batch_size=args.batch_size
)

images = load_images(args.input)
Expand All @@ -250,15 +318,15 @@ def main():
prev_time = time.time()
image, detections = image_detection(
image_name, network, class_names, class_colors, args.thresh
)
)
if args.save_labels:
save_annotations(image_name, image, detections, class_names)
darknet.print_detections(detections, args.ext_output)
fps = int(1/(time.time() - prev_time))
fps = int(1 / (time.time() - prev_time))
print("FPS: {}".format(fps))
if not args.dont_show:
cv2.imshow('Inference', image)
if cv2.waitKey() & 0xFF == ord('q'):
cv2.imshow("Inference", image)
if cv2.waitKey() & 0xFF == ord("q"):
break
index += 1

Expand Down
2 changes: 1 addition & 1 deletion Autonomous/config.ini
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ FOCAL_LENGTH=435
FOCAL_LENGTH30H=590
FOCAL_LENGTH30V=470
KNOWN_TAG_WIDTH=20
FORMAT=MJPG
FORMAT=MJPG # some fourcc format: https://web.archive.org/web/20210130070315/https://www.fourcc.org/codecs.php
FRAME_WIDTH=1280
FRAME_HEIGHT=720
MAIN_CAMERA=2.3
Expand Down
Loading