diff --git a/.gitignore b/.gitignore index fb2d9db..2065c23 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,6 @@ .vscode/ .venv/ +.idea/ +__pycache__/ +.DS_Store +config.py \ No newline at end of file diff --git a/README.md b/README.md index b983104..bc7ae6d 100644 --- a/README.md +++ b/README.md @@ -48,15 +48,7 @@ Now, for the last step, make sure that you have `.venv` active using the command If the above runs without errors, you have installed things correctly. -#### Running the code on the Jetson Nano for detection - -To run the detection, use the commands: - -```bash -python yolo_object_detection.py -y model -``` - -This should pull up a screen with the live feed from the camera. +### Misc instructions if you have not compiled OpenCV yet #### OpenCV compile CMake @@ -78,3 +70,40 @@ cmake -D CMAKE_BUILD_TYPE=RELEASE \ -D OPENCV_ENABLE_NONFREE=ON \ -D OPENCV_EXTRA_MODULES_PATH=/home/`whoami`/opencv_contrib/modules .. ``` + + +#### Setup on the Jetson Nano board for Pixhawk + +we are using [DroneKit-Python API](https://dronekit-python.readthedocs.io/en/latest/about/overview.html) as an Onboard app between Jetson Nano and Pixhawk. + +Make sure your linux userid has the permission to use your tty port device + +connection port = `dev/ttyTHS1` + +Assume our userid is `user` +```bash +sudo usermod -a -G dialout user +``` +let's try running `testing.py` to get a brief introduction with `Dronekit` ( in `botmlcode/` directory ) + +```bash +python testing.py +``` +we are aware that we need to wait for around `10 seconds` or more to get the above's print statement be executed. At first, we though this was an issue( listed below ) +* Note ( 14th July, 2020): Optimise Pixhawk integration to the Jetson #5 [Track the issue here](https://github.com/clearbothk/botmlcode/issues/5) + +In `pixhawk.py` script, below is the line code to establish Dronekit connectivity to the connected device. it is recommended to set [wait_ready=True](https://dronekit-python.readthedocs.io/en/latest/guide/connecting_vehicle.html) to waits until some vehicle parameters and attributes are populated so that it is initialized successfully. + +```python +def __init__(self, connection_port="/dev/ttyTHS1", baud=57600): + try: + self.vehicle = connect(connection_port, wait_ready=True, baud=baud) + self.vehicle.mode = VehicleMode("MANUAL") + except serialutil.SerialException as e: + logging.error(e) +```` +Thus we need to first initialize the `dronekit.connect()` and make it as a constructor rather than repeatedly run the scripts so that we do not need to re run the script for everytime the [Dronekit attributes functions](https://dronekit-python.readthedocs.io/en/latest/guide/vehicle_state_and_parameters.html) + get called. + + + diff --git a/detector/__init__.py b/detector/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/detector/detector.py b/detector/detector.py new file mode 100644 index 0000000..cc5d850 --- /dev/null +++ b/detector/detector.py @@ -0,0 +1,123 @@ +import numpy as np +import cv2 +import os +import functools, operator + +import logging + + +class Detector: + weights_file = None + config_file = None + names_file = None + + confidence_threshold = 0 + nms_threshold = 0 + LABELS = [] + + net = None + ln = None + + def __init__(self, model_path="model", use_gpu=False, confidence_thres=0.5, nms_thres=0.3, + weights_file="clearbot.weights", config_file="clearbot.cfg", names_file="clearbot.names"): + + self.confidence_threshold = confidence_thres + self.nms_threshold = nms_thres + + self.weights_file = os.path.sep.join([os.path.dirname(os.path.realpath(__file__)), model_path, weights_file]) + self.config_file = os.path.sep.join([os.path.dirname(os.path.realpath(__file__)), model_path, config_file]) + self.names_file = os.path.sep.join([os.path.dirname(os.path.realpath(__file__)), model_path, names_file]) + logging.debug("Finished initialising model file paths") + + try: + self.LABELS = open(self.names_file).read().strip().split("\n") + logging.debug(f"Loaded labels from the names file: \n{self.LABELS}") + except Exception as e: + logging.error(e) + + try: + logging.debug("Loading Darknet model") + self.net = cv2.dnn.readNetFromDarknet(self.config_file, self.weights_file) + logging.debug("Finished loading Darknet model") + except Exception as e: + logging.error(e) + + if use_gpu: + logging.info("Will try to use GPU backend") + self.net.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA) + self.net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA) + else: + logging.info("Using CPU only") + + self.ln = self.net.getLayerNames() + + unconnected_layers = functools.reduce(operator.iconcat, self.net.getUnconnectedOutLayers(), []) + logging.debug(f"Indexes of unconnected layers: {unconnected_layers}") + self.ln = [self.ln[i - 1] for i in unconnected_layers] + logging.debug(f"Output layers for YOLO are: {self.ln}") + + def detect(self, frame): + """ + Detect the objects in the frame + :param frame: Frame that has been captured from the OpenCV video stream + :return: dict object with the objects and the bounding boxes + """ + (H, W) = frame.shape[:2] + blob = cv2.dnn.blobFromImage(frame, 1 / 255.0, (416, 416), swapRB=True, crop=False) + + self.net.setInput(blob) + layer_outputs = self.net.forward(self.ln) + + boxes = [] + confidences = [] + class_ids = [] + + for output in layer_outputs: + for detection in output: + scores = detection[5:] + class_id = np.argmax(scores) + confidence = scores[class_id] + + if confidence > self.confidence_threshold: + box = detection[0:4] * np.array([W, H, W, H]) + (centerX, centerY, width, height) = box.astype("int") + + x = int(centerX - (width / 2)) + y = int(centerY - (width / 2)) + + # Adding int(width) and int(height) is really important for some reason. + # Removing it gives an error in NMSBoxes() call + # Shall figure out soon and write a justification here. + boxes.append([x, y, int(width), int(height)]) + confidences.append(float(confidence)) + class_ids.append(class_id) + + logging.debug((boxes, confidences, self.confidence_threshold, self.nms_threshold)) + indexes = cv2.dnn.NMSBoxes(boxes, confidences, self.confidence_threshold, self.nms_threshold) + logging.debug(f"Indexes: {indexes}") + if len(indexes) > 0: + indexes = indexes.flatten() + return map(lambda idx: self.detected_to_result(boxes[idx], confidences[idx], class_ids[idx]), indexes) + + def detected_to_result(self, box, confidence, class_id): + (x, y) = (box[0], box[1]) + (w, h) = (box[2], box[3]) + + label = self.LABELS[class_id] + + return { + "label": label, + "confidence": confidence, + "bbox": { + "x": x, + "y": y, + "width": w, + "height": h + } + } + + +if __name__ == "__main__": + logging.getLogger().setLevel(logging.DEBUG) + + detector = Detector() diff --git a/detector/model/clearbot-tiny.cfg b/detector/model/clearbot-tiny.cfg new file mode 100644 index 0000000..d352bf6 --- /dev/null +++ b/detector/model/clearbot-tiny.cfg @@ -0,0 +1,331 @@ +[net] +# Testing +#batch=1 +#subdivisions=1 +# Training +batch=64 +subdivisions=16 +width=608 +height=608 +channels=3 +momentum=0.9 +decay=0.0005 +angle=0 +saturation = 1.5 +exposure = 1.5 +hue=.1 + +learning_rate=0.00261 +burn_in=1000 +max_batches = 128000 +policy=steps +steps=102400,115200 +scales=.1,.1 + +[convolutional] +batch_normalize=1 +filters=32 +size=3 +stride=2 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=64 +size=3 +stride=2 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=64 +size=3 +stride=1 +pad=1 +activation=leaky + +[route] +layers=-1 +groups=2 +group_id=1 + +[convolutional] +batch_normalize=1 +filters=32 +size=3 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=32 +size=3 +stride=1 +pad=1 +activation=leaky + +[route] +layers = -1,-2 + +[convolutional] +batch_normalize=1 +filters=64 +size=1 +stride=1 +pad=1 +activation=leaky + +[route] +layers = -6,-1 + +[maxpool] +size=2 +stride=2 + +[convolutional] +batch_normalize=1 +filters=128 +size=3 +stride=1 +pad=1 +activation=leaky + +[route] +layers=-1 +groups=2 +group_id=1 + +[convolutional] +batch_normalize=1 +filters=64 +size=3 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=64 +size=3 +stride=1 +pad=1 +activation=leaky + +[route] +layers = -1,-2 + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[route] +layers = -6,-1 + +[maxpool] +size=2 +stride=2 + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[route] +layers=-1 +groups=2 +group_id=1 + +[convolutional] +batch_normalize=1 +filters=128 +size=3 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=128 +size=3 +stride=1 +pad=1 +activation=leaky + +[route] +layers = -1,-2 + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[route] +layers = -6,-1 + +[maxpool] +size=2 +stride=2 + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +################################## + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[convolutional] +size=1 +stride=1 +pad=1 +filters=207 +activation=linear + + + +[yolo] +mask = 6,7,8 +anchors = 11, 9, 32, 22, 48, 48, 107, 54, 63,105, 153,108, 159,239, 310,173, 368,362 +classes=64 +num=9 +jitter=.3 +scale_x_y = 1.05 +cls_normalizer=1.0 +iou_normalizer=0.07 +iou_loss=ciou +ignore_thresh = .7 +truth_thresh = 1 +random=0 +resize=1.5 +nms_kind=greedynms +beta_nms=0.6 + +[route] +layers = -4 + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[upsample] +stride=2 + +[route] +layers = -1, 23 + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[convolutional] +size=1 +stride=1 +pad=1 +filters=207 +activation=linear + +[yolo] +mask = 3,4,5 +anchors = 11, 9, 32, 22, 48, 48, 107, 54, 63,105, 153,108, 159,239, 310,173, 368,362 +classes=64 +num=9 +jitter=.3 +scale_x_y = 1.05 +cls_normalizer=1.0 +iou_normalizer=0.07 +iou_loss=ciou +ignore_thresh = .7 +truth_thresh = 1 +random=0 +resize=1.5 +nms_kind=greedynms +beta_nms=0.6 + + +[route] +layers = -3 + +[convolutional] +batch_normalize=1 +filters=64 +size=1 +stride=1 +pad=1 +activation=leaky + +[upsample] +stride=2 + +[route] +layers = -1, 15 + +[convolutional] +batch_normalize=1 +filters=128 +size=3 +stride=1 +pad=1 +activation=leaky + +[convolutional] +size=1 +stride=1 +pad=1 +filters=207 +activation=linear + +[yolo] +mask = 0,1,2 +anchors = 11, 9, 32, 22, 48, 48, 107, 54, 63,105, 153,108, 159,239, 310,173, 368,362 +classes=64 +num=9 +jitter=.3 +scale_x_y = 1.05 +cls_normalizer=1.0 +iou_normalizer=0.07 +iou_loss=ciou +ignore_thresh = .7 +truth_thresh = 1 +random=0 +resize=1.5 +nms_kind=greedynms +beta_nms=0.6 diff --git a/detector/model/clearbot-tiny.weights b/detector/model/clearbot-tiny.weights new file mode 100755 index 0000000..f627b9f --- /dev/null +++ b/detector/model/clearbot-tiny.weights @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:af301cbdbd919cd4e84839fdc49ab049d8a239cc08339f83e3277fdc59e790e6 +size 25163592 diff --git a/model/clearbot.cfg b/detector/model/clearbot.cfg similarity index 100% rename from model/clearbot.cfg rename to detector/model/clearbot.cfg diff --git a/detector/model/clearbot.names b/detector/model/clearbot.names new file mode 100644 index 0000000..4635999 --- /dev/null +++ b/detector/model/clearbot.names @@ -0,0 +1,64 @@ +Aerosol +Aluminium foil +Battery +Aluminium blister pack +Carded blister pack +Clear plastic bottle +Glass bottle +Other plastic bottle +Plastic bottle cap +Metal bottle cap +Broken glass +Drink can +Food Can +Corrugated carton +Drink carton +Egg carton +Meal carton +Other carton +Paper cup +Disposable plastic cup +Foam cup +Glass cup +Other plastic cup +Food waste +Plastic lid +Metal lid +Magazine paper +Tissues +Wrapping paper +Normal paper +Paper bag +Plastified paper bag +Pizza box +Garbage bag +Single-use carrier bag +Polypropylene bag +Produce bag +Cereal bag +Bread bag +Plastic film +Crisp packet +Other plastic wrapper +Retort pouch +Spread tub +Tupperware +Disposable food container +Foam food container +Other plastic container +Plastic glooves +Plastic utensils +Pop tab +Rope & strings +Scrap metal +Shoe +Six pack rings +Squeezable tube +Plastic straw +Paper straw +Styrofoam piece +Toilet tube +Unlabeled litter +Glass jar +Other plastic +Cigarette \ No newline at end of file diff --git a/model/clearbot.weights b/detector/model/clearbot.weights similarity index 100% rename from model/clearbot.weights rename to detector/model/clearbot.weights diff --git a/main.py b/main.py new file mode 100644 index 0000000..c6ce829 --- /dev/null +++ b/main.py @@ -0,0 +1,107 @@ +import argparse +import logging +import multiprocessing +from multiprocessing import Queue + +import cv2 +from imutils.video import FPS + +from detector import detector as dt +from report import report, thingspeak +from pixhawk import pixhawk as px + +reports_path = 'report/report_folder/reports.json' +q = Queue(maxsize=0) + + +def writeData(): + logging.info("Starting connection to Pixhawk") + try: + pixhawk = px.Pixhawk() + logging.info("Connected to Pixhawk") + except Exception as e: + return -1 + + while True: + while True: + if (q.empty == False): + logging.debug("Message queue is empty") + break + + yolo_data = q.get() + + # post to thingspeak.com + visualize = thingspeak.ThingSpeak(yolo_data, pixhawk) + visualize.send_to_thingspeak() + + # saved to reports.json + get_report = report.Report(yolo_data, pixhawk) + get_report.create_report() + get_report.print_report() + get_report.write_report(reports_path) + + +def main(params): + print("Yolo is starting") + + logging.info("accessing video stream...") + vs = cv2.VideoCapture(0) + detector = dt.Detector("model", use_gpu=True, weights_file="clearbot-tiny.weights", config_file="clearbot-tiny.cfg", confidence_thres=0.1) + fps = FPS().start() + + while True: + (grabbed, frame) = vs.read() + if not grabbed: + break + result = detector.detect(frame) + for box in result: + bbox = box["bbox"] + x = bbox["x"] + y = bbox["y"] + w = bbox["width"] + h = bbox["height"] + cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 2) + + logging.debug(result) + + for r in result: + q.put(r) + # This loop is iterating over all YOLO results + # TODO: Optimise this section so that each frame is sent only once. + + if params.video_out: + cv2.imshow("Clearbot", frame) + # If this is not there, frame will not actually show: I did not dig into the explanation + if cv2.waitKey(1) & 0xFF == ord('q'): + break + + fps.update() + + fps.stop() + logging.info("approx. FPS: {:.2f}".format(fps.fps())) + vs.release() + cv2.destroyAllWindows() + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Clearbot AI and PController") + parser.add_argument('-v', '--video_out', type=bool, default=False, help="Show the camera video output") + parser.add_argument('--debug', type=bool, default=False, help="Switch to debug mode") + args = parser.parse_args() + + # Added the logging package instead of printing data randomly + if args.debug: + logging.getLogger('root').setLevel(logging.DEBUG) + else: + logging.getLogger('root').setLevel(logging.INFO) + + # Set multiprocessing + p1 = multiprocessing.Process(target=main, args=(args,)) + p2 = multiprocessing.Process(target=writeData) + + # Start Multiprocessing + p1.start() + p2.start() + + p1.join() + p2.join() diff --git a/model/clearbot.names b/model/clearbot.names deleted file mode 100644 index d742f21..0000000 --- a/model/clearbot.names +++ /dev/null @@ -1,64 +0,0 @@ -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter -litter \ No newline at end of file diff --git a/pixhawk/__init__.py b/pixhawk/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/pixhawk/pixhawk.py b/pixhawk/pixhawk.py new file mode 100644 index 0000000..bc86a53 --- /dev/null +++ b/pixhawk/pixhawk.py @@ -0,0 +1,101 @@ +from dronekit import connect, VehicleMode +import logging +from serial import serialutil + + +class Pixhawk: + vehicle = None + + def __init__(self, connection_port="/dev/ttyTHS1", baud=57600): + try: + self.vehicle = connect(connection_port, wait_ready=True, baud=baud) + self.vehicle.mode = VehicleMode("MANUAL") + except serialutil.SerialException as e: + logging.error(e) + + def firmware_version(self): + return self.vehicle.version + + def vehicle_capabilities(self): + return self.vehicle.capabilities.ftp + + def do_capture_global_location(self): + return self.vehicle.location.global_frame + + def do_capture_relative_global_location(self): + return self.vehicle.location.global_relative_frame + + def do_capture_attitude(self): + return self.vehicle.attitude + + def do_capture_velocity(self): + return self.vehicle.velocity + + def do_capture_gps(self): + return self.vehicle.gps_0 + + def do_capture_ground_speed(self): + return self.vehicle.groundspeed + + def do_capture_air_speed(self): + return self.vehicle.airspeed + + def gimbal_status(self): + return self.vehicle.gimbal + + def battery_status(self): + return self.vehicle.battery + + def EKF_OK(self): + return self.vehicle.ekf_ok + + def last_heartbeat(self): + return self.vehicle.last_heartbeat + + def range_finder(self): + return self.vehicle.rangefinder + + def range_finder_distance(self): + return self.vehicle.rangefinder.distance + + def range_finder_voltage(self): + return self.vehicle.rangefinder.voltage + + def heading(self): + return self.vehicle.heading + + def vehicle_is_armable(self): + return self.vehicle.is_armable + + def system_status(self): + return self.vehicle.system_status.state + + def vehicle_mode_name(self): + return self.vehicle.mode.name + + def check_vehicle_armed(self): + return self.vehicle.armed + + def debug(self): + print('Autopilot Firmware version: %s' % self.vehicle.version) + print('Autopilot capabilities (supports ftp): %s' % self.vehicle.capabilities.ftp) + print('Global Location: %s' % self.vehicle.location.global_frame) + print('Global Location (relative altitude): %s' % self.vehicle.location.global_relative_frame) + print('Local Location: %s' % self.vehicle.location.local_frame) + print('Attitude: %s' % self.vehicle.attitude) + print('Velocity: %s' % self.vehicle.velocity) + print('GPS: %s' % self.vehicle.gps_0) + print('Groundspeed: %s' % self.vehicle.groundspeed) + print('Airspeed: %s' % self.vehicle.airspeed) + print('Gimbal status: %s' % self.vehicle.gimbal) + print('Battery: %s' % self.vehicle.battery) + print('EKF OK?: %s' % self.vehicle.ekf_ok) + print('Last Heartbeat: %s' % self.vehicle.last_heartbeat) + print('Rangefinder: %s' % self.vehicle.rangefinder) + print('Rangefinder distance: %s' % self.vehicle.rangefinder.distance) + print('Rangefinder voltage: %s' % self.vehicle.rangefinder.voltage) + print('Heading: %s' % self.vehicle.heading) + print('Is Armable?: %s' % self.vehicle.is_armable) + print('System status: %s' % self.vehicle.system_status.state) + print('Mode: %s' % self.vehicle.mode.name) + print('Armed: %s' % self.vehicle.armed) diff --git a/report/__init__.py b/report/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/report/report.py b/report/report.py new file mode 100644 index 0000000..59dd3a6 --- /dev/null +++ b/report/report.py @@ -0,0 +1,66 @@ +import json + + +class Report: + def __init__(self, yolo, pixhawk): + self.label = yolo["label"] + self.confidence = yolo["confidence"] + self.firmware_version = pixhawk.firmware_version() + self.vehicle_capabilities = pixhawk.vehicle_capabilities() + self.location = pixhawk.do_capture_global_location() + self.attitude = pixhawk.do_capture_attitude() + self.velocity = pixhawk.do_capture_velocity() + self.gps = pixhawk.do_capture_gps() + self.ground_speed = pixhawk.do_capture_ground_speed() + self.air_speed = pixhawk.do_capture_air_speed() + self.gimbal_status = pixhawk.gimbal_status() + self.battery_status = pixhawk.battery_status() + self.ekf_ok = pixhawk.EKF_OK() + self.last_heartbeat = pixhawk.last_heartbeat() + self.range_finder_distance = pixhawk.range_finder_distance() + self.range_finder_voltage = pixhawk.range_finder_voltage() + self.heading = pixhawk.heading() + self.vehicle_is_armable = pixhawk.vehicle_is_armable() + self.system_status = pixhawk.system_status() + self.vehicle_mode_name = pixhawk.vehicle_mode_name() + self.check_vehicle_armed = pixhawk.check_vehicle_armed() + self.report = {} + + def create_report(self): + self.report = { + "label": self.label, + "confidence": self.confidence, + "firmware_version": self.firmware_version, + "vehicle_capabilities": self.vehicle_capabilities, + "location": self.location, + "attitude": self.attitude, + "velocity": self.velocity, + "gps": self.gps, + "ground_speed": self.ground_speed, + "air_speed": self.air_speed, + "gimbal_status": self.gimbal_status, + "battery_status": self.battery_status, + "EKF_OK": self.ekf_ok, + "last_heartbeat": self.last_heartbeat, + "range_finder_distance": self.range_finder_distance, + "range_finder_voltage": self.range_finder_voltage, + "heading": self.heading, + "vehicle_is_armable": self.vehicle_is_armable, + "system_status": self.system_status, + "vehicle_mode_name": self.vehicle_mode_name, + "check_vehicle_armed": self.check_vehicle_armed + } + + def print_report(self): + print(self.report) + + def read_report_json(self, path): + with open(path, 'r') as f: + data = json.load(f) + return data + + def write_report(self, path): + currentJSONDump = self.read_report_json(path) + currentJSONDump.append(self.report) + with open(path, 'w') as file_stream: + json.dump(currentJSONDump, file_stream, indent=2, sort_keys=True) diff --git a/report/report_folder/reports.json b/report/report_folder/reports.json new file mode 100644 index 0000000..1719fc6 --- /dev/null +++ b/report/report_folder/reports.json @@ -0,0 +1,983 @@ +[ + { + "confidence": 97, + "label": "litter", + "location": "hello" + }, + { + "confidence": 97, + "label": "litter", + "location": "hello" + }, + { + "confidence": 97, + "label": "litter", + "location": "hello" + }, + { + "EKF_OK": false, + "air_speed": 0.0, + "attitude": "Attitude:pitch=0.01909925416111946,yaw=2.4231948852539062,roll=-0.4838428497314453", + "battery_status": "Battery:voltage=0.0,current=None,level=None", + "check_vehicle_armed": false, + "confidence": 0.5103110074996948, + "firmware_version": "APM:UnknownVehicleType11-4.0.0", + "gimbal_status": "Gimbal: pitch=0.0, roll=0.0, yaw=0.0", + "gps": "GPSInfo:fix=1,num_sat=0", + "ground_speed": 0.0, + "heading": 138, + "label": "Single-use carrier bag", + "last_heartbeat": 0.528749322999829, + "location": "LocationGlobal:lat=0.0,lon=0.0,alt=-2.06", + "range_finder_distance": "None", + "range_finder_voltage": "None", + "system_status": "CRITICAL", + "vehicle_capabilities": "True", + "vehicle_is_armable": false, + "vehicle_mode_name": "MANUAL", + "velocity": "[0.0, 0.0, 0.0]" + }, + { + "EKF_OK": false, + "air_speed": 0.0, + "attitude": "Attitude:pitch=0.008913249708712101,yaw=2.566417694091797,roll=-0.4564279317855835", + "battery_status": "Battery:voltage=0.0,current=None,level=None", + "check_vehicle_armed": false, + "confidence": 0.944784939289093, + "firmware_version": "APM:UnknownVehicleType11-4.0.0", + "gimbal_status": "Gimbal: pitch=0.0, roll=0.0, yaw=0.0", + "gps": "GPSInfo:fix=1,num_sat=0", + "ground_speed": 0.0, + "heading": 147, + "label": "Clear plastic bottle", + "last_heartbeat": 0.7555133850000857, + "location": "LocationGlobal:lat=0.0,lon=0.0,alt=-2.19", + "range_finder_distance": "None", + "range_finder_voltage": "None", + "system_status": "CRITICAL", + "vehicle_capabilities": "True", + "vehicle_is_armable": false, + "vehicle_mode_name": "MANUAL", + "velocity": "[0.0, 0.0, 0.0]" + }, + { + "EKF_OK": false, + "air_speed": 0.0, + "attitude": "Attitude:pitch=0.008600435219705105,yaw=2.637603759765625,roll=-0.468279629945755", + "battery_status": "Battery:voltage=0.0,current=None,level=None", + "check_vehicle_armed": false, + "confidence": 0.8287092447280884, + "firmware_version": "APM:UnknownVehicleType11-4.0.0", + "gimbal_status": "Gimbal: pitch=0.0, roll=0.0, yaw=0.0", + "gps": "GPSInfo:fix=1,num_sat=0", + "ground_speed": 0.0, + "heading": 151, + "label": "Clear plastic bottle", + "last_heartbeat": 0.7411906769993948, + "location": "LocationGlobal:lat=0.0,lon=0.0,alt=-1.88", + "range_finder_distance": "None", + "range_finder_voltage": "None", + "system_status": "CRITICAL", + "vehicle_capabilities": "True", + "vehicle_is_armable": false, + "vehicle_mode_name": "MANUAL", + "velocity": "[0.0, 0.0, 0.0]" + }, + { + "EKF_OK": false, + "air_speed": 0.0, + "attitude": "Attitude:pitch=0.002421633806079626,yaw=2.63266658782959,roll=-0.33760201930999756", + "battery_status": "Battery:voltage=0.0,current=None,level=None", + "check_vehicle_armed": false, + "confidence": 0.7057521343231201, + "firmware_version": "APM:UnknownVehicleType11-4.0.0", + "gimbal_status": "Gimbal: pitch=0.0, roll=0.0, yaw=0.0", + "gps": "GPSInfo:fix=1,num_sat=0", + "ground_speed": 0.0, + "heading": 150, + "label": "Single-use carrier bag", + "last_heartbeat": 0.45644921800067095, + "location": "LocationGlobal:lat=0.0,lon=0.0,alt=-1.71", + "range_finder_distance": "None", + "range_finder_voltage": "None", + "system_status": "CRITICAL", + "vehicle_capabilities": "True", + "vehicle_is_armable": false, + "vehicle_mode_name": "MANUAL", + "velocity": "[0.0, 0.0, 0.0]" + }, + { + "EKF_OK": false, + "air_speed": 0.0, + "attitude": "Attitude:pitch=0.0019324326422065496,yaw=2.634483814239502,roll=-0.3371628522872925", + "battery_status": "Battery:voltage=0.0,current=None,level=None", + "check_vehicle_armed": false, + "confidence": 0.6058073043823242, + "firmware_version": "APM:UnknownVehicleType11-4.0.0", + "gimbal_status": "Gimbal: pitch=0.0, roll=0.0, yaw=0.0", + "gps": "GPSInfo:fix=1,num_sat=0", + "ground_speed": 0.0, + "heading": 150, + "label": "Single-use carrier bag", + "last_heartbeat": 0.6393409370002701, + "location": "LocationGlobal:lat=0.0,lon=0.0,alt=-1.92", + "range_finder_distance": "None", + "range_finder_voltage": "None", + "system_status": "CRITICAL", + "vehicle_capabilities": "True", + "vehicle_is_armable": false, + "vehicle_mode_name": "MANUAL", + "velocity": "[0.0, 0.0, 0.0]" + }, + { + "EKF_OK": false, + "air_speed": 0.0, + "attitude": "Attitude:pitch=0.004327771253883839,yaw=2.628669261932373,roll=-0.3355568051338196", + "battery_status": "Battery:voltage=0.0,current=None,level=None", + "check_vehicle_armed": false, + "confidence": 0.6313447952270508, + "firmware_version": "APM:UnknownVehicleType11-4.0.0", + "gimbal_status": "Gimbal: pitch=0.0, roll=0.0, yaw=0.0", + "gps": "GPSInfo:fix=1,num_sat=0", + "ground_speed": 0.0, + "heading": 150, + "label": "Single-use carrier bag", + "last_heartbeat": 0.12869474000035552, + "location": "LocationGlobal:lat=0.0,lon=0.0,alt=-2.05", + "range_finder_distance": "None", + "range_finder_voltage": "None", + "system_status": "CRITICAL", + "vehicle_capabilities": "True", + "vehicle_is_armable": false, + "vehicle_mode_name": "MANUAL", + "velocity": "[0.0, 0.0, 0.0]" + }, + { + "EKF_OK": false, + "air_speed": 0.0, + "attitude": "Attitude:pitch=0.004637624602764845,yaw=2.655484676361084,roll=-0.38725385069847107", + "battery_status": "Battery:voltage=0.0,current=None,level=None", + "check_vehicle_armed": false, + "confidence": 0.5052488446235657, + "firmware_version": "APM:UnknownVehicleType11-4.0.0", + "gimbal_status": "Gimbal: pitch=0.0, roll=0.0, yaw=0.0", + "gps": "GPSInfo:fix=1,num_sat=0", + "ground_speed": 0.0, + "heading": 152, + "label": "Plastified paper bag", + "last_heartbeat": 0.8054212500001086, + "location": "LocationGlobal:lat=0.0,lon=0.0,alt=-2.3", + "range_finder_distance": "None", + "range_finder_voltage": "None", + "system_status": "CRITICAL", + "vehicle_capabilities": "True", + "vehicle_is_armable": false, + "vehicle_mode_name": "MANUAL", + "velocity": "[0.0, 0.0, 0.0]" + }, + { + "EKF_OK": false, + "air_speed": 0.0, + "attitude": "Attitude:pitch=0.004376034252345562,yaw=2.653416395187378,roll=-0.38649651408195496", + "battery_status": "Battery:voltage=0.0,current=None,level=None", + "check_vehicle_armed": false, + "confidence": 0.6701147556304932, + "firmware_version": "APM:UnknownVehicleType11-4.0.0", + "gimbal_status": "Gimbal: pitch=0.0, roll=0.0, yaw=0.0", + "gps": "GPSInfo:fix=1,num_sat=0", + "ground_speed": 0.0, + "heading": 152, + "label": "Plastified paper bag", + "last_heartbeat": 0.9475373960003708, + "location": "LocationGlobal:lat=0.0,lon=0.0,alt=-1.5", + "range_finder_distance": "None", + "range_finder_voltage": "None", + "system_status": "CRITICAL", + "vehicle_capabilities": "True", + "vehicle_is_armable": false, + "vehicle_mode_name": "MANUAL", + "velocity": "[0.0, 0.0, 0.0]" + }, + { + "EKF_OK": false, + "air_speed": 0.0, + "attitude": "Attitude:pitch=0.0039167385548353195,yaw=2.6539077758789062,roll=-0.38680440187454224", + "battery_status": "Battery:voltage=0.0,current=None,level=None", + "check_vehicle_armed": false, + "confidence": 0.8561442494392395, + "firmware_version": "APM:UnknownVehicleType11-4.0.0", + "gimbal_status": "Gimbal: pitch=0.0, roll=0.0, yaw=0.0", + "gps": "GPSInfo:fix=1,num_sat=0", + "ground_speed": 0.0, + "heading": 152, + "label": "Crisp packet", + "last_heartbeat": 0.689201406000393, + "location": "LocationGlobal:lat=0.0,lon=0.0,alt=-1.46", + "range_finder_distance": "None", + "range_finder_voltage": "None", + "system_status": "CRITICAL", + "vehicle_capabilities": "True", + "vehicle_is_armable": false, + "vehicle_mode_name": "MANUAL", + "velocity": "[0.0, 0.0, 0.0]" + }, + { + "EKF_OK": false, + "air_speed": 0.0, + "attitude": "Attitude:pitch=0.0024878692347556353,yaw=2.6573050022125244,roll=-0.3856864869594574", + "battery_status": "Battery:voltage=0.0,current=None,level=None", + "check_vehicle_armed": false, + "confidence": 0.674862802028656, + "firmware_version": "APM:UnknownVehicleType11-4.0.0", + "gimbal_status": "Gimbal: pitch=0.0, roll=0.0, yaw=0.0", + "gps": "GPSInfo:fix=1,num_sat=0", + "ground_speed": 0.0, + "heading": 152, + "label": "Tissues", + "last_heartbeat": 0.17121276000034413, + "location": "LocationGlobal:lat=0.0,lon=0.0,alt=-1.95", + "range_finder_distance": "None", + "range_finder_voltage": "None", + "system_status": "CRITICAL", + "vehicle_capabilities": "True", + "vehicle_is_armable": false, + "vehicle_mode_name": "MANUAL", + "velocity": "[0.0, 0.0, 0.0]" + }, + { + "EKF_OK": false, + "air_speed": 0.0, + "attitude": "Attitude:pitch=-0.07103683799505234,yaw=0.7741695046424866,roll=-0.41734689474105835", + "battery_status": "Battery:voltage=0.0,current=None,level=None", + "check_vehicle_armed": false, + "confidence": 0.5699434280395508, + "firmware_version": "APM:UnknownVehicleType11-4.0.0", + "gimbal_status": "Gimbal: pitch=0.0, roll=0.0, yaw=0.0", + "gps": "GPSInfo:fix=1,num_sat=0", + "ground_speed": 0.0, + "heading": 44, + "label": "Paper straw", + "last_heartbeat": 0.21931572999983473, + "location": "LocationGlobal:lat=0.0,lon=0.0,alt=-0.45", + "range_finder_distance": "None", + "range_finder_voltage": "None", + "system_status": "CRITICAL", + "vehicle_capabilities": "True", + "vehicle_is_armable": false, + "vehicle_mode_name": "MANUAL", + "velocity": "[0.0, 0.0, 0.0]" + }, + { + "EKF_OK": false, + "air_speed": 0.0, + "attitude": "Attitude:pitch=-0.069066122174263,yaw=0.7767916917800903,roll=-0.4175513684749603", + "battery_status": "Battery:voltage=0.0,current=None,level=None", + "check_vehicle_armed": false, + "confidence": 0.5248982310295105, + "firmware_version": "APM:UnknownVehicleType11-4.0.0", + "gimbal_status": "Gimbal: pitch=0.0, roll=0.0, yaw=0.0", + "gps": "GPSInfo:fix=1,num_sat=0", + "ground_speed": 0.0, + "heading": 44, + "label": "Glass bottle", + "last_heartbeat": 0.06126848900021287, + "location": "LocationGlobal:lat=0.0,lon=0.0,alt=-0.22", + "range_finder_distance": "None", + "range_finder_voltage": "None", + "system_status": "CRITICAL", + "vehicle_capabilities": "True", + "vehicle_is_armable": false, + "vehicle_mode_name": "MANUAL", + "velocity": "[0.0, 0.0, 0.0]" + }, + { + "EKF_OK": false, + "air_speed": 0.0, + "attitude": "Attitude:pitch=-0.07107638567686081,yaw=0.7734728455543518,roll=-0.4168369174003601", + "battery_status": "Battery:voltage=0.0,current=None,level=None", + "check_vehicle_armed": false, + "confidence": 0.7648918628692627, + "firmware_version": "APM:UnknownVehicleType11-4.0.0", + "gimbal_status": "Gimbal: pitch=0.0, roll=0.0, yaw=0.0", + "gps": "GPSInfo:fix=1,num_sat=0", + "ground_speed": 0.0, + "heading": 44, + "label": "Spread tub", + "last_heartbeat": 0.17502203099957114, + "location": "LocationGlobal:lat=0.0,lon=0.0,alt=-0.51", + "range_finder_distance": "None", + "range_finder_voltage": "None", + "system_status": "CRITICAL", + "vehicle_capabilities": "True", + "vehicle_is_armable": false, + "vehicle_mode_name": "MANUAL", + "velocity": "[0.0, 0.0, 0.0]" + }, + { + "EKF_OK": false, + "air_speed": 0.0, + "attitude": "Attitude:pitch=-0.06390124559402466,yaw=0.7821321487426758,roll=-0.42286205291748047", + "battery_status": "Battery:voltage=0.0,current=None,level=None", + "check_vehicle_armed": false, + "confidence": 0.516333818435669, + "firmware_version": "APM:UnknownVehicleType11-4.0.0", + "gimbal_status": "Gimbal: pitch=0.0, roll=0.0, yaw=0.0", + "gps": "GPSInfo:fix=1,num_sat=0", + "ground_speed": 0.0, + "heading": 44, + "label": "Squeezable tube", + "last_heartbeat": 0.17359416599902033, + "location": "LocationGlobal:lat=0.0,lon=0.0,alt=-0.36", + "range_finder_distance": "None", + "range_finder_voltage": "None", + "system_status": "CRITICAL", + "vehicle_capabilities": "True", + "vehicle_is_armable": false, + "vehicle_mode_name": "MANUAL", + "velocity": "[0.0, 0.0, 0.0]" + }, + { + "EKF_OK": false, + "air_speed": 0.0, + "attitude": "Attitude:pitch=-0.06786604225635529,yaw=0.8050878047943115,roll=-0.4275035560131073", + "battery_status": "Battery:voltage=0.0,current=None,level=None", + "check_vehicle_armed": false, + "confidence": 0.5929812788963318, + "firmware_version": "APM:UnknownVehicleType11-4.0.0", + "gimbal_status": "Gimbal: pitch=0.0, roll=0.0, yaw=0.0", + "gps": "GPSInfo:fix=1,num_sat=0", + "ground_speed": 0.0, + "heading": 46, + "label": "Broken glass", + "last_heartbeat": 0.29605604100106575, + "location": "LocationGlobal:lat=0.0,lon=0.0,alt=-0.33", + "range_finder_distance": "None", + "range_finder_voltage": "None", + "system_status": "CRITICAL", + "vehicle_capabilities": "True", + "vehicle_is_armable": false, + "vehicle_mode_name": "MANUAL", + "velocity": "[0.0, 0.0, 0.0]" + }, + { + "EKF_OK": false, + "air_speed": 0.0, + "attitude": "Attitude:pitch=-0.06688760966062546,yaw=0.8089165091514587,roll=-0.42657241225242615", + "battery_status": "Battery:voltage=0.0,current=None,level=None", + "check_vehicle_armed": false, + "confidence": 0.5623620748519897, + "firmware_version": "APM:UnknownVehicleType11-4.0.0", + "gimbal_status": "Gimbal: pitch=0.0, roll=0.0, yaw=0.0", + "gps": "GPSInfo:fix=1,num_sat=0", + "ground_speed": 0.0, + "heading": 46, + "label": "Egg carton", + "last_heartbeat": 0.1956399999999121, + "location": "LocationGlobal:lat=0.0,lon=0.0,alt=0.0", + "range_finder_distance": "None", + "range_finder_voltage": "None", + "system_status": "CRITICAL", + "vehicle_capabilities": "True", + "vehicle_is_armable": false, + "vehicle_mode_name": "MANUAL", + "velocity": "[0.0, 0.0, 0.0]" + }, + { + "EKF_OK": false, + "air_speed": 0.0, + "attitude": "Attitude:pitch=0.011720940470695496,yaw=-2.691927671432495,roll=0.02516011707484722", + "battery_status": "Battery:voltage=0.0,current=None,level=None", + "check_vehicle_armed": false, + "confidence": 0.6233267784118652, + "firmware_version": "APM:UnknownVehicleType11-4.0.0", + "gimbal_status": "Gimbal: pitch=0.0, roll=0.0, yaw=0.0", + "gps": "GPSInfo:fix=1,num_sat=0", + "ground_speed": 0.0, + "heading": 205, + "label": "Plastified paper bag", + "last_heartbeat": 0.4513490780000211, + "location": "LocationGlobal:lat=0.0,lon=0.0,alt=3.09", + "range_finder_distance": "None", + "range_finder_voltage": "None", + "system_status": "CRITICAL", + "vehicle_capabilities": "True", + "vehicle_is_armable": false, + "vehicle_mode_name": "HOLD", + "velocity": "[0.0, 0.0, 0.0]" + }, + { + "EKF_OK": false, + "air_speed": 0.0, + "attitude": "Attitude:pitch=0.017221353948116302,yaw=-2.6880340576171875,roll=0.02412303164601326", + "battery_status": "Battery:voltage=0.0,current=None,level=None", + "check_vehicle_armed": false, + "confidence": 0.8484107851982117, + "firmware_version": "APM:UnknownVehicleType11-4.0.0", + "gimbal_status": "Gimbal: pitch=0.0, roll=0.0, yaw=0.0", + "gps": "GPSInfo:fix=1,num_sat=0", + "ground_speed": 0.0, + "heading": 205, + "label": "Carded blister pack", + "last_heartbeat": 0.49970943899984377, + "location": "LocationGlobal:lat=0.0,lon=0.0,alt=2.59", + "range_finder_distance": "None", + "range_finder_voltage": "None", + "system_status": "CRITICAL", + "vehicle_capabilities": "True", + "vehicle_is_armable": false, + "vehicle_mode_name": "MANUAL", + "velocity": "[0.0, 0.0, 0.0]" + }, + { + "EKF_OK": false, + "air_speed": 0.0, + "attitude": "Attitude:pitch=0.017535418272018433,yaw=-2.682232141494751,roll=0.02506384253501892", + "battery_status": "Battery:voltage=0.0,current=None,level=None", + "check_vehicle_armed": false, + "confidence": 0.9025440812110901, + "firmware_version": "APM:UnknownVehicleType11-4.0.0", + "gimbal_status": "Gimbal: pitch=0.0, roll=0.0, yaw=0.0", + "gps": "GPSInfo:fix=1,num_sat=0", + "ground_speed": 0.0, + "heading": 206, + "label": "Carded blister pack", + "last_heartbeat": 0.9765662840000005, + "location": "LocationGlobal:lat=0.0,lon=0.0,alt=2.84", + "range_finder_distance": "None", + "range_finder_voltage": "None", + "system_status": "CRITICAL", + "vehicle_capabilities": "True", + "vehicle_is_armable": false, + "vehicle_mode_name": "MANUAL", + "velocity": "[0.0, 0.0, 0.0]" + }, + { + "EKF_OK": false, + "air_speed": 0.0, + "attitude": "Attitude:pitch=0.013507163152098656,yaw=-2.699464797973633,roll=0.032972127199172974", + "battery_status": "Battery:voltage=0.0,current=None,level=None", + "check_vehicle_armed": false, + "confidence": 0.7768799066543579, + "firmware_version": "APM:UnknownVehicleType11-4.0.0", + "gimbal_status": "Gimbal: pitch=0.0, roll=0.0, yaw=0.0", + "gps": "GPSInfo:fix=1,num_sat=0", + "ground_speed": 0.0, + "heading": 205, + "label": "Tissues", + "last_heartbeat": 0.07120154800009004, + "location": "LocationGlobal:lat=0.0,lon=0.0,alt=2.4", + "range_finder_distance": "None", + "range_finder_voltage": "None", + "system_status": "CRITICAL", + "vehicle_capabilities": "True", + "vehicle_is_armable": false, + "vehicle_mode_name": "MANUAL", + "velocity": "[0.0, 0.0, 0.0]" + }, + { + "EKF_OK": false, + "air_speed": 0.0, + "attitude": "Attitude:pitch=0.014546588063240051,yaw=-2.7026543617248535,roll=0.03452213481068611", + "battery_status": "Battery:voltage=0.0,current=None,level=None", + "check_vehicle_armed": false, + "confidence": 0.6090551018714905, + "firmware_version": "APM:UnknownVehicleType11-4.0.0", + "gimbal_status": "Gimbal: pitch=0.0, roll=0.0, yaw=0.0", + "gps": "GPSInfo:fix=1,num_sat=0", + "ground_speed": 0.0, + "heading": 205, + "label": "Plastic bottle cap", + "last_heartbeat": 0.08426600600000711, + "location": "LocationGlobal:lat=0.0,lon=0.0,alt=2.67", + "range_finder_distance": "None", + "range_finder_voltage": "None", + "system_status": "CRITICAL", + "vehicle_capabilities": "True", + "vehicle_is_armable": false, + "vehicle_mode_name": "MANUAL", + "velocity": "[0.0, 0.0, 0.0]" + }, + { + "EKF_OK": false, + "air_speed": 0.0, + "attitude": "Attitude:pitch=0.0023166825994849205,yaw=-2.7255067825317383,roll=0.04753636568784714", + "battery_status": "Battery:voltage=0.0,current=None,level=None", + "check_vehicle_armed": false, + "confidence": 0.7308673858642578, + "firmware_version": "APM:UnknownVehicleType11-4.0.0", + "gimbal_status": "Gimbal: pitch=0.0, roll=0.0, yaw=0.0", + "gps": "GPSInfo:fix=1,num_sat=0", + "ground_speed": 0.0, + "heading": 203, + "label": "Plastified paper bag", + "last_heartbeat": 0.9308011690000058, + "location": "LocationGlobal:lat=0.0,lon=0.0,alt=2.37", + "range_finder_distance": "None", + "range_finder_voltage": "None", + "system_status": "CRITICAL", + "vehicle_capabilities": "True", + "vehicle_is_armable": false, + "vehicle_mode_name": "MANUAL", + "velocity": "[0.0, 0.0, 0.0]" + }, + { + "EKF_OK": false, + "air_speed": 0.0, + "attitude": "Attitude:pitch=0.001522311009466648,yaw=-2.724100112915039,roll=0.04830246418714523", + "battery_status": "Battery:voltage=0.0,current=None,level=None", + "check_vehicle_armed": false, + "confidence": 0.639407217502594, + "firmware_version": "APM:UnknownVehicleType11-4.0.0", + "gimbal_status": "Gimbal: pitch=0.0, roll=0.0, yaw=0.0", + "gps": "GPSInfo:fix=1,num_sat=0", + "ground_speed": 0.0, + "heading": 203, + "label": "Plastified paper bag", + "last_heartbeat": 0.06578741799989984, + "location": "LocationGlobal:lat=0.0,lon=0.0,alt=1.97", + "range_finder_distance": "None", + "range_finder_voltage": "None", + "system_status": "CRITICAL", + "vehicle_capabilities": "True", + "vehicle_is_armable": false, + "vehicle_mode_name": "MANUAL", + "velocity": "[0.0, 0.0, 0.0]" + }, + { + "EKF_OK": false, + "air_speed": 0.0, + "attitude": "Attitude:pitch=-0.006178590003401041,yaw=-2.734241485595703,roll=0.05553458258509636", + "battery_status": "Battery:voltage=0.0,current=None,level=None", + "check_vehicle_armed": false, + "confidence": 0.545289933681488, + "firmware_version": "APM:UnknownVehicleType11-4.0.0", + "gimbal_status": "Gimbal: pitch=0.0, roll=0.0, yaw=0.0", + "gps": "GPSInfo:fix=1,num_sat=0", + "ground_speed": 0.0, + "heading": 203, + "label": "Tissues", + "last_heartbeat": 0.9213393700001689, + "location": "LocationGlobal:lat=0.0,lon=0.0,alt=2.8", + "range_finder_distance": "None", + "range_finder_voltage": "None", + "system_status": "CRITICAL", + "vehicle_capabilities": "True", + "vehicle_is_armable": false, + "vehicle_mode_name": "MANUAL", + "velocity": "[0.0, 0.0, 0.0]" + }, + { + "EKF_OK": false, + "air_speed": 0.0, + "attitude": "Attitude:pitch=0.09895947575569153,yaw=-2.8563711643218994,roll=-0.03333592042326927", + "battery_status": "Battery:voltage=0.0,current=None,level=None", + "check_vehicle_armed": false, + "confidence": 0.6184415221214294, + "firmware_version": "APM:UnknownVehicleType11-4.0.0", + "gimbal_status": "Gimbal: pitch=0.0, roll=0.0, yaw=0.0", + "gps": "GPSInfo:fix=1,num_sat=0", + "ground_speed": 0.0, + "heading": 196, + "label": "Broken glass", + "last_heartbeat": 0.9445924540000306, + "location": "LocationGlobal:lat=0.0,lon=0.0,alt=3.0", + "range_finder_distance": "None", + "range_finder_voltage": "None", + "system_status": "CRITICAL", + "vehicle_capabilities": "True", + "vehicle_is_armable": false, + "vehicle_mode_name": "MANUAL", + "velocity": "[0.0, 0.0, 0.0]" + }, + { + "EKF_OK": false, + "air_speed": 0.0, + "attitude": "Attitude:pitch=0.09880923479795456,yaw=-2.8584089279174805,roll=-0.03788881003856659", + "battery_status": "Battery:voltage=0.0,current=None,level=None", + "check_vehicle_armed": false, + "confidence": 0.5609496831893921, + "firmware_version": "APM:UnknownVehicleType11-4.0.0", + "gimbal_status": "Gimbal: pitch=0.0, roll=0.0, yaw=0.0", + "gps": "GPSInfo:fix=1,num_sat=0", + "ground_speed": 0.0, + "heading": 196, + "label": "Spread tub", + "last_heartbeat": 0.20779678500002774, + "location": "LocationGlobal:lat=0.0,lon=0.0,alt=3.25", + "range_finder_distance": "None", + "range_finder_voltage": "None", + "system_status": "CRITICAL", + "vehicle_capabilities": "True", + "vehicle_is_armable": false, + "vehicle_mode_name": "MANUAL", + "velocity": "[0.0, 0.0, 0.0]" + }, + { + "EKF_OK": false, + "air_speed": 0.0, + "attitude": "Attitude:pitch=0.09830862283706665,yaw=-2.857605218887329,roll=-0.03894437104463577", + "battery_status": "Battery:voltage=0.0,current=None,level=None", + "check_vehicle_armed": false, + "confidence": 0.5146123766899109, + "firmware_version": "APM:UnknownVehicleType11-4.0.0", + "gimbal_status": "Gimbal: pitch=0.0, roll=0.0, yaw=0.0", + "gps": "GPSInfo:fix=1,num_sat=0", + "ground_speed": 0.0, + "heading": 196, + "label": "Disposable plastic cup", + "last_heartbeat": 0.39948584700005085, + "location": "LocationGlobal:lat=0.0,lon=0.0,alt=3.28", + "range_finder_distance": "None", + "range_finder_voltage": "None", + "system_status": "CRITICAL", + "vehicle_capabilities": "True", + "vehicle_is_armable": false, + "vehicle_mode_name": "MANUAL", + "velocity": "[0.0, 0.0, 0.0]" + }, + { + "EKF_OK": false, + "air_speed": 0.0, + "attitude": "Attitude:pitch=0.08901780843734741,yaw=-2.879223346710205,roll=-0.03568514809012413", + "battery_status": "Battery:voltage=0.0,current=None,level=None", + "check_vehicle_armed": false, + "confidence": 0.6122862100601196, + "firmware_version": "APM:UnknownVehicleType11-4.0.0", + "gimbal_status": "Gimbal: pitch=0.0, roll=0.0, yaw=0.0", + "gps": "GPSInfo:fix=1,num_sat=0", + "ground_speed": 0.0, + "heading": 195, + "label": "Carded blister pack", + "last_heartbeat": 0.9131540979997226, + "location": "LocationGlobal:lat=0.0,lon=0.0,alt=4.38", + "range_finder_distance": "None", + "range_finder_voltage": "None", + "system_status": "CRITICAL", + "vehicle_capabilities": "True", + "vehicle_is_armable": false, + "vehicle_mode_name": "MANUAL", + "velocity": "[0.0, 0.0, 0.0]" + }, + { + "EKF_OK": false, + "air_speed": 0.0, + "attitude": "Attitude:pitch=0.11036232858896255,yaw=3.0507771968841553,roll=0.09607145190238953", + "battery_status": "Battery:voltage=0.0,current=None,level=None", + "check_vehicle_armed": false, + "confidence": 0.817825198173523, + "firmware_version": "APM:UnknownVehicleType11-4.0.0", + "gimbal_status": "Gimbal: pitch=0.0, roll=0.0, yaw=0.0", + "gps": "GPSInfo:fix=1,num_sat=0", + "ground_speed": 0.0, + "heading": 174, + "label": "Spread tub", + "last_heartbeat": 0.6851423230000364, + "location": "LocationGlobal:lat=0.0,lon=0.0,alt=4.18", + "range_finder_distance": "None", + "range_finder_voltage": "None", + "system_status": "CRITICAL", + "vehicle_capabilities": "True", + "vehicle_is_armable": false, + "vehicle_mode_name": "MANUAL", + "velocity": "[0.0, 0.0, 0.0]" + }, + { + "EKF_OK": false, + "air_speed": 0.0, + "attitude": "Attitude:pitch=0.031789928674697876,yaw=-2.52939772605896,roll=0.010927568189799786", + "battery_status": "Battery:voltage=0.0,current=None,level=None", + "check_vehicle_armed": false, + "confidence": 0.5057023167610168, + "firmware_version": "APM:UnknownVehicleType11-4.0.0", + "gimbal_status": "Gimbal: pitch=0.0, roll=0.0, yaw=0.0", + "gps": "GPSInfo:fix=1,num_sat=0", + "ground_speed": 0.0, + "heading": 215, + "label": "Crisp packet", + "last_heartbeat": 0.39529037799999855, + "location": "LocationGlobal:lat=0.0,lon=0.0,alt=4.95", + "range_finder_distance": "None", + "range_finder_voltage": "None", + "system_status": "CRITICAL", + "vehicle_capabilities": "True", + "vehicle_is_armable": false, + "vehicle_mode_name": "MANUAL", + "velocity": "[0.0, 0.0, 0.0]" + }, + { + "EKF_OK": false, + "air_speed": 0.0, + "attitude": "Attitude:pitch=0.030726207420229912,yaw=-2.5291688442230225,roll=0.011235682293772697", + "battery_status": "Battery:voltage=0.0,current=None,level=None", + "check_vehicle_armed": false, + "confidence": 0.7137885689735413, + "firmware_version": "APM:UnknownVehicleType11-4.0.0", + "gimbal_status": "Gimbal: pitch=0.0, roll=0.0, yaw=0.0", + "gps": "GPSInfo:fix=1,num_sat=0", + "ground_speed": 0.0, + "heading": 215, + "label": "Broken glass", + "last_heartbeat": 0.09994538699999111, + "location": "LocationGlobal:lat=0.0,lon=0.0,alt=4.62", + "range_finder_distance": "None", + "range_finder_voltage": "None", + "system_status": "CRITICAL", + "vehicle_capabilities": "True", + "vehicle_is_armable": false, + "vehicle_mode_name": "MANUAL", + "velocity": "[0.0, 0.0, 0.0]" + }, + { + "EKF_OK": false, + "air_speed": 0.0, + "attitude": "Attitude:pitch=0.032340094447135925,yaw=-2.5291972160339355,roll=0.010941646993160248", + "battery_status": "Battery:voltage=0.0,current=None,level=None", + "check_vehicle_armed": false, + "confidence": 0.5565459728240967, + "firmware_version": "APM:UnknownVehicleType11-4.0.0", + "gimbal_status": "Gimbal: pitch=0.0, roll=0.0, yaw=0.0", + "gps": "GPSInfo:fix=1,num_sat=0", + "ground_speed": 0.0, + "heading": 215, + "label": "Crisp packet", + "last_heartbeat": 0.43918579600000385, + "location": "LocationGlobal:lat=0.0,lon=0.0,alt=4.58", + "range_finder_distance": "None", + "range_finder_voltage": "None", + "system_status": "CRITICAL", + "vehicle_capabilities": "True", + "vehicle_is_armable": false, + "vehicle_mode_name": "MANUAL", + "velocity": "[0.0, 0.0, 0.0]" + }, + { + "EKF_OK": false, + "air_speed": 0.0, + "attitude": "Attitude:pitch=0.03162189945578575,yaw=-2.528460741043091,roll=0.010744147002696991", + "battery_status": "Battery:voltage=0.0,current=None,level=None", + "check_vehicle_armed": false, + "confidence": 0.6089277863502502, + "firmware_version": "APM:UnknownVehicleType11-4.0.0", + "gimbal_status": "Gimbal: pitch=0.0, roll=0.0, yaw=0.0", + "gps": "GPSInfo:fix=1,num_sat=0", + "ground_speed": 0.0, + "heading": 215, + "label": "Carded blister pack", + "last_heartbeat": 0.33337623099998837, + "location": "LocationGlobal:lat=0.0,lon=0.0,alt=5.06", + "range_finder_distance": "None", + "range_finder_voltage": "None", + "system_status": "CRITICAL", + "vehicle_capabilities": "True", + "vehicle_is_armable": false, + "vehicle_mode_name": "MANUAL", + "velocity": "[0.0, 0.0, 0.0]" + }, + { + "EKF_OK": false, + "air_speed": 0.0, + "attitude": "Attitude:pitch=0.030344994738698006,yaw=-2.531757354736328,roll=0.011866731569170952", + "battery_status": "Battery:voltage=0.0,current=None,level=None", + "check_vehicle_armed": false, + "confidence": 0.6337704062461853, + "firmware_version": "APM:UnknownVehicleType11-4.0.0", + "gimbal_status": "Gimbal: pitch=0.0, roll=0.0, yaw=0.0", + "gps": "GPSInfo:fix=1,num_sat=0", + "ground_speed": 0.0, + "heading": 214, + "label": "Produce bag", + "last_heartbeat": 0.5924038890000247, + "location": "LocationGlobal:lat=0.0,lon=0.0,alt=4.8", + "range_finder_distance": "None", + "range_finder_voltage": "None", + "system_status": "CRITICAL", + "vehicle_capabilities": "True", + "vehicle_is_armable": false, + "vehicle_mode_name": "MANUAL", + "velocity": "[0.0, 0.0, 0.0]" + }, + { + "EKF_OK": false, + "air_speed": 0.0, + "attitude": "Attitude:pitch=0.021685877814888954,yaw=-2.576737642288208,roll=0.03922276198863983", + "battery_status": "Battery:voltage=0.0,current=None,level=None", + "check_vehicle_armed": false, + "confidence": 0.510886013507843, + "firmware_version": "APM:UnknownVehicleType11-4.0.0", + "gimbal_status": "Gimbal: pitch=0.0, roll=0.0, yaw=0.0", + "gps": "GPSInfo:fix=1,num_sat=0", + "ground_speed": 0.0, + "heading": 212, + "label": "Crisp packet", + "last_heartbeat": 0.387161047999939, + "location": "LocationGlobal:lat=0.0,lon=0.0,alt=4.21", + "range_finder_distance": "None", + "range_finder_voltage": "None", + "system_status": "CRITICAL", + "vehicle_capabilities": "True", + "vehicle_is_armable": false, + "vehicle_mode_name": "MANUAL", + "velocity": "[0.0, 0.0, 0.0]" + }, + { + "EKF_OK": false, + "air_speed": 0.0, + "attitude": "Attitude:pitch=0.021333904936909676,yaw=-2.5751540660858154,roll=0.03939945623278618", + "battery_status": "Battery:voltage=0.0,current=None,level=None", + "check_vehicle_armed": false, + "confidence": 0.5126315951347351, + "firmware_version": "APM:UnknownVehicleType11-4.0.0", + "gimbal_status": "Gimbal: pitch=0.0, roll=0.0, yaw=0.0", + "gps": "GPSInfo:fix=1,num_sat=0", + "ground_speed": 0.0, + "heading": 212, + "label": "Drink can", + "last_heartbeat": 0.35668073699991965, + "location": "LocationGlobal:lat=0.0,lon=0.0,alt=4.62", + "range_finder_distance": "None", + "range_finder_voltage": "None", + "system_status": "CRITICAL", + "vehicle_capabilities": "True", + "vehicle_is_armable": false, + "vehicle_mode_name": "MANUAL", + "velocity": "[0.0, 0.0, 0.0]" + }, + { + "EKF_OK": false, + "air_speed": 0.0, + "attitude": "Attitude:pitch=0.022167686372995377,yaw=-2.5750272274017334,roll=0.038983624428510666", + "battery_status": "Battery:voltage=0.0,current=None,level=None", + "check_vehicle_armed": false, + "confidence": 0.5082154273986816, + "firmware_version": "APM:UnknownVehicleType11-4.0.0", + "gimbal_status": "Gimbal: pitch=0.0, roll=0.0, yaw=0.0", + "gps": "GPSInfo:fix=1,num_sat=0", + "ground_speed": 0.0, + "heading": 212, + "label": "Tissues", + "last_heartbeat": 0.2797554009999885, + "location": "LocationGlobal:lat=0.0,lon=0.0,alt=4.43", + "range_finder_distance": "None", + "range_finder_voltage": "None", + "system_status": "CRITICAL", + "vehicle_capabilities": "True", + "vehicle_is_armable": false, + "vehicle_mode_name": "MANUAL", + "velocity": "[0.0, 0.0, 0.0]" + }, + { + "EKF_OK": false, + "air_speed": 0.0, + "attitude": "Attitude:pitch=0.022055204957723618,yaw=-2.5754761695861816,roll=0.03863729164004326", + "battery_status": "Battery:voltage=0.0,current=None,level=None", + "check_vehicle_armed": false, + "confidence": 0.6818053722381592, + "firmware_version": "APM:UnknownVehicleType11-4.0.0", + "gimbal_status": "Gimbal: pitch=0.0, roll=0.0, yaw=0.0", + "gps": "GPSInfo:fix=1,num_sat=0", + "ground_speed": 0.0, + "heading": 212, + "label": "Glass bottle", + "last_heartbeat": 0.5872588710000173, + "location": "LocationGlobal:lat=0.0,lon=0.0,alt=4.33", + "range_finder_distance": "None", + "range_finder_voltage": "None", + "system_status": "CRITICAL", + "vehicle_capabilities": "True", + "vehicle_is_armable": false, + "vehicle_mode_name": "MANUAL", + "velocity": "[0.0, 0.0, 0.0]" + }, + { + "EKF_OK": false, + "air_speed": 0.0, + "attitude": "Attitude:pitch=0.021176500245928764,yaw=-2.576674461364746,roll=0.0393514446914196", + "battery_status": "Battery:voltage=0.0,current=None,level=None", + "check_vehicle_armed": false, + "confidence": 0.6461251378059387, + "firmware_version": "APM:UnknownVehicleType11-4.0.0", + "gimbal_status": "Gimbal: pitch=0.0, roll=0.0, yaw=0.0", + "gps": "GPSInfo:fix=1,num_sat=0", + "ground_speed": 0.0, + "heading": 212, + "label": "Glass bottle", + "last_heartbeat": 0.8723373020000054, + "location": "LocationGlobal:lat=0.0,lon=0.0,alt=4.9", + "range_finder_distance": "None", + "range_finder_voltage": "None", + "system_status": "CRITICAL", + "vehicle_capabilities": "True", + "vehicle_is_armable": false, + "vehicle_mode_name": "MANUAL", + "velocity": "[0.0, 0.0, 0.0]" + }, + { + "EKF_OK": false, + "air_speed": 0.0, + "attitude": "Attitude:pitch=0.02113579772412777,yaw=-2.5758206844329834,roll=0.03883090615272522", + "battery_status": "Battery:voltage=0.0,current=None,level=None", + "check_vehicle_armed": false, + "confidence": 0.6111947298049927, + "firmware_version": "APM:UnknownVehicleType11-4.0.0", + "gimbal_status": "Gimbal: pitch=0.0, roll=0.0, yaw=0.0", + "gps": "GPSInfo:fix=1,num_sat=0", + "ground_speed": 0.0, + "heading": 212, + "label": "Crisp packet", + "last_heartbeat": 0.42284541800017905, + "location": "LocationGlobal:lat=0.0,lon=0.0,alt=4.73", + "range_finder_distance": "None", + "range_finder_voltage": "None", + "system_status": "CRITICAL", + "vehicle_capabilities": "True", + "vehicle_is_armable": false, + "vehicle_mode_name": "MANUAL", + "velocity": "[0.0, 0.0, 0.0]" + }, + { + "EKF_OK": false, + "air_speed": 0.0, + "attitude": "Attitude:pitch=0.1569267213344574,yaw=1.739096760749817,roll=0.059471968561410904", + "battery_status": "Battery:voltage=0.0,current=None,level=None", + "check_vehicle_armed": false, + "confidence": 0.7094597816467285, + "firmware_version": "APM:UnknownVehicleType11-4.0.0", + "gimbal_status": "Gimbal: pitch=0.0, roll=0.0, yaw=0.0", + "gps": "GPSInfo:fix=1,num_sat=0", + "ground_speed": 0.0, + "heading": 99, + "label": "Plastic bottle cap", + "last_heartbeat": 0.5886059800000112, + "location": "LocationGlobal:lat=0.0,lon=0.0,alt=-0.25", + "range_finder_distance": "None", + "range_finder_voltage": "None", + "system_status": "CRITICAL", + "vehicle_capabilities": "True", + "vehicle_is_armable": false, + "vehicle_mode_name": "HOLD", + "velocity": "[0.0, 0.0, 0.0]" + }, + { + "EKF_OK": false, + "air_speed": 0.0, + "attitude": "Attitude:pitch=-0.013345734216272831,yaw=2.816819190979004,roll=0.018571699038147926", + "battery_status": "Battery:voltage=0.0,current=None,level=None", + "check_vehicle_armed": false, + "confidence": 0.5480275750160217, + "firmware_version": "APM:UnknownVehicleType11-4.0.0", + "gimbal_status": "Gimbal: pitch=0.0, roll=0.0, yaw=0.0", + "gps": "GPSInfo:fix=1,num_sat=0", + "ground_speed": 0.0, + "heading": 161, + "label": "Paper straw", + "last_heartbeat": 0.014498732999982167, + "location": "LocationGlobal:lat=0.0,lon=0.0,alt=0.45", + "range_finder_distance": "None", + "range_finder_voltage": "None", + "system_status": "CRITICAL", + "vehicle_capabilities": "True", + "vehicle_is_armable": false, + "vehicle_mode_name": "MANUAL", + "velocity": "[0.0, 0.0, 0.0]" + } +] diff --git a/report/thingspeak.py b/report/thingspeak.py new file mode 100644 index 0000000..5413f02 --- /dev/null +++ b/report/thingspeak.py @@ -0,0 +1,58 @@ +import os +import paho.mqtt.publish as publish +import re +import logging + + +channel_ID = os.environ['CHANNEL_ID'] +api_key = os.environ['API_KEY'] +topic = "channels/"+channel_ID+"/publish/"+api_key +mqttHost = "mqtt.thingspeak.com" +tTransport = "tcp" +tPort = 1883 +tTLS = None + + +class ThingSpeak: + def __init__(self, yolo, pixhawk): + self.label = yolo["label"] + self.confidence = yolo["confidence"] + self.location = pixhawk.do_capture_global_location() + self.battery_status = pixhawk.battery_status() + self.system_status = pixhawk.system_status() + + def create_payload_string(self, payload): + return "&".join(map(lambda x: f"{x[0]}={x[1]}", payload.items())) + + def send_to_thingspeak(self): + # get gps_location from string variable and stored it in a list + location_string = self.location.get_coordinates() + gps_location = re.findall(r"[-+]?\d*\.\d+|\d+", location_string) + + label_data = str(self.label.get_label()) + confidence_data = str(self.confidence.get_confidence() * 100) + lat = gps_location[0] + lon = gps_location[1] + battery_status_data = str(self.battery_status.get_battery_status()) + system_status_data = str(self.system_status.get_system_status()) + + # payload + payload = { + "field1": lat, + "field2": lon, + "field3": confidence_data, + "field4": system_status_data, + "field5": battery_status_data, + "field6": label_data + } + + payload_string = self.create_payload_string(payload) + + print("[INFO] Data prepared to be uploaded") + + try: + # publish the data + publish.single(topic, payload=payload_string, hostname=mqttHost, port=tPort, tls=tTLS, transport=tTransport) + print("[INFO] Data sent successfully") + except Exception as e: + logging.error(e) diff --git a/testing.py b/testing.py new file mode 100644 index 0000000..11acb72 --- /dev/null +++ b/testing.py @@ -0,0 +1,32 @@ +from dronekit import connect, VehicleMode, LocationGlobalRelative +print("stage 1 done") + +connection_port="/dev/ttyTHS1" + +baud=57600 +vehicle = connect(connection_port, wait_ready=None, baud=baud) +vehicle.mode = VehicleMode("MANUAL") + +print("stage 2 done") +print('Autopilot Firmware version: %s' % vehicle.version) +#print('Autopilot capabilities (supports ftp): %s' % vehicle.capabilities.ftp) +print('Global Location: %s' % vehicle.location.global_frame) +print('Global Location (relative altitude): %s' % vehicle.location.global_relative_frame) +print('Local Location: %s' % vehicle.location.local_frame) +print('Attitude: %s' % vehicle.attitude) +print('Velocity: %s' % vehicle.velocity) +print('GPS: %s' % vehicle.gps_0) +print('Groundspeed: %s' % vehicle.groundspeed) +print('Airspeed: %s' % vehicle.airspeed) +print('Gimbal status: %s' % vehicle.gimbal) +print('Battery: %s' % vehicle.battery) +print('EKF OK?: %s' % vehicle.ekf_ok) +print('Last Heartbeat: %s' % vehicle.last_heartbeat) +print('Rangefinder: %s' % vehicle.rangefinder) +print('Rangefinder distance: %s' % vehicle.rangefinder.distance) +print('Rangefinder voltage: %s' % vehicle.rangefinder.voltage) +print('Heading: %s' % vehicle.heading) +print('Is Armable?: %s' % vehicle.is_armable) +print('System status: %s' % vehicle.system_status.state) +print('Mode: %s' % vehicle.mode.name) +print('Armed: %s' % vehicle.armed) diff --git a/yolo_object_detection.py b/yolo_object_detection.py deleted file mode 100644 index fef240d..0000000 --- a/yolo_object_detection.py +++ /dev/null @@ -1,180 +0,0 @@ -# USAGE -# python yolo_object_detection.py --input ../example_videos/janie.mp4 --output ../output_videos/yolo_janie.avi --yolo yolo-coco --display 0 -# python yolo_object_detection.py --input ../example_videos/janie.mp4 --output ../output_videos/yolo_janie.avi --yolo yolo-coco --display 0 --use-gpu 1 - -# import the necessary packages -from imutils.video import FPS -import numpy as np -import argparse -import cv2 -import os - -# construct the argument parse and parse the arguments -ap = argparse.ArgumentParser() -ap.add_argument("-i", "--input", type=str, default="", - help="path to (optional) input video file") -ap.add_argument("-o", "--output", type=str, default="", - help="path to (optional) output video file") -ap.add_argument("-d", "--display", type=int, default=1, - help="whether or not output frame should be displayed") -ap.add_argument("-y", "--yolo", required=True, - help="base path to YOLO directory") -ap.add_argument("-c", "--confidence", type=float, default=0.5, - help="minimum probability to filter weak detections") -ap.add_argument("-t", "--threshold", type=float, default=0.3, - help="threshold when applyong non-maxima suppression") -ap.add_argument("-u", "--use-gpu", type=bool, default=0, - help="boolean indicating if CUDA GPU should be used") -args = vars(ap.parse_args()) - -# load the COCO class labels our YOLO model was trained on -labelsPath = os.path.sep.join([args["yolo"], "clearbot.names"]) -LABELS = open(labelsPath).read().strip().split("\n") - -# initialize a list of colors to represent each possible class label -np.random.seed(42) -COLORS = np.random.randint(0, 255, size=(len(LABELS), 3), - dtype="uint8") - -# derive the paths to the YOLO weights and model configuration -weightsPath = os.path.sep.join([args["yolo"], "clearbot.weights"]) -configPath = os.path.sep.join([args["yolo"], "clearbot.cfg"]) - -# load our YOLO object detector trained on COCO dataset (80 classes) -print("[INFO] loading YOLO from disk...") -net = cv2.dnn.readNetFromDarknet(configPath, weightsPath) - -# check if we are going to use GPU -if args["use_gpu"]: - # set CUDA as the preferable backend and target - print("[INFO] setting preferable backend and target to CUDA...") - net.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA) - net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA) - -# determine only the *output* layer names that we need from YOLO -ln = net.getLayerNames() -ln = [ln[i[0] - 1] for i in net.getUnconnectedOutLayers()] - -# initialize the width and height of the frames in the video file -W = None -H = None - -# initialize the video stream and pointer to output video file, then -# start the FPS timer -print("[INFO] accessing video stream...") -vs = cv2.VideoCapture(args["input"] if args["input"] else 0) -writer = None -fps = FPS().start() - -# loop over frames from the video file stream -while True: - # read the next frame from the file - (grabbed, frame) = vs.read() - - # if the frame was not grabbed, then we have reached the end - # of the stream - if not grabbed: - break - - # if the frame dimensions are empty, grab them - if W is None or H is None: - (H, W) = frame.shape[:2] - - # construct a blob from the input frame and then perform a forward - # pass of the YOLO object detector, giving us our bounding boxes - # and associated probabilities - blob = cv2.dnn.blobFromImage(frame, 1 / 255.0, (416, 416), - swapRB=True, crop=False) - net.setInput(blob) - layerOutputs = net.forward(ln) - - # initialize our lists of detected bounding boxes, confidences, - # and class IDs, respectively - boxes = [] - confidences = [] - classIDs = [] - - # loop over each of the layer outputs - for output in layerOutputs: - # loop over each of the detections - for detection in output: - # extract the class ID and confidence (i.e., probability) - # of the current object detection - scores = detection[5:] - classID = np.argmax(scores) - confidence = scores[classID] - - # filter out weak predictions by ensuring the detected - # probability is greater than the minimum probability - if confidence > args["confidence"]: - # scale the bounding box coordinates back relative to - # the size of the image, keeping in mind that YOLO - # actually returns the center (x, y)-coordinates of - # the bounding box followed by the boxes' width and - # height - box = detection[0:4] * np.array([W, H, W, H]) - (centerX, centerY, width, height) = box.astype("int") - - # use the center (x, y)-coordinates to derive the top - # and and left corner of the bounding box - x = int(centerX - (width / 2)) - y = int(centerY - (height / 2)) - - # update our list of bounding box coordinates, - # confidences, and class IDs - boxes.append([x, y, int(width), int(height)]) - confidences.append(float(confidence)) - classIDs.append(classID) - - # apply non-maxima suppression to suppress weak, overlapping - # bounding boxes - idxs = cv2.dnn.NMSBoxes(boxes, confidences, args["confidence"], - args["threshold"]) - - # ensure at least one detection exists - if len(idxs) > 0: - # loop over the indexes we are keeping - for i in idxs.flatten(): - # extract the bounding box coordinates - (x, y) = (boxes[i][0], boxes[i][1]) - (w, h) = (boxes[i][2], boxes[i][3]) - - # draw a bounding box rectangle and label on the frame - color = [int(c) for c in COLORS[classIDs[i]]] - cv2.rectangle(frame, (x, y), (x + w, y + h), color, 2) - text = "{}: {:.4f}".format(LABELS[classIDs[i]], - confidences[i]) - cv2.putText(frame, text, (x, y - 5), - cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2) - - # check to see if the output frame should be displayed to our - # screen - if args["display"] > 0: - # show the output frame - cv2.imshow("Frame", frame) - key = cv2.waitKey(1) & 0xFF - - # if the `q` key was pressed, break from the loop - if key == ord("q"): - break - - # if an output video file path has been supplied and the video - # writer has not been initialized, do so now - if args["output"] != "" and writer is None: - # initialize our video writer - fourcc = cv2.VideoWriter_fourcc(*"MJPG") - writer = cv2.VideoWriter(args["output"], fourcc, 30, - (frame.shape[1], frame.shape[0]), True) - - # if the video writer is not None, write the frame to the output - # video file - if writer is not None: - writer.write(frame) - - # update the FPS counter - fps.update() - -# stop the timer and display FPS information -fps.stop() -print("[INFO] elasped time: {:.2f}".format(fps.elapsed())) -print("[INFO] approx. FPS: {:.2f}".format(fps.fps())) \ No newline at end of file