From 5f7ab3665fcc4f6d635e060994a5d3a90c23c400 Mon Sep 17 00:00:00 2001 From: Ahsan Raza Date: Sun, 15 May 2022 21:23:12 +0500 Subject: [PATCH 1/8] Add files via upload pytracking/evaluation/tracker.py has been modified by adding camera_video and camera_rtsp functions for tracking on both recorded videos and webcam/rtsp streams. The functions are executed in threads and the main purpose is to enable tracking in real time on rtsp streams without lag. --- pytracking/evaluation/tracker.py | 307 +++++++++++++++++++------------ 1 file changed, 192 insertions(+), 115 deletions(-) diff --git a/pytracking/evaluation/tracker.py b/pytracking/evaluation/tracker.py index 634173f0..c8002c41 100644 --- a/pytracking/evaluation/tracker.py +++ b/pytracking/evaluation/tracker.py @@ -15,6 +15,7 @@ from pathlib import Path import torch +import threading _tracker_disp_colors = {1: (0, 255, 0), 2: (0, 0, 255), 3: (255, 0, 0), 4: (255, 255, 255), 5: (0, 0, 0), 6: (0, 255, 128), @@ -50,6 +51,10 @@ def __init__(self, name: str, parameter_name: str, run_id: int = None, display_n self.parameter_name = parameter_name self.run_id = run_id self.display_name = display_name + self.rtsp = 'rtsp://192.168.0.60/0' # RTSP Stream or Web Stream = Use 0 if webcam needs to be used. + + self.skip_frame = 1 # Number of frames to skip while processing + self.camera_flag = False env = env_settings() if self.run_id is None: @@ -231,6 +236,56 @@ def _store_outputs(tracker_out: dict, defaults=None): output['object_presence_score_threshold'] = tracker.params.get('object_presence_score_threshold', 0.55) return output + + def camera_video(self, videofilepath, sf): + + self.cap = cv.VideoCapture(videofilepath) + + self.camera_thread = False # Camera Function thread Flag + + counter = 0 + skip_frame = sf + + while True: + if self.camera_flag == False: + self.success, self.frame = self.cap.read() + + counter += 1 + + if counter == skip_frame + 1: + self.camera_flag = True + + self.new_frame = self.frame + + counter = 0 + + if self.success == False: + break + + if self.camera_thread == True: + print('Quit !!!') + break + + time.sleep(0.005) + + def camera_rtsp(self, rtsp): + + self.cap = cv.VideoCapture(rtsp) + + self.camera_thread = False # Camera Function thread Flag + + while True: + self.success, self.frame = self.cap.read() + self.camera_flag = True + + if self.success == False: + break + + if self.camera_thread == True: + print('Quit !!!') + break + + time.sleep(0.005) def run_video(self, videofilepath, optional_box=None, debug=None, visdom_info=None, save_results=False): """Run the tracker with the video file. @@ -266,95 +321,104 @@ def run_video(self, videofilepath, optional_box=None, debug=None, visdom_info=No output_boxes = [] - cap = cv.VideoCapture(videofilepath) + camera = threading.Thread(target=self.camera_video, args=(videofilepath, self.skip_frame,)) + camera.start() + print('Camera initiated') + display_name = 'Display: ' + tracker.params.tracker_name cv.namedWindow(display_name, cv.WINDOW_NORMAL | cv.WINDOW_KEEPRATIO) cv.resizeWindow(display_name, 960, 720) - success, frame = cap.read() - cv.imshow(display_name, frame) + cv.imshow(display_name, self.frame) + def _build_init_info(box): return {'init_bbox': OrderedDict({1: box}), 'init_object_ids': [1, ], 'object_ids': [1, ], 'sequence_object_ids': [1, ]} - if success is not True: + if self.success is not True: print("Read frame from {} failed.".format(videofilepath)) exit(-1) if optional_box is not None: assert isinstance(optional_box, (list, tuple)) assert len(optional_box) == 4, "valid box's foramt is [x,y,w,h]" - tracker.initialize(frame, _build_init_info(optional_box)) + tracker.initialize(self.frame, _build_init_info(optional_box)) output_boxes.append(optional_box) else: while True: - # cv.waitKey() - frame_disp = frame.copy() - - cv.putText(frame_disp, 'Select target ROI and press ENTER', (20, 30), cv.FONT_HERSHEY_COMPLEX_SMALL, - 1.5, (0, 0, 0), 1) + if self.camera_flag == True: + frame_disp = self.new_frame.copy() - x, y, w, h = cv.selectROI(display_name, frame_disp, fromCenter=False) - init_state = [x, y, w, h] - tracker.initialize(frame, _build_init_info(init_state)) - output_boxes.append(init_state) - break - - while True: - ret, frame = cap.read() - - if frame is None: - break + cv.putText(frame_disp, 'Select target ROI and press ENTER', (20, 30), cv.FONT_HERSHEY_COMPLEX_SMALL, + 1.5, (0, 0, 255), 1) - frame_disp = frame.copy() + x, y, w, h = cv.selectROI(display_name, frame_disp, fromCenter=False) + init_state = [x, y, w, h] + tracker.initialize(self.new_frame, _build_init_info(init_state)) + output_boxes.append(init_state) + self.camera_flag = False - # Draw box - out = tracker.track(frame) - state = [int(s) for s in out['target_bbox'][1]] - output_boxes.append(state) - - cv.rectangle(frame_disp, (state[0], state[1]), (state[2] + state[0], state[3] + state[1]), - (0, 255, 0), 5) + break - font_color = (0, 0, 0) - cv.putText(frame_disp, 'Tracking!', (20, 30), cv.FONT_HERSHEY_COMPLEX_SMALL, 1, - font_color, 1) - cv.putText(frame_disp, 'Press r to reset', (20, 55), cv.FONT_HERSHEY_COMPLEX_SMALL, 1, - font_color, 1) - cv.putText(frame_disp, 'Press q to quit', (20, 80), cv.FONT_HERSHEY_COMPLEX_SMALL, 1, - font_color, 1) + else: + time.sleep(0.01) - # Display the resulting frame - cv.imshow(display_name, frame_disp) - key = cv.waitKey(1) - if key == ord('q'): - break - elif key == ord('r'): - ret, frame = cap.read() - frame_disp = frame.copy() - cv.putText(frame_disp, 'Select target ROI and press ENTER', (20, 30), cv.FONT_HERSHEY_COMPLEX_SMALL, 1.5, - (0, 0, 0), 1) + while True: + if self.camera_flag == True: + frame_disp = self.new_frame.copy() + out = tracker.track(self.new_frame) + + state = [int(s) for s in out['target_bbox'][1]] + output_boxes.append(state) + + cv.rectangle(frame_disp, (state[0], state[1]), (state[2] + state[0], state[3] + state[1]), (0, 0, 255), 2) + + font_color = (0, 0, 255) + cv.putText(frame_disp, 'Tracking!', (20, 30), cv.FONT_HERSHEY_COMPLEX_SMALL, 2, font_color, 1) + cv.putText(frame_disp, 'Press r to reset', (20, 55), cv.FONT_HERSHEY_COMPLEX_SMALL, 2, font_color, 1) + cv.putText(frame_disp, 'Press q to quit', (20, 80), cv.FONT_HERSHEY_COMPLEX_SMALL, 2, font_color, 1) + + # Display the resulting frame cv.imshow(display_name, frame_disp) - x, y, w, h = cv.selectROI(display_name, frame_disp, fromCenter=False) - init_state = [x, y, w, h] - tracker.initialize(frame, _build_init_info(init_state)) - output_boxes.append(init_state) - + key = cv.waitKey(1) + if key == ord('q'): + self.camera_thread = True + camera.join() + + break + + elif key == ord('r'): + frame_disp = self.new_frame.copy() + + cv.putText(frame_disp, 'Select target ROI and press ENTER', (20, 30), cv.FONT_HERSHEY_COMPLEX_SMALL, 2.5, (0, 0, 255), 1) + + cv.imshow(display_name, frame_disp) + x, y, w, h = cv.selectROI(display_name, frame_disp, fromCenter=False) + init_state = [x, y, w, h] + tracker.initialize(self.new_frame, _build_init_info(init_state)) + output_boxes.append(init_state) + + self.camera_flag = False + + else: + time.sleep(0.01) + # When everything done, release the capture - cap.release() + self.cap.release() cv.destroyAllWindows() - + if save_results: if not os.path.exists(self.results_dir): os.makedirs(self.results_dir) video_name = Path(videofilepath).stem base_results_path = os.path.join(self.results_dir, 'video_{}'.format(video_name)) - + tracked_bb = np.array(output_boxes).astype(int) bbox_file = '{}.txt'.format(base_results_path) np.savetxt(bbox_file, tracked_bb, delimiter='\t', fmt='%d') + def run_webcam(self, debug=None, visdom_info=None): """Run the tracker with the webcam. args: @@ -415,81 +479,95 @@ def get_bb(self): return bb ui_control = UIControl() - cap = cv.VideoCapture(0) - display_name = 'Display: ' + self.name + + camera = threading.Thread(target=self.camera_rtsp, args=(self.rtsp,)) + camera.start() + print('Camera initiated') + + display_name = 'Display: ' + tracker.params.tracker_name cv.namedWindow(display_name, cv.WINDOW_NORMAL | cv.WINDOW_KEEPRATIO) cv.resizeWindow(display_name, 960, 720) + cv.setMouseCallback(display_name, ui_control.mouse_callback) next_object_id = 1 sequence_object_ids = [] prev_output = OrderedDict() + while True: - # Capture frame-by-frame - ret, frame = cap.read() - frame_disp = frame.copy() + if self.camera_flag == True: + frame_disp = self.frame.copy() - info = OrderedDict() - info['previous_output'] = prev_output + info = OrderedDict() + info['previous_output'] = prev_output - if ui_control.new_init: - ui_control.new_init = False - init_state = ui_control.get_bb() - - info['init_object_ids'] = [next_object_id, ] - info['init_bbox'] = OrderedDict({next_object_id: init_state}) - sequence_object_ids.append(next_object_id) - - next_object_id += 1 - - # Draw box - if ui_control.mode == 'select': - cv.rectangle(frame_disp, ui_control.get_tl(), ui_control.get_br(), (255, 0, 0), 2) - - if len(sequence_object_ids) > 0: - info['sequence_object_ids'] = sequence_object_ids - out = tracker.track(frame, info) - prev_output = OrderedDict(out) - - if 'segmentation' in out: - frame_disp = overlay_mask(frame_disp, out['segmentation']) - - if 'target_bbox' in out: - for obj_id, state in out['target_bbox'].items(): - state = [int(s) for s in state] - cv.rectangle(frame_disp, (state[0], state[1]), (state[2] + state[0], state[3] + state[1]), - _tracker_disp_colors[obj_id], 5) - - # Put text - font_color = (0, 0, 0) - cv.putText(frame_disp, 'Select target', (20, 30), cv.FONT_HERSHEY_COMPLEX_SMALL, 1, font_color, 1) - cv.putText(frame_disp, 'Press r to reset', (20, 55), cv.FONT_HERSHEY_COMPLEX_SMALL, 1, - font_color, 1) - cv.putText(frame_disp, 'Press q to quit', (20, 85), cv.FONT_HERSHEY_COMPLEX_SMALL, 1, - font_color, 1) - - # Display the resulting frame - cv.imshow(display_name, frame_disp) - key = cv.waitKey(1) - if key == ord('q'): - break - elif key == ord('r'): - next_object_id = 1 - sequence_object_ids = [] - prev_output = OrderedDict() + if ui_control.new_init: + ui_control.new_init = False + init_state = ui_control.get_bb() - info = OrderedDict() + info['init_object_ids'] = [next_object_id, ] + info['init_bbox'] = OrderedDict({next_object_id: init_state}) + sequence_object_ids.append(next_object_id) + + next_object_id += 1 - info['object_ids'] = [] - info['init_object_ids'] = [] - info['init_bbox'] = OrderedDict() - tracker.initialize(frame, info) - ui_control.mode = 'init' + # Draw box + if ui_control.mode == 'select': + cv.rectangle(frame_disp, ui_control.get_tl(), ui_control.get_br(), (255, 0, 0), 2) + + if len(sequence_object_ids) > 0: + info['sequence_object_ids'] = sequence_object_ids + out = tracker.track(self.frame, info) + prev_output = OrderedDict(out) + + if 'segmentation' in out: + frame_disp = overlay_mask(frame_disp, out['segmentation']) + + if 'target_bbox' in out: + for obj_id, state in out['target_bbox'].items(): + state = [int(s) for s in state] + cv.rectangle(frame_disp, (state[0], state[1]), (state[2] + state[0], state[3] + state[1]), + _tracker_disp_colors[obj_id], 5) + + # Put text + font_color = (0, 255, 0) + cv.putText(frame_disp, 'Select target', (20, 30), cv.FONT_HERSHEY_COMPLEX_SMALL, 1, font_color, 1) + cv.putText(frame_disp, 'Press r to reset', (20, 55), cv.FONT_HERSHEY_COMPLEX_SMALL, 1, font_color, 1) + cv.putText(frame_disp, 'Press q to quit', (20, 85), cv.FONT_HERSHEY_COMPLEX_SMALL, 1, font_color, 1) + + # Display the resulting frame + cv.imshow(display_name, frame_disp) + key = cv.waitKey(1) + if key == ord('q'): + self.camera_thread = True + camera.join() + + break + + elif key == ord('r'): + next_object_id = 1 + sequence_object_ids = [] + prev_output = OrderedDict() + + info = OrderedDict() + + info['object_ids'] = [] + info['init_object_ids'] = [] + info['init_bbox'] = OrderedDict() + tracker.initialize(self.frame, info) + ui_control.mode = 'init' + + self.camera_flag = False + + else: + time.sleep(0.005) + # When everything done, release the capture - cap.release() + self.cap.release() cv.destroyAllWindows() + def run_vot2020(self, debug=None, visdom_info=None): params = self.get_parameters() params.tracker_name = self.name @@ -652,6 +730,7 @@ def _convert_image_path(image_path): elif tracker.params.visualization: self.visualize(image, out['target_bbox'], segmentation) + def get_parameters(self): """Get parameters.""" param_module = importlib.import_module('pytracking.parameter.{}.{}'.format(self.name, self.parameter_name)) @@ -711,5 +790,3 @@ def _read_image(self, image_file: str): im = cv.imread(image_file) return cv.cvtColor(im, cv.COLOR_BGR2RGB) - - From 104750266b83f5e66b6008ca2fe428e30bff19f5 Mon Sep 17 00:00:00 2001 From: Ahsan Raza Date: Wed, 20 Jul 2022 12:39:27 +0500 Subject: [PATCH 2/8] Add files via upload --- pytracking/run_video_communication.py | 41 +++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 pytracking/run_video_communication.py diff --git a/pytracking/run_video_communication.py b/pytracking/run_video_communication.py new file mode 100644 index 00000000..79f33731 --- /dev/null +++ b/pytracking/run_video_communication.py @@ -0,0 +1,41 @@ +''' +Execute this file when tracking with a Client Server setup. +''' + +import os +import sys +import argparse + +env_path = os.path.join(os.path.dirname(__file__), '..') +if env_path not in sys.path: + sys.path.append(env_path) + +from pytracking.evaluation import Tracker + + +def run_video_comm(tracker_name, tracker_param, optional_box=None, debug=None, save_results=False): + """Run the tracker with the communication with the Ground Station (socket programming) using rtsp. + args: + tracker_name: Name of tracking method. + tracker_param: Name of parameter file. + debug: Debug level. + """ + tracker = Tracker(tracker_name, tracker_param) + tracker.run_video_comm(optional_box=optional_box, debug=debug, save_results=save_results) + +def main(): + parser = argparse.ArgumentParser(description='Run the tracker on your webcam.') + parser.add_argument('tracker_name', type=str, help='Name of tracking method.') + parser.add_argument('tracker_param', type=str, help='Name of parameter file.') + parser.add_argument('--optional_box', type=float, default=None, nargs="+", help='optional_box with format x y w h.') + parser.add_argument('--debug', type=int, default=0, help='Debug level.') + parser.add_argument('--save_results', dest='save_results', action='store_true', help='Save bounding boxes') + parser.set_defaults(save_results=False) + + args = parser.parse_args() + + run_video_comm(args.tracker_name, args.tracker_param, args.optional_box, args.debug, args.save_results) + + +if __name__ == '__main__': + main() From bdc0e421bd47f2ab1ee5673176aa51f109cb8efc Mon Sep 17 00:00:00 2001 From: Ahsan Raza Date: Wed, 20 Jul 2022 12:46:33 +0500 Subject: [PATCH 3/8] Delete tracker.py --- pytracking/evaluation/tracker.py | 792 ------------------------------- 1 file changed, 792 deletions(-) delete mode 100644 pytracking/evaluation/tracker.py diff --git a/pytracking/evaluation/tracker.py b/pytracking/evaluation/tracker.py deleted file mode 100644 index c8002c41..00000000 --- a/pytracking/evaluation/tracker.py +++ /dev/null @@ -1,792 +0,0 @@ -import importlib -import os -import numpy as np -from collections import OrderedDict -from pytracking.evaluation.environment import env_settings -import time -import cv2 as cv -from pytracking.utils.visdom import Visdom -import matplotlib.pyplot as plt -import matplotlib.patches as patches -from pytracking.utils.plotting import draw_figure, overlay_mask -from pytracking.utils.convert_vot_anno_to_rect import convert_vot_anno_to_rect -from ltr.data.bounding_box_utils import masks_to_bboxes -from pytracking.evaluation.multi_object_wrapper import MultiObjectWrapper -from pathlib import Path -import torch - -import threading - -_tracker_disp_colors = {1: (0, 255, 0), 2: (0, 0, 255), 3: (255, 0, 0), - 4: (255, 255, 255), 5: (0, 0, 0), 6: (0, 255, 128), - 7: (123, 123, 123), 8: (255, 128, 0), 9: (128, 0, 255)} - - -def trackerlist(name: str, parameter_name: str, run_ids = None, display_name: str = None): - """Generate list of trackers. - args: - name: Name of tracking method. - parameter_name: Name of parameter file. - run_ids: A single or list of run_ids. - display_name: Name to be displayed in the result plots. - """ - if run_ids is None or isinstance(run_ids, int): - run_ids = [run_ids] - return [Tracker(name, parameter_name, run_id, display_name) for run_id in run_ids] - - -class Tracker: - """Wraps the tracker for evaluation and running purposes. - args: - name: Name of tracking method. - parameter_name: Name of parameter file. - run_id: The run id. - display_name: Name to be displayed in the result plots. - """ - - def __init__(self, name: str, parameter_name: str, run_id: int = None, display_name: str = None): - assert run_id is None or isinstance(run_id, int) - - self.name = name - self.parameter_name = parameter_name - self.run_id = run_id - self.display_name = display_name - self.rtsp = 'rtsp://192.168.0.60/0' # RTSP Stream or Web Stream = Use 0 if webcam needs to be used. - - self.skip_frame = 1 # Number of frames to skip while processing - self.camera_flag = False - - env = env_settings() - if self.run_id is None: - self.results_dir = '{}/{}/{}'.format(env.results_path, self.name, self.parameter_name) - self.segmentation_dir = '{}/{}/{}'.format(env.segmentation_path, self.name, self.parameter_name) - else: - self.results_dir = '{}/{}/{}_{:03d}'.format(env.results_path, self.name, self.parameter_name, self.run_id) - self.segmentation_dir = '{}/{}/{}_{:03d}'.format(env.segmentation_path, self.name, self.parameter_name, self.run_id) - - tracker_module_abspath = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'tracker', self.name)) - if os.path.isdir(tracker_module_abspath): - tracker_module = importlib.import_module('pytracking.tracker.{}'.format(self.name)) - self.tracker_class = tracker_module.get_tracker_class() - else: - self.tracker_class = None - - self.visdom = None - - - def _init_visdom(self, visdom_info, debug): - visdom_info = {} if visdom_info is None else visdom_info - self.pause_mode = False - self.step = False - if debug > 0 and visdom_info.get('use_visdom', True): - try: - self.visdom = Visdom(debug, {'handler': self._visdom_ui_handler, 'win_id': 'Tracking'}, - visdom_info=visdom_info) - - # Show help - help_text = 'You can pause/unpause the tracker by pressing ''space'' with the ''Tracking'' window ' \ - 'selected. During paused mode, you can track for one frame by pressing the right arrow key.' \ - 'To enable/disable plotting of a data block, tick/untick the corresponding entry in ' \ - 'block list.' - self.visdom.register(help_text, 'text', 1, 'Help') - except: - time.sleep(0.5) - print('!!! WARNING: Visdom could not start, so using matplotlib visualization instead !!!\n' - '!!! Start Visdom in a separate terminal window by typing \'visdom\' !!!') - - def _visdom_ui_handler(self, data): - if data['event_type'] == 'KeyPress': - if data['key'] == ' ': - self.pause_mode = not self.pause_mode - - elif data['key'] == 'ArrowRight' and self.pause_mode: - self.step = True - - - def create_tracker(self, params): - tracker = self.tracker_class(params) - tracker.visdom = self.visdom - return tracker - - def run_sequence(self, seq, visualization=None, debug=None, visdom_info=None, multiobj_mode=None): - """Run tracker on sequence. - args: - seq: Sequence to run the tracker on. - visualization: Set visualization flag (None means default value specified in the parameters). - debug: Set debug level (None means default value specified in the parameters). - visdom_info: Visdom info. - multiobj_mode: Which mode to use for multiple objects. - """ - params = self.get_parameters() - visualization_ = visualization - - debug_ = debug - if debug is None: - debug_ = getattr(params, 'debug', 0) - if visualization is None: - if debug is None: - visualization_ = getattr(params, 'visualization', False) - else: - visualization_ = True if debug else False - - params.visualization = visualization_ - params.debug = debug_ - - self._init_visdom(visdom_info, debug_) - if visualization_ and self.visdom is None: - self.init_visualization() - - # Get init information - init_info = seq.init_info() - is_single_object = not seq.multiobj_mode - - if multiobj_mode is None: - multiobj_mode = getattr(params, 'multiobj_mode', getattr(self.tracker_class, 'multiobj_mode', 'default')) - - if multiobj_mode == 'default' or is_single_object: - tracker = self.create_tracker(params) - elif multiobj_mode == 'parallel': - tracker = MultiObjectWrapper(self.tracker_class, params, self.visdom) - else: - raise ValueError('Unknown multi object mode {}'.format(multiobj_mode)) - - output = self._track_sequence(tracker, seq, init_info) - return output - - def _track_sequence(self, tracker, seq, init_info): - # Define outputs - # Each field in output is a list containing tracker prediction for each frame. - - # In case of single object tracking mode: - # target_bbox[i] is the predicted bounding box for frame i - # time[i] is the processing time for frame i - # segmentation[i] is the segmentation mask for frame i (numpy array) - - # In case of multi object tracking mode: - # target_bbox[i] is an OrderedDict, where target_bbox[i][obj_id] is the predicted box for target obj_id in - # frame i - # time[i] is either the processing time for frame i, or an OrderedDict containing processing times for each - # object in frame i - # segmentation[i] is the multi-label segmentation mask for frame i (numpy array) - - output = {'target_bbox': [], - 'time': [], - 'segmentation': [], - 'object_presence_score': []} - - def _store_outputs(tracker_out: dict, defaults=None): - defaults = {} if defaults is None else defaults - for key in output.keys(): - val = tracker_out.get(key, defaults.get(key, None)) - if key in tracker_out or val is not None: - output[key].append(val) - - # Initialize - image = self._read_image(seq.frames[0]) - - if tracker.params.visualization and self.visdom is None: - self.visualize(image, init_info.get('init_bbox')) - - start_time = time.time() - out = tracker.initialize(image, init_info) - if out is None: - out = {} - - prev_output = OrderedDict(out) - - init_default = {'target_bbox': init_info.get('init_bbox'), - 'time': time.time() - start_time, - 'segmentation': init_info.get('init_mask'), - 'object_presence_score': 1.} - - _store_outputs(out, init_default) - - for frame_num, frame_path in enumerate(seq.frames[1:], start=1): - while True: - if not self.pause_mode: - break - elif self.step: - self.step = False - break - else: - time.sleep(0.1) - - image = self._read_image(frame_path) - - start_time = time.time() - - info = seq.frame_info(frame_num) - info['previous_output'] = prev_output - - out = tracker.track(image, info) - prev_output = OrderedDict(out) - _store_outputs(out, {'time': time.time() - start_time}) - - segmentation = out['segmentation'] if 'segmentation' in out else None - if self.visdom is not None: - tracker.visdom_draw_tracking(image, out['target_bbox'], segmentation) - elif tracker.params.visualization: - self.visualize(image, out['target_bbox'], segmentation) - - for key in ['target_bbox', 'segmentation']: - if key in output and len(output[key]) <= 1: - output.pop(key) - - output['image_shape'] = image.shape[:2] - output['object_presence_score_threshold'] = tracker.params.get('object_presence_score_threshold', 0.55) - - return output - - def camera_video(self, videofilepath, sf): - - self.cap = cv.VideoCapture(videofilepath) - - self.camera_thread = False # Camera Function thread Flag - - counter = 0 - skip_frame = sf - - while True: - if self.camera_flag == False: - self.success, self.frame = self.cap.read() - - counter += 1 - - if counter == skip_frame + 1: - self.camera_flag = True - - self.new_frame = self.frame - - counter = 0 - - if self.success == False: - break - - if self.camera_thread == True: - print('Quit !!!') - break - - time.sleep(0.005) - - def camera_rtsp(self, rtsp): - - self.cap = cv.VideoCapture(rtsp) - - self.camera_thread = False # Camera Function thread Flag - - while True: - self.success, self.frame = self.cap.read() - self.camera_flag = True - - if self.success == False: - break - - if self.camera_thread == True: - print('Quit !!!') - break - - time.sleep(0.005) - - def run_video(self, videofilepath, optional_box=None, debug=None, visdom_info=None, save_results=False): - """Run the tracker with the video file. - args: - debug: Debug level. - """ - - params = self.get_parameters() - - debug_ = debug - if debug is None: - debug_ = getattr(params, 'debug', 0) - params.debug = debug_ - - params.tracker_name = self.name - params.param_name = self.parameter_name - self._init_visdom(visdom_info, debug_) - - multiobj_mode = getattr(params, 'multiobj_mode', getattr(self.tracker_class, 'multiobj_mode', 'default')) - - if multiobj_mode == 'default': - tracker = self.create_tracker(params) - if hasattr(tracker, 'initialize_features'): - tracker.initialize_features() - - elif multiobj_mode == 'parallel': - tracker = MultiObjectWrapper(self.tracker_class, params, self.visdom, fast_load=True) - else: - raise ValueError('Unknown multi object mode {}'.format(multiobj_mode)) - - assert os.path.isfile(videofilepath), "Invalid param {}".format(videofilepath) - ", videofilepath must be a valid videofile" - - output_boxes = [] - - camera = threading.Thread(target=self.camera_video, args=(videofilepath, self.skip_frame,)) - camera.start() - print('Camera initiated') - - display_name = 'Display: ' + tracker.params.tracker_name - cv.namedWindow(display_name, cv.WINDOW_NORMAL | cv.WINDOW_KEEPRATIO) - cv.resizeWindow(display_name, 960, 720) - cv.imshow(display_name, self.frame) - - - def _build_init_info(box): - return {'init_bbox': OrderedDict({1: box}), 'init_object_ids': [1, ], 'object_ids': [1, ], - 'sequence_object_ids': [1, ]} - - if self.success is not True: - print("Read frame from {} failed.".format(videofilepath)) - exit(-1) - if optional_box is not None: - assert isinstance(optional_box, (list, tuple)) - assert len(optional_box) == 4, "valid box's foramt is [x,y,w,h]" - tracker.initialize(self.frame, _build_init_info(optional_box)) - output_boxes.append(optional_box) - else: - while True: - if self.camera_flag == True: - frame_disp = self.new_frame.copy() - - cv.putText(frame_disp, 'Select target ROI and press ENTER', (20, 30), cv.FONT_HERSHEY_COMPLEX_SMALL, - 1.5, (0, 0, 255), 1) - - x, y, w, h = cv.selectROI(display_name, frame_disp, fromCenter=False) - init_state = [x, y, w, h] - tracker.initialize(self.new_frame, _build_init_info(init_state)) - output_boxes.append(init_state) - self.camera_flag = False - - break - - else: - time.sleep(0.01) - - - while True: - - if self.camera_flag == True: - frame_disp = self.new_frame.copy() - out = tracker.track(self.new_frame) - - state = [int(s) for s in out['target_bbox'][1]] - output_boxes.append(state) - - cv.rectangle(frame_disp, (state[0], state[1]), (state[2] + state[0], state[3] + state[1]), (0, 0, 255), 2) - - font_color = (0, 0, 255) - cv.putText(frame_disp, 'Tracking!', (20, 30), cv.FONT_HERSHEY_COMPLEX_SMALL, 2, font_color, 1) - cv.putText(frame_disp, 'Press r to reset', (20, 55), cv.FONT_HERSHEY_COMPLEX_SMALL, 2, font_color, 1) - cv.putText(frame_disp, 'Press q to quit', (20, 80), cv.FONT_HERSHEY_COMPLEX_SMALL, 2, font_color, 1) - - # Display the resulting frame - cv.imshow(display_name, frame_disp) - key = cv.waitKey(1) - if key == ord('q'): - self.camera_thread = True - camera.join() - - break - - elif key == ord('r'): - frame_disp = self.new_frame.copy() - - cv.putText(frame_disp, 'Select target ROI and press ENTER', (20, 30), cv.FONT_HERSHEY_COMPLEX_SMALL, 2.5, (0, 0, 255), 1) - - cv.imshow(display_name, frame_disp) - x, y, w, h = cv.selectROI(display_name, frame_disp, fromCenter=False) - init_state = [x, y, w, h] - tracker.initialize(self.new_frame, _build_init_info(init_state)) - output_boxes.append(init_state) - - self.camera_flag = False - - else: - time.sleep(0.01) - - # When everything done, release the capture - self.cap.release() - cv.destroyAllWindows() - - if save_results: - if not os.path.exists(self.results_dir): - os.makedirs(self.results_dir) - video_name = Path(videofilepath).stem - base_results_path = os.path.join(self.results_dir, 'video_{}'.format(video_name)) - - tracked_bb = np.array(output_boxes).astype(int) - bbox_file = '{}.txt'.format(base_results_path) - np.savetxt(bbox_file, tracked_bb, delimiter='\t', fmt='%d') - - - def run_webcam(self, debug=None, visdom_info=None): - """Run the tracker with the webcam. - args: - debug: Debug level. - """ - - params = self.get_parameters() - - debug_ = debug - if debug is None: - debug_ = getattr(params, 'debug', 0) - params.debug = debug_ - - params.tracker_name = self.name - params.param_name = self.parameter_name - - self._init_visdom(visdom_info, debug_) - - multiobj_mode = getattr(params, 'multiobj_mode', getattr(self.tracker_class, 'multiobj_mode', 'default')) - - if multiobj_mode == 'default': - tracker = self.create_tracker(params) - elif multiobj_mode == 'parallel': - tracker = MultiObjectWrapper(self.tracker_class, params, self.visdom, fast_load=True) - else: - raise ValueError('Unknown multi object mode {}'.format(multiobj_mode)) - - class UIControl: - def __init__(self): - self.mode = 'init' # init, select, track - self.target_tl = (-1, -1) - self.target_br = (-1, -1) - self.new_init = False - - def mouse_callback(self, event, x, y, flags, param): - if event == cv.EVENT_LBUTTONDOWN and self.mode == 'init': - self.target_tl = (x, y) - self.target_br = (x, y) - self.mode = 'select' - elif event == cv.EVENT_MOUSEMOVE and self.mode == 'select': - self.target_br = (x, y) - elif event == cv.EVENT_LBUTTONDOWN and self.mode == 'select': - self.target_br = (x, y) - self.mode = 'init' - self.new_init = True - - def get_tl(self): - return self.target_tl if self.target_tl[0] < self.target_br[0] else self.target_br - - def get_br(self): - return self.target_br if self.target_tl[0] < self.target_br[0] else self.target_tl - - def get_bb(self): - tl = self.get_tl() - br = self.get_br() - - bb = [min(tl[0], br[0]), min(tl[1], br[1]), abs(br[0] - tl[0]), abs(br[1] - tl[1])] - return bb - - ui_control = UIControl() - - camera = threading.Thread(target=self.camera_rtsp, args=(self.rtsp,)) - camera.start() - print('Camera initiated') - - display_name = 'Display: ' + tracker.params.tracker_name - cv.namedWindow(display_name, cv.WINDOW_NORMAL | cv.WINDOW_KEEPRATIO) - cv.resizeWindow(display_name, 960, 720) - - cv.setMouseCallback(display_name, ui_control.mouse_callback) - - next_object_id = 1 - sequence_object_ids = [] - prev_output = OrderedDict() - - while True: - if self.camera_flag == True: - frame_disp = self.frame.copy() - - info = OrderedDict() - info['previous_output'] = prev_output - - if ui_control.new_init: - ui_control.new_init = False - init_state = ui_control.get_bb() - - info['init_object_ids'] = [next_object_id, ] - info['init_bbox'] = OrderedDict({next_object_id: init_state}) - sequence_object_ids.append(next_object_id) - - next_object_id += 1 - - # Draw box - if ui_control.mode == 'select': - cv.rectangle(frame_disp, ui_control.get_tl(), ui_control.get_br(), (255, 0, 0), 2) - - if len(sequence_object_ids) > 0: - info['sequence_object_ids'] = sequence_object_ids - out = tracker.track(self.frame, info) - prev_output = OrderedDict(out) - - if 'segmentation' in out: - frame_disp = overlay_mask(frame_disp, out['segmentation']) - - if 'target_bbox' in out: - for obj_id, state in out['target_bbox'].items(): - state = [int(s) for s in state] - cv.rectangle(frame_disp, (state[0], state[1]), (state[2] + state[0], state[3] + state[1]), - _tracker_disp_colors[obj_id], 5) - - # Put text - font_color = (0, 255, 0) - cv.putText(frame_disp, 'Select target', (20, 30), cv.FONT_HERSHEY_COMPLEX_SMALL, 1, font_color, 1) - cv.putText(frame_disp, 'Press r to reset', (20, 55), cv.FONT_HERSHEY_COMPLEX_SMALL, 1, font_color, 1) - cv.putText(frame_disp, 'Press q to quit', (20, 85), cv.FONT_HERSHEY_COMPLEX_SMALL, 1, font_color, 1) - - # Display the resulting frame - cv.imshow(display_name, frame_disp) - key = cv.waitKey(1) - if key == ord('q'): - self.camera_thread = True - camera.join() - - break - - elif key == ord('r'): - next_object_id = 1 - sequence_object_ids = [] - prev_output = OrderedDict() - - info = OrderedDict() - - info['object_ids'] = [] - info['init_object_ids'] = [] - info['init_bbox'] = OrderedDict() - tracker.initialize(self.frame, info) - ui_control.mode = 'init' - - self.camera_flag = False - - else: - time.sleep(0.005) - - - # When everything done, release the capture - self.cap.release() - cv.destroyAllWindows() - - - def run_vot2020(self, debug=None, visdom_info=None): - params = self.get_parameters() - params.tracker_name = self.name - params.param_name = self.parameter_name - params.run_id = self.run_id - - debug_ = debug - if debug is None: - debug_ = getattr(params, 'debug', 0) - - if debug is None: - visualization_ = getattr(params, 'visualization', False) - else: - visualization_ = True if debug else False - - params.visualization = visualization_ - params.debug = debug_ - - self._init_visdom(visdom_info, debug_) - - tracker = self.create_tracker(params) - tracker.initialize_features() - - output_segmentation = tracker.predicts_segmentation_mask() - - import pytracking.evaluation.vot2020 as vot - - def _convert_anno_to_list(vot_anno): - vot_anno = [vot_anno[0], vot_anno[1], vot_anno[2], vot_anno[3]] - return vot_anno - - def _convert_image_path(image_path): - return image_path - - """Run tracker on VOT.""" - - if output_segmentation: - handle = vot.VOT("mask") - else: - handle = vot.VOT("rectangle") - - vot_anno = handle.region() - - image_path = handle.frame() - if not image_path: - return - image_path = _convert_image_path(image_path) - - image = self._read_image(image_path) - - if output_segmentation: - vot_anno_mask = vot.make_full_size(vot_anno, (image.shape[1], image.shape[0])) - bbox = masks_to_bboxes(torch.from_numpy(vot_anno_mask), fmt='t').squeeze().tolist() - else: - bbox = _convert_anno_to_list(vot_anno) - vot_anno_mask = None - - out = tracker.initialize(image, {'init_mask': vot_anno_mask, 'init_bbox': bbox}) - - if out is None: - out = {} - prev_output = OrderedDict(out) - - # Track - while True: - image_path = handle.frame() - if not image_path: - break - image_path = _convert_image_path(image_path) - - image = self._read_image(image_path) - - info = OrderedDict() - info['previous_output'] = prev_output - - out = tracker.track(image, info) - prev_output = OrderedDict(out) - - if output_segmentation: - pred = out['segmentation'].astype(np.uint8) - else: - state = out['target_bbox'] - pred = vot.Rectangle(*state) - handle.report(pred, 1.0) - - segmentation = out['segmentation'] if 'segmentation' in out else None - if self.visdom is not None: - tracker.visdom_draw_tracking(image, out['target_bbox'], segmentation) - elif tracker.params.visualization: - self.visualize(image, out['target_bbox'], segmentation) - - - def run_vot(self, debug=None, visdom_info=None): - params = self.get_parameters() - params.tracker_name = self.name - params.param_name = self.parameter_name - params.run_id = self.run_id - - debug_ = debug - if debug is None: - debug_ = getattr(params, 'debug', 0) - - if debug is None: - visualization_ = getattr(params, 'visualization', False) - else: - visualization_ = True if debug else False - - params.visualization = visualization_ - params.debug = debug_ - - self._init_visdom(visdom_info, debug_) - - tracker = self.create_tracker(params) - tracker.initialize_features() - - import pytracking.evaluation.vot as vot - - def _convert_anno_to_list(vot_anno): - vot_anno = [vot_anno[0][0][0], vot_anno[0][0][1], vot_anno[0][1][0], vot_anno[0][1][1], - vot_anno[0][2][0], vot_anno[0][2][1], vot_anno[0][3][0], vot_anno[0][3][1]] - return vot_anno - - def _convert_image_path(image_path): - image_path_new = image_path[20:- 2] - return "".join(image_path_new) - - """Run tracker on VOT.""" - - handle = vot.VOT("polygon") - - vot_anno_polygon = handle.region() - vot_anno_polygon = _convert_anno_to_list(vot_anno_polygon) - - init_state = convert_vot_anno_to_rect(vot_anno_polygon, tracker.params.vot_anno_conversion_type) - - image_path = handle.frame() - if not image_path: - return - image_path = _convert_image_path(image_path) - - image = self._read_image(image_path) - tracker.initialize(image, {'init_bbox': init_state}) - - # Track - while True: - image_path = handle.frame() - if not image_path: - break - image_path = _convert_image_path(image_path) - - image = self._read_image(image_path) - out = tracker.track(image) - state = out['target_bbox'] - - handle.report(vot.Rectangle(state[0], state[1], state[2], state[3])) - - segmentation = out['segmentation'] if 'segmentation' in out else None - if self.visdom is not None: - tracker.visdom_draw_tracking(image, out['target_bbox'], segmentation) - elif tracker.params.visualization: - self.visualize(image, out['target_bbox'], segmentation) - - - def get_parameters(self): - """Get parameters.""" - param_module = importlib.import_module('pytracking.parameter.{}.{}'.format(self.name, self.parameter_name)) - params = param_module.parameters() - return params - - - def init_visualization(self): - self.pause_mode = False - self.fig, self.ax = plt.subplots(1) - self.fig.canvas.mpl_connect('key_press_event', self.press) - plt.tight_layout() - - - def visualize(self, image, state, segmentation=None): - self.ax.cla() - self.ax.imshow(image) - if segmentation is not None: - self.ax.imshow(segmentation, alpha=0.5) - - if isinstance(state, (OrderedDict, dict)): - boxes = [v for k, v in state.items()] - else: - boxes = (state,) - - for i, box in enumerate(boxes, start=1): - col = _tracker_disp_colors[i] - col = [float(c) / 255.0 for c in col] - rect = patches.Rectangle((box[0], box[1]), box[2], box[3], linewidth=1, edgecolor=col, facecolor='none') - self.ax.add_patch(rect) - - if getattr(self, 'gt_state', None) is not None: - gt_state = self.gt_state - rect = patches.Rectangle((gt_state[0], gt_state[1]), gt_state[2], gt_state[3], linewidth=1, edgecolor='g', facecolor='none') - self.ax.add_patch(rect) - self.ax.set_axis_off() - self.ax.axis('equal') - draw_figure(self.fig) - - if self.pause_mode: - keypress = False - while not keypress: - keypress = plt.waitforbuttonpress() - - def reset_tracker(self): - pass - - def press(self, event): - if event.key == 'p': - self.pause_mode = not self.pause_mode - print("Switching pause mode!") - elif event.key == 'r': - self.reset_tracker() - print("Resetting target pos to gt!") - - def _read_image(self, image_file: str): - im = cv.imread(image_file) - return cv.cvtColor(im, cv.COLOR_BGR2RGB) - From 91403ac65798215c0d272eb1fdb01e198c0c6fc8 Mon Sep 17 00:00:00 2001 From: Ahsan Raza Date: Wed, 20 Jul 2022 12:47:25 +0500 Subject: [PATCH 4/8] Updated for Ground Station Communication --- pytracking/evaluation/tracker.py | 767 +++++++++++++++++++++++++++++++ 1 file changed, 767 insertions(+) create mode 100644 pytracking/evaluation/tracker.py diff --git a/pytracking/evaluation/tracker.py b/pytracking/evaluation/tracker.py new file mode 100644 index 00000000..e088a0ac --- /dev/null +++ b/pytracking/evaluation/tracker.py @@ -0,0 +1,767 @@ +''' +Edit the tracker.py file accordingly. + +Set self.rtsp to your rtsp stream + +Set self.localIP as it's the Server IP (your PC) + +Set self.localPort as it's the Server communication port + +''' + + +import importlib +import os +import numpy as np +from collections import OrderedDict +from pytracking.evaluation.environment import env_settings +import time +import cv2 as cv +from pytracking.utils.visdom import Visdom +import matplotlib.pyplot as plt +import matplotlib.patches as patches +from pytracking.utils.plotting import draw_figure, overlay_mask +from pytracking.evaluation.multi_object_wrapper import MultiObjectWrapper +from pathlib import Path + +import threading + +import socket + +_tracker_disp_colors = {1: (0, 255, 0), 2: (0, 0, 255), 3: (255, 0, 0), + 4: (255, 255, 255), 5: (0, 0, 0), 6: (0, 255, 128), + 7: (123, 123, 123), 8: (255, 128, 0), 9: (128, 0, 255)} + + +def trackerlist(name: str, parameter_name: str, run_ids = None, display_name: str = None): + """Generate list of trackers. + args: + name: Name of tracking method. + parameter_name: Name of parameter file. + run_ids: A single or list of run_ids. + display_name: Name to be displayed in the result plots. + """ + if run_ids is None or isinstance(run_ids, int): + run_ids = [run_ids] + return [Tracker(name, parameter_name, run_id, display_name) for run_id in run_ids] + + +class Tracker: + """Wraps the tracker for evaluation and running purposes. + args: + name: Name of tracking method. + parameter_name: Name of parameter file. + run_id: The run id. + display_name: Name to be displayed in the result plots. + """ + + def __init__(self, name: str, parameter_name: str, run_id: int = None, display_name: str = None): + assert run_id is None or isinstance(run_id, int) + + # Initializing Parameters + + self.name = name + self.parameter_name = parameter_name + self.run_id = run_id + self.display_name = display_name + + # RTSP Stream + self.rtsp = 'rtsp://...' + + # Number of frames to skip while processing + self.skip_frame = 1 + self.camera_flag = False + self.distance_flag = False # Flag for distance calculation + + # Socket programming parameters + self.localIP = "127.0.0.1" # Server IP + self.localPort = 8554 # Server Port + self.bufferSize = 1024 + self.initBB = (0,0,0,0) + self.initAA = (0,0,0,0) + + # New parameters for NAHL + self.tilt_y = 0 # Title Angle of Drone + self.tilt_x = 0 # Roll Angle of Drone + self.height = 0 # Height of Drone in meters + self.p_pitch = 0 # Camera specification pixel pitch + self.F_lens = 0 # Camera specification lens focal length, changes with zoom + self.Text_File = [] + self.liny = 0 + self.linx = 0 + + self.BB_centroid_x = 0 # Bounding Box Centroid_x + self.BB_centroid_y = 0 # Bounding Box Centroid_y + + env = env_settings() + if self.run_id is None: + self.results_dir = '{}/{}/{}'.format(env.results_path, self.name, self.parameter_name) + self.segmentation_dir = '{}/{}/{}'.format(env.segmentation_path, self.name, self.parameter_name) + else: + self.results_dir = '{}/{}/{}_{:03d}'.format(env.results_path, self.name, self.parameter_name, self.run_id) + self.segmentation_dir = '{}/{}/{}_{:03d}'.format(env.segmentation_path, self.name, self.parameter_name, self.run_id) + + tracker_module_abspath = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'tracker', self.name)) + if os.path.isdir(tracker_module_abspath): + tracker_module = importlib.import_module('pytracking.tracker.{}'.format(self.name)) + self.tracker_class = tracker_module.get_tracker_class() + else: + self.tracker_class = None + + self.visdom = None + + def connection(self, localIP, localPort): + + # Create a datagram socket and bind IP/Port Address + + UDPServerSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + UDPServerSocket.bind((localIP, localPort)) + + return UDPServerSocket + + def receive_msg(self, conn, bufferSize): + + bytesAddressPair = conn.recvfrom(bufferSize) + + message = b'' + message = bytesAddressPair[0] + message = message.decode('utf-8') + address = bytesAddressPair[1] + + return message, address + + + def send_msg(self, conn, address, box): + + payload = str(box) + payload = payload.encode('utf-8') + conn.sendto(payload, address) + + + def _init_visdom(self, visdom_info, debug): + visdom_info = {} if visdom_info is None else visdom_info + self.pause_mode = False + self.step = False + if debug > 0 and visdom_info.get('use_visdom', True): + try: + self.visdom = Visdom(debug, {'handler': self._visdom_ui_handler, 'win_id': 'Tracking'}, + visdom_info=visdom_info) + + # Show help + help_text = 'You can pause/unpause the tracker by pressing ''space'' with the ''Tracking'' window ' \ + 'selected. During paused mode, you can track for one frame by pressing the right arrow key.' \ + 'To enable/disable plotting of a data block, tick/untick the corresponding entry in ' \ + 'block list.' + self.visdom.register(help_text, 'text', 1, 'Help') + except: + time.sleep(0.5) + print('!!! WARNING: Visdom could not start, so using matplotlib visualization instead !!!\n' + '!!! Start Visdom in a separate terminal window by typing \'visdom\' !!!') + + def _visdom_ui_handler(self, data): + if data['event_type'] == 'KeyPress': + if data['key'] == ' ': + self.pause_mode = not self.pause_mode + + elif data['key'] == 'ArrowRight' and self.pause_mode: + self.step = True + + + def create_tracker(self, params): + tracker = self.tracker_class(params) + tracker.visdom = self.visdom + return tracker + + + def camera_video(self, videofilepath, sf): + + self.cap = cv.VideoCapture(videofilepath) + + txt = videofilepath.split("/") + txt = txt[2].split(".") + txt = txt[0] + + self.camera_thread = False + + # VIDEO Writing + + frame_width = int(self.cap.get(3)) + frame_height = int(self.cap.get(4)) + self.out = cv.VideoWriter(txt + '_Result.avi',cv.VideoWriter_fourcc('M','J','P','G'), 15, (frame_width,frame_height)) + + counter = 0 + skip_frame = sf + + while True: + if self.camera_flag == False: + self.success, self.frame = self.cap.read() + + counter += 1 + + if counter == skip_frame + 1: + self.camera_flag = True + + self.new_frame = self.frame + + counter = 0 + + if self.success == False: + break + + if self.camera_thread == True: + break + + time.sleep(0.005) + + def camera_rtsp(self, rtsp): + + while True: + + self.cap = cv.VideoCapture(rtsp) + + self.camera_thread = False + + while (self.cap.isOpened() == True): + self.success, self.frame = self.cap.read() + self.camera_flag = True + + if self.success == False: + break + + if self.camera_thread == True: + break + + time.sleep(0.005) + + if self.camera_thread == True: + break + + + def run_video(self, videofilepath, optional_box=None, debug=None, visdom_info=None, save_results=False): + """Run the tracker with the video file. + args: + debug: Debug level. + """ + + params = self.get_parameters() + + debug_ = debug + if debug is None: + debug_ = getattr(params, 'debug', 0) + params.debug = debug_ + + params.tracker_name = self.name + params.param_name = self.parameter_name + self._init_visdom(visdom_info, debug_) + + multiobj_mode = getattr(params, 'multiobj_mode', getattr(self.tracker_class, 'multiobj_mode', 'default')) + + if multiobj_mode == 'default': + tracker = self.create_tracker(params) + if hasattr(tracker, 'initialize_features'): + tracker.initialize_features() + + elif multiobj_mode == 'parallel': + tracker = MultiObjectWrapper(self.tracker_class, params, self.visdom, fast_load=True) + else: + raise ValueError('Unknown multi object mode {}'.format(multiobj_mode)) + + assert os.path.isfile(videofilepath), "Invalid param {}".format(videofilepath) + ", videofilepath must be a valid videofile" + + output_boxes = [] + + camera = threading.Thread(target=self.camera_video, args=(videofilepath, self.skip_frame,)) + camera.start() + print('Camera initiated') + + + while True: + if self.camera_flag == True: + break + + display_name = 'Display: ' + tracker.params.tracker_name + cv.namedWindow(display_name, cv.WINDOW_NORMAL | cv.WINDOW_KEEPRATIO) + cv.resizeWindow(display_name, 960, 720) + cv.imshow(display_name, self.frame) + + + def _build_init_info(box): + return {'init_bbox': OrderedDict({1: box}), 'init_object_ids': [1, ], 'object_ids': [1, ], + 'sequence_object_ids': [1, ]} + + if self.success is not True: + print("Read frame from {} failed.".format(videofilepath)) + exit(-1) + if optional_box is not None: + assert isinstance(optional_box, (list, tuple)) + assert len(optional_box) == 4, "valid box's foramt is [x,y,w,h]" + tracker.initialize(self.frame, _build_init_info(optional_box)) + output_boxes.append(optional_box) + else: + while True: + if self.camera_flag == True: + frame_disp = self.new_frame.copy() + + cv.putText(frame_disp, 'Select target ROI and press ENTER', (20, 30), cv.FONT_HERSHEY_COMPLEX_SMALL, + 1.5, (0, 0, 255), 1) + + x, y, w, h = cv.selectROI(display_name, frame_disp, fromCenter=False) + init_state = [x, y, w, h] + tracker.initialize(self.new_frame, _build_init_info(init_state)) + output_boxes.append(init_state) + self.camera_flag = False + + break + + else: + time.sleep(0.01) + + while True: + + if self.camera_flag == True: + frame_disp = self.new_frame.copy() + t1 = time.time() + out = tracker.track(self.new_frame) + t2 = time.time() - t1 + #print('FPS: ', 1/t2) + + state = [int(s) for s in out['target_bbox'][1]] + output_boxes.append(state) + + cv.rectangle(frame_disp, (state[0], state[1]), (state[2] + state[0], state[3] + state[1]), (0, 0, 255), 2) + + font_color = (0, 0, 255) + cv.putText(frame_disp, 'Tracking!', (20, 30), cv.FONT_HERSHEY_COMPLEX_SMALL, 2, font_color, 1) + cv.putText(frame_disp, 'Press r to reset', (20, 55), cv.FONT_HERSHEY_COMPLEX_SMALL, 2, font_color, 1) + cv.putText(frame_disp, 'Press q to quit', (20, 80), cv.FONT_HERSHEY_COMPLEX_SMALL, 2, font_color, 1) + + # Tracked BoundBox Centroid + self.BB_centroid_x = state[0] + int(state[2]/2) + self.BB_centroid_y = state[1] + int(state[3]/2) + + if self.distance_flag == True: + self.distance_x , self.distance_y = self.im2distance(self.new_frame,self.BB_centroid_x,self.BB_centroid_y,self.liny,self.linx) + lst = [self.distance_x, self.distance_y] + + self.Text_File.append(lst) + + # Display the resulting frame + cv.imshow(display_name, frame_disp) + self.out.write(frame_disp) + key = cv.waitKey(1) + if key == ord('q'): + self.camera_thread = True + camera.join() + + break + + elif key == ord('r'): + frame_disp = self.new_frame.copy() + + cv.putText(frame_disp, 'Select target ROI and press ENTER', (20, 30), cv.FONT_HERSHEY_COMPLEX_SMALL, 2.5, (0, 0, 255), 1) + + cv.imshow(display_name, frame_disp) + x, y, w, h = cv.selectROI(display_name, frame_disp, fromCenter=False) + init_state = [x, y, w, h] + tracker.initialize(self.new_frame, _build_init_info(init_state)) + output_boxes.append(init_state) + + self.camera_flag = False + + else: + time.sleep(0.01) + + # When everything done, release the capture + self.cap.release() + cv.destroyAllWindows() + + if save_results: + if not os.path.exists(self.results_dir): + os.makedirs(self.results_dir) + video_name = Path(videofilepath).stem + base_results_path = os.path.join(self.results_dir, 'video_{}'.format(video_name)) + + tracked_bb = np.array(output_boxes).astype(int) + bbox_file = '{}.txt'.format(base_results_path) + np.savetxt(bbox_file, tracked_bb, delimiter='\t', fmt='%d') + + def run_video_comm(self, optional_box=None, debug=None, visdom_info=None, save_results=False): + """Run the tracker with the communication with the Ground Station (socket programming) using rtsp. + args: + debug: Debug level. + """ + + params = self.get_parameters() + + debug_ = debug + if debug is None: + debug_ = getattr(params, 'debug', 0) + params.debug = debug_ + + params.tracker_name = self.name + params.param_name = self.parameter_name + self._init_visdom(visdom_info, debug_) + + multiobj_mode = getattr(params, 'multiobj_mode', getattr(self.tracker_class, 'multiobj_mode', 'default')) + + if multiobj_mode == 'default': + tracker = self.create_tracker(params) + if hasattr(tracker, 'initialize_features'): + tracker.initialize_features() + + elif multiobj_mode == 'parallel': + tracker = MultiObjectWrapper(self.tracker_class, params, self.visdom, fast_load=True) + else: + raise ValueError('Unknown multi object mode {}'.format(multiobj_mode)) + + while True: + + camera = threading.Thread(target=self.camera_rtsp, args=(self.rtsp,)) + camera.start() + print('Camera thread Initiated') + + output_boxes = [] + + while True: + if self.camera_flag == True: + break + + self.conn = self.connection(self.localIP,self.localPort) + + while True: + self.message, self.address = self.receive_msg(self.conn, self.bufferSize) + if self.message == "Connection": + print('Connection Established.') + Mess_conn = "Connected" + self.send_msg(self.conn, self.address, Mess_conn) + + elif self.message == "Send Tracker Coordinates": + print('message', self.message) + cv.destroyAllWindows() + self.conn.close() + + elif self.message == "Close": + print('Ground Station is Closed, waiting for reconnection ...') + + + elif self.message == "Terminate": + print('Program terminated from Ground Station.') + + self.camera_thread = True + camera.join() + + self.cap.release() + cv.destroyAllWindows() + self.conn.close() + + return + + else: + self.initBB = (int(self.message.split(",")[0][1:]), int(self.message.split(",")[1][1:]), int(self.message.split(",")[2][1:]), + int(self.message.split(",")[3][1:(len(self.message.split(",")[3])-1)])) + print('Bounding Box from GCS:', self.initBB) + + break + + while True: + + if self.camera_flag == True: + + def _build_init_info(box): + return {'init_bbox': OrderedDict({1: box}), 'init_object_ids': [1, ], 'object_ids': [1, ], + 'sequence_object_ids': [1, ]} + + if self.initAA[0] != self.initBB[0] or self.initAA[1] != self.initBB[1] or self.initAA[2] != self.initBB[2] or self.initAA[3] != self.initBB[3]: + init_state = self.initBB + tracker.initialize(self.frame, _build_init_info(init_state)) + output_boxes.append(init_state) + + self.initAA = self.initBB + frame_disp = self.frame.copy() + + if self.initBB is not None: + + out = tracker.track(self.frame) + state = [int(s) for s in out['target_bbox'][1]] + output_boxes.append(state) + + cv.rectangle(frame_disp, (state[0], state[1]), (state[2] + state[0], state[3] + state[1]), + (0, 255, 0), 5) + + # Tracked BoundBox Centroid + self.BB_centroid_x = state[0] + int(state[2]/2) + self.BB_centroid_y = state[1] + int(state[3]/2) + + if self.distance_flag == True: + self.distance_x , self.distance_y = self.im2distance(self.frame,self.BB_centroid_x,self.BB_centroid_y,self.liny,self.linx) + lst = [self.distance_x, self.distance_y] + + self.Text_File.append(lst) + + self.message2, self.address2 = self.receive_msg(self.conn, self.bufferSize) + + if self.message2 == "Send Tracker Coordinates": + + print('state', state) + self.send_msg(self.conn, self.address2, state) + + elif self.message2 == "Close": + + print('Ground Station is Closed, waiting for reconnection ...') + cv.destroyAllWindows() + + self.camera_thread = True + camera.join() + + self.initBB = (0,0,0,0) + self.initAA = (0,0,0,0) + + break + + elif self.message2 == "Terminate": + print('Program terminated from Ground Station') + + self.camera_thread = True + camera.join() + + self.cap.release() + cv.destroyAllWindows() + self.conn.close() + + return + + self.camera_flag = False + + else: + time.sleep(0.01) + + # When everything done, release the capture + self.cap.release() + cv.destroyAllWindows() + self.conn.close() + + + def run_webcam(self, debug=None, visdom_info=None): + """Run the tracker with the webcam. + args: + debug: Debug level. + """ + + params = self.get_parameters() + + debug_ = debug + if debug is None: + debug_ = getattr(params, 'debug', 0) + params.debug = debug_ + + params.tracker_name = self.name + params.param_name = self.parameter_name + + self._init_visdom(visdom_info, debug_) + + multiobj_mode = getattr(params, 'multiobj_mode', getattr(self.tracker_class, 'multiobj_mode', 'default')) + + if multiobj_mode == 'default': + tracker = self.create_tracker(params) + elif multiobj_mode == 'parallel': + tracker = MultiObjectWrapper(self.tracker_class, params, self.visdom, fast_load=True) + else: + raise ValueError('Unknown multi object mode {}'.format(multiobj_mode)) + + class UIControl: + def __init__(self): + self.mode = 'init' # init, select, track + self.target_tl = (-1, -1) + self.target_br = (-1, -1) + self.new_init = False + + def mouse_callback(self, event, x, y, flags, param): + if event == cv.EVENT_LBUTTONDOWN and self.mode == 'init': + self.target_tl = (x, y) + self.target_br = (x, y) + self.mode = 'select' + elif event == cv.EVENT_MOUSEMOVE and self.mode == 'select': + self.target_br = (x, y) + elif event == cv.EVENT_LBUTTONDOWN and self.mode == 'select': + self.target_br = (x, y) + self.mode = 'init' + self.new_init = True + + def get_tl(self): + return self.target_tl if self.target_tl[0] < self.target_br[0] else self.target_br + + def get_br(self): + return self.target_br if self.target_tl[0] < self.target_br[0] else self.target_tl + + def get_bb(self): + tl = self.get_tl() + br = self.get_br() + + bb = [min(tl[0], br[0]), min(tl[1], br[1]), abs(br[0] - tl[0]), abs(br[1] - tl[1])] + return bb + + ui_control = UIControl() + + camera = threading.Thread(target=self.camera_rtsp, args=(self.rtsp,)) + camera.start() + print('Camera initiated') + + display_name = 'Display: ' + tracker.params.tracker_name + cv.namedWindow(display_name, cv.WINDOW_NORMAL | cv.WINDOW_KEEPRATIO) + cv.resizeWindow(display_name, 960, 720) + + cv.setMouseCallback(display_name, ui_control.mouse_callback) + + next_object_id = 1 + sequence_object_ids = [] + prev_output = OrderedDict() + + while True: + if self.camera_flag == True: + break + + while True: + if self.camera_flag == True: + frame_disp = self.frame.copy() + + info = OrderedDict() + info['previous_output'] = prev_output + + if ui_control.new_init: + ui_control.new_init = False + init_state = ui_control.get_bb() + + info['init_object_ids'] = [next_object_id, ] + info['init_bbox'] = OrderedDict({next_object_id: init_state}) + sequence_object_ids.append(next_object_id) + + next_object_id += 1 + + # Draw box + if ui_control.mode == 'select': + cv.rectangle(frame_disp, ui_control.get_tl(), ui_control.get_br(), (255, 0, 0), 2) + + if len(sequence_object_ids) > 0: + info['sequence_object_ids'] = sequence_object_ids + out = tracker.track(self.frame, info) + prev_output = OrderedDict(out) + + if 'segmentation' in out: + frame_disp = overlay_mask(frame_disp, out['segmentation']) + + if 'target_bbox' in out: + for obj_id, state in out['target_bbox'].items(): + state = [int(s) for s in state] + cv.rectangle(frame_disp, (state[0], state[1]), (state[2] + state[0], state[3] + state[1]), + _tracker_disp_colors[obj_id], 5) + + # Tracked BoundBox Centroid + self.BB_centroid_x = state[0] + int(state[2]/2) + self.BB_centroid_y = state[1] + int(state[3]/2) + + if self.distance_flag == True: + self.distance_x , self.distance_y = self.im2distance(self.frame, self.BB_centroid_x, self.BB_centroid_y, self.liny, self.linx) + lst = [self.distance_x, self.distance_y] + + self.Text_File.append(lst) + + # Put text + font_color = (0, 255, 0) + cv.putText(frame_disp, 'Select target', (20, 30), cv.FONT_HERSHEY_COMPLEX_SMALL, 1, font_color, 1) + cv.putText(frame_disp, 'Press r to reset', (20, 55), cv.FONT_HERSHEY_COMPLEX_SMALL, 1, font_color, 1) + cv.putText(frame_disp, 'Press q to quit', (20, 85), cv.FONT_HERSHEY_COMPLEX_SMALL, 1, font_color, 1) + + # Display the resulting frame + cv.imshow(display_name, frame_disp) + self.out.write(frame_disp) + key = cv.waitKey(1) + if key == ord('q'): + self.camera_thread = True + camera.join() + + break + + elif key == ord('r'): + next_object_id = 1 + sequence_object_ids = [] + prev_output = OrderedDict() + + info = OrderedDict() + + info['object_ids'] = [] + info['init_object_ids'] = [] + info['init_bbox'] = OrderedDict() + tracker.initialize(self.frame, info) + ui_control.mode = 'init' + + self.camera_flag = False + + else: + time.sleep(0.005) + + + # When everything done, release the capture + self.cap.release() + cv.destroyAllWindows() + + + def get_parameters(self): + """Get parameters.""" + param_module = importlib.import_module('pytracking.parameter.{}.{}'.format(self.name, self.parameter_name)) + params = param_module.parameters() + return params + + + def init_visualization(self): + self.pause_mode = False + self.fig, self.ax = plt.subplots(1) + self.fig.canvas.mpl_connect('key_press_event', self.press) + plt.tight_layout() + + + def visualize(self, image, state, segmentation=None): + self.ax.cla() + self.ax.imshow(image) + if segmentation is not None: + self.ax.imshow(segmentation, alpha=0.5) + + if isinstance(state, (OrderedDict, dict)): + boxes = [v for k, v in state.items()] + else: + boxes = (state,) + + for i, box in enumerate(boxes, start=1): + col = _tracker_disp_colors[i] + col = [float(c) / 255.0 for c in col] + rect = patches.Rectangle((box[0], box[1]), box[2], box[3], linewidth=1, edgecolor=col, facecolor='none') + self.ax.add_patch(rect) + + if getattr(self, 'gt_state', None) is not None: + gt_state = self.gt_state + rect = patches.Rectangle((gt_state[0], gt_state[1]), gt_state[2], gt_state[3], linewidth=1, edgecolor='g', facecolor='none') + self.ax.add_patch(rect) + self.ax.set_axis_off() + self.ax.axis('equal') + draw_figure(self.fig) + + if self.pause_mode: + keypress = False + while not keypress: + keypress = plt.waitforbuttonpress() + + def reset_tracker(self): + pass + + def press(self, event): + if event.key == 'p': + self.pause_mode = not self.pause_mode + print("Switching pause mode!") + elif event.key == 'r': + self.reset_tracker() + print("Resetting target pos to gt!") + + def _read_image(self, image_file: str): + im = cv.imread(image_file) + return cv.cvtColor(im, cv.COLOR_BGR2RGB) + From 51095b8f443c9786a37c99758a2b0d840a383f98 Mon Sep 17 00:00:00 2001 From: Ahsan Raza Date: Wed, 20 Jul 2022 12:52:31 +0500 Subject: [PATCH 5/8] Ground Station (Client) This represents Ground Station (Client) and needs to be placed in another PC which will act as Client to communicate with Server (run_video_communication.py) --- Ground_Station.py | 358 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 358 insertions(+) create mode 100644 Ground_Station.py diff --git a/Ground_Station.py b/Ground_Station.py new file mode 100644 index 00000000..f09669c6 --- /dev/null +++ b/Ground_Station.py @@ -0,0 +1,358 @@ +''' +The Ground Station represents a client in the communication with pytracking (server). + +self.rtsp variable represents an rtsp stream, which should be set accordingly. + +self.serverAddressPort represents server ID and port for communication. + +Workflow of the Ground Station: + +1. Tries to connect with the server, unitl it is connected. + +2. After connection establishment, the ground station pop-up a window that shows continuous video feed. + Select a target object by drawing a bounding box using left mouse click. + +3. The Bounding Box is sent to the server end to initialize the tracker. + +4. The server after the initialization starts tracking the target object and sends back the tracked bounding box to Ground Station. + +5. The Ground Station displays the countinuous receving tracked object. + +Press Q for quit the Ground Station +Press R to re-select the object for tracking +Press T to Terminate both Ground Station and Server + +''' + +import cv2 +from win32api import GetSystemMetrics +import socket +import threading +import time + +class Tracking(): + + def __init__(self): + + # Initializing Parameters + + self.rect = (0,0,0,0) + self.startPoint = False + self.endPoint = False + self.Flag = False + self.init_flag = False + self.camera_flag = False + self.rec_flag = False + self.flag_recv = False + self.flag_sending = False + + # RTSP Stream + self.rtsp = 'rtsp://admin:admin1234@192.168.1.196:554/cam/realmonitor?channel=1&subtype=0' + #self.rtsp = "rtsp://192.168.1.176:8554/unicast" + #self.rtsp = 0 + + self.initBB = (0,0,0,0) + self.initAA = (0,0,0,0) + + # Server ID and Port No + self.serverAddressPort = ("192.168.1.176", 8554) + self.bufferSize = 1024 + + + def receive_msg(self, conn, bufferSize): + + bytesAddressPair = conn.recvfrom(bufferSize) + + message = b'' + message = bytesAddressPair[0] + message = message.decode('utf-8') + address = bytesAddressPair[1] + + return message, address + + def send_msg(self, conn, address, box): + + payload = str(box) + payload = payload.encode('utf-8') + conn.sendto(payload, address) + + def sending(self): + counter = 0 + while self.flag_recv == False: + Mess_conn = "Connection" + self.send_msg(self.UDPClientSocket, self.serverAddressPort, Mess_conn) + + if self.flag_sending == True: + break + + counter += 1 + if counter == 3: + print('Trying to connect ...') + counter = 0 + + time.sleep(1) + + def closing_threads(self, cm, sd, con): + + self.thread_flag = True + cm.join() + + self.flag_sending = True + sd.join() + + self.thread_conn = True + con.join() + + def connection(self): + + self.thread_conn = False + + msg_conn, addr = self.receive_msg(self.UDPClientSocket, self.bufferSize) + if msg_conn == "Connected": + print("Connection Establised.") + + self.flag_recv = True + + while True: + if self.init_flag == True: + if msg_conn == "Connected": + + if self.init_flag == True: + self.send_msg(self.UDPClientSocket, self.serverAddressPort, self.initialization) + + if self.Flag == True: + Message2 = "Send Tracker Coordinates" + self.send_msg(self.UDPClientSocket, self.serverAddressPort, Message2) + + msg, addr = self.receive_msg(self.UDPClientSocket, self.bufferSize) + + if self.thread_conn == True: + break + + if msg == "Tracker Lost": + print('Tracker Lost the Object') + cv2.destroyAllWindows() + break + + else: + self.rec_flag = True + Trackerbox = (float(msg.split(",")[0][1:]), float(msg.split(",")[1][1:]), float(msg.split(",")[2][1:]), float(msg.split(",")[3][1:(len(msg.split(",")[3])-1)])) + + self.Trackerbox = ((1/self.ratio)*Trackerbox[0], (1/self.ratio)*Trackerbox[1], (1/self.ratio)*Trackerbox[2], (1/self.ratio)*Trackerbox[3]) + + if self.thread_conn == True: + break + + time.sleep(0.005) + + + + def camera(self): + + while True: + cap = cv2.VideoCapture(self.rtsp) + self.thread_flag = False + + while cap.isOpened() == True: + self.success, self.frame = cap.read() + self.camera_flag = True + + if self.success == False: + break + + if self.thread_flag == True: + break + + time.sleep(0.005) + + if self.thread_flag == True: + break + + time.sleep(0.005) + + def main(self): + + while True: + + try: + self.UDPClientSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + + cam = threading.Thread(target=self.camera) + cam.start() + print('Camera thread Initiated') + + while True: + if self.camera_flag == True: + break + + snd = threading.Thread(target=self.sending) + snd.start() + print('Sending thread Initiated') + + conn = threading.Thread(target=self.connection) + conn.start() + print('Connection thread Initiated') + + while True: + if self.camera_flag == True: + frame_disp = self.frame.copy() + + self.img_input, self.ratio = self.Img2ScreenRatio(frame_disp) + + cv2.namedWindow("image") + cv2.setMouseCallback("image", self.GetCoordinates) + + if self.startPoint == True and self.Flag == False: + cv2.rectangle(self.img_input, (self.rect[0], self.rect[1]), (self.rect[2], self.rect[3]), (0, 255, 0), 2) + + x = int((int(self.screen_width) - int(self.img_input.shape[1]))/2) + + if self.endPoint == True: + Rectangle = self.RectPositioning(self.rect[0], self.rect[1], self.rect[2], self.rect[3]) + + if Rectangle[0] > 0 and Rectangle[1] > 0 and Rectangle[2] > 0 and Rectangle[3] > 0: + Rectangle = (int(self.ratio*Rectangle[0]), int(self.ratio*Rectangle[1]), int(self.ratio*Rectangle[2]), int(self.ratio*Rectangle[3])) + + self.initBB = Rectangle + self.initialization = (self.initBB[0], self.initBB[1], (self.initBB[2] - self.initBB[0]), (self.initBB[3] - self.initBB[1])) + + if self.initialization[2] >= 5 and self.initialization[3] >=5: + self.Verify() + self.Flag = True + + else: + print('Select a Bounding Box instead of a Click') + self.rect = (0,0,0,0) + self.startPoint = False + self.endPoint = False + self.initBB = (0,0,0,0) + self.initAA = (0,0,0,0) + self.initialization = (0,0,0,0) + self.Flag = False + + if self.rec_flag == True: + cv2.rectangle(self.img_input, (int(self.Trackerbox[0]), int(self.Trackerbox[1])), (int(self.Trackerbox[0]+self.Trackerbox[2]), int(self.Trackerbox[1]+self.Trackerbox[3])), (0, 0, 255), 2) + cv2.moveWindow("image",x,0) + cv2.imshow('image', self.img_input) + if cv2.waitKey(1) & 0xFF == ord('q'): + print("Quit program using keyboard Interrupt") + Message3 = "Close" + self.send_msg(self.UDPClientSocket, self.serverAddressPort, Message3) + + self.closing_threads(cam, snd, conn) + + return + + if cv2.waitKey(1) & 0xFF == ord('t'): + print("Terminate both GCS and Air Station") + Message3 = "Terminate" + self.send_msg(self.UDPClientSocket, self.serverAddressPort, Message3) + + self.closing_threads(cam, snd, conn) + + return + + if cv2.waitKey(1) & 0xFF == ord('r'): + print("Reset program using keyboard Interrupt") + Message3 = "Close" + self.send_msg(self.UDPClientSocket, self.serverAddressPort, Message3) + + self.thread_conn = True + conn.join() + + self.rect = (0,0,0,0) + self.startPoint = False + self.endPoint = False + self.initBB = (0,0,0,0) + self.initAA = (0,0,0,0) + self.Trackerbox = (0,0,0,0) + self.flag_recv = False + self.initialization = (0,0,0,0) + self.init_flag = False + self.Flag = False + + break + + self.camera_flag = False + + time.sleep(0.005) + + cv2.destroyAllWindows() + self.UDPClientSocket.close() + + time.sleep(0.005) + + except KeyboardInterrupt: + print("Closed program using keyboard Interrupt") + Message3 = "Close" + self.send_msg(self.UDPClientSocket, self.serverAddressPort, Message3) + + self.closing_threads(cam, snd, conn) + + cv2.destroyAllWindows() + self.UDPClientSocket.close() + + def Img2ScreenRatio(self, frame): + + image_height, image_width = frame.shape[:2] + + self.screen_width = GetSystemMetrics(0) # 1920 + screen_height = GetSystemMetrics(1) #1080 + + image_ratio = image_width / image_height + screen_ratio = self.screen_width / screen_height + + if image_ratio < screen_ratio: + img_input = cv2.resize(frame, (int(screen_height*image_ratio),screen_height)) + ratio = image_height / screen_height + + else: + img_input = cv2.resize(frame, (self.screen_width,int(self.screen_width/image_ratio))) + ratio = image_width / self.screen_width + + return img_input, ratio + + def GetCoordinates(self,event, x, y, flags, param): + + if event == cv2.EVENT_LBUTTONDOWN: + self.rect = (x, y, 0, 0) + self.startPoint = True + self.endPoint = False + self.rect = (self.rect[0], self.rect[1], x, y) + + elif event == cv2.EVENT_MOUSEMOVE: + + if self.endPoint == False: + self.rect = (self.rect[0], self.rect[1], x, y) + + elif event == cv2.EVENT_LBUTTONUP: + self.endPoint = True + + def RectPositioning(self,x1,y1,x2,y2): + + if x1 <= x2 and y1 <= y2: + rect = (x1, y1, x2, y2) + return rect + + elif x1 >= x2 and y1 >= y2: + rect = (x2, y2, x1, y1) + return rect + + elif x1 <= x2 and y1 >= y2: + rect = (x1, y2, x2, y1) + return rect + + elif x1 >= x2 and y1 <= y2: + rect = (x2, y1, x1, y2) + return rect + + + def Verify(self): + if self.initAA[0] != self.initBB[0] or self.initAA[1] != self.initBB[1] or self.initAA[2] != self.initBB[2] or self.initAA[3] != self.initBB[3]: + print("Bounding Box Selected from GCS: ", self.initialization) + self.init_flag = True + + self.initAA = self.initBB + + +Tracking().main() \ No newline at end of file From 2add8cb41378031e24c568515b554a4ee85c4b59 Mon Sep 17 00:00:00 2001 From: Ahsan Raza Date: Wed, 20 Jul 2022 13:01:09 +0500 Subject: [PATCH 6/8] Delete Ground_Station.py --- Ground_Station.py | 358 ---------------------------------------------- 1 file changed, 358 deletions(-) delete mode 100644 Ground_Station.py diff --git a/Ground_Station.py b/Ground_Station.py deleted file mode 100644 index f09669c6..00000000 --- a/Ground_Station.py +++ /dev/null @@ -1,358 +0,0 @@ -''' -The Ground Station represents a client in the communication with pytracking (server). - -self.rtsp variable represents an rtsp stream, which should be set accordingly. - -self.serverAddressPort represents server ID and port for communication. - -Workflow of the Ground Station: - -1. Tries to connect with the server, unitl it is connected. - -2. After connection establishment, the ground station pop-up a window that shows continuous video feed. - Select a target object by drawing a bounding box using left mouse click. - -3. The Bounding Box is sent to the server end to initialize the tracker. - -4. The server after the initialization starts tracking the target object and sends back the tracked bounding box to Ground Station. - -5. The Ground Station displays the countinuous receving tracked object. - -Press Q for quit the Ground Station -Press R to re-select the object for tracking -Press T to Terminate both Ground Station and Server - -''' - -import cv2 -from win32api import GetSystemMetrics -import socket -import threading -import time - -class Tracking(): - - def __init__(self): - - # Initializing Parameters - - self.rect = (0,0,0,0) - self.startPoint = False - self.endPoint = False - self.Flag = False - self.init_flag = False - self.camera_flag = False - self.rec_flag = False - self.flag_recv = False - self.flag_sending = False - - # RTSP Stream - self.rtsp = 'rtsp://admin:admin1234@192.168.1.196:554/cam/realmonitor?channel=1&subtype=0' - #self.rtsp = "rtsp://192.168.1.176:8554/unicast" - #self.rtsp = 0 - - self.initBB = (0,0,0,0) - self.initAA = (0,0,0,0) - - # Server ID and Port No - self.serverAddressPort = ("192.168.1.176", 8554) - self.bufferSize = 1024 - - - def receive_msg(self, conn, bufferSize): - - bytesAddressPair = conn.recvfrom(bufferSize) - - message = b'' - message = bytesAddressPair[0] - message = message.decode('utf-8') - address = bytesAddressPair[1] - - return message, address - - def send_msg(self, conn, address, box): - - payload = str(box) - payload = payload.encode('utf-8') - conn.sendto(payload, address) - - def sending(self): - counter = 0 - while self.flag_recv == False: - Mess_conn = "Connection" - self.send_msg(self.UDPClientSocket, self.serverAddressPort, Mess_conn) - - if self.flag_sending == True: - break - - counter += 1 - if counter == 3: - print('Trying to connect ...') - counter = 0 - - time.sleep(1) - - def closing_threads(self, cm, sd, con): - - self.thread_flag = True - cm.join() - - self.flag_sending = True - sd.join() - - self.thread_conn = True - con.join() - - def connection(self): - - self.thread_conn = False - - msg_conn, addr = self.receive_msg(self.UDPClientSocket, self.bufferSize) - if msg_conn == "Connected": - print("Connection Establised.") - - self.flag_recv = True - - while True: - if self.init_flag == True: - if msg_conn == "Connected": - - if self.init_flag == True: - self.send_msg(self.UDPClientSocket, self.serverAddressPort, self.initialization) - - if self.Flag == True: - Message2 = "Send Tracker Coordinates" - self.send_msg(self.UDPClientSocket, self.serverAddressPort, Message2) - - msg, addr = self.receive_msg(self.UDPClientSocket, self.bufferSize) - - if self.thread_conn == True: - break - - if msg == "Tracker Lost": - print('Tracker Lost the Object') - cv2.destroyAllWindows() - break - - else: - self.rec_flag = True - Trackerbox = (float(msg.split(",")[0][1:]), float(msg.split(",")[1][1:]), float(msg.split(",")[2][1:]), float(msg.split(",")[3][1:(len(msg.split(",")[3])-1)])) - - self.Trackerbox = ((1/self.ratio)*Trackerbox[0], (1/self.ratio)*Trackerbox[1], (1/self.ratio)*Trackerbox[2], (1/self.ratio)*Trackerbox[3]) - - if self.thread_conn == True: - break - - time.sleep(0.005) - - - - def camera(self): - - while True: - cap = cv2.VideoCapture(self.rtsp) - self.thread_flag = False - - while cap.isOpened() == True: - self.success, self.frame = cap.read() - self.camera_flag = True - - if self.success == False: - break - - if self.thread_flag == True: - break - - time.sleep(0.005) - - if self.thread_flag == True: - break - - time.sleep(0.005) - - def main(self): - - while True: - - try: - self.UDPClientSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - - cam = threading.Thread(target=self.camera) - cam.start() - print('Camera thread Initiated') - - while True: - if self.camera_flag == True: - break - - snd = threading.Thread(target=self.sending) - snd.start() - print('Sending thread Initiated') - - conn = threading.Thread(target=self.connection) - conn.start() - print('Connection thread Initiated') - - while True: - if self.camera_flag == True: - frame_disp = self.frame.copy() - - self.img_input, self.ratio = self.Img2ScreenRatio(frame_disp) - - cv2.namedWindow("image") - cv2.setMouseCallback("image", self.GetCoordinates) - - if self.startPoint == True and self.Flag == False: - cv2.rectangle(self.img_input, (self.rect[0], self.rect[1]), (self.rect[2], self.rect[3]), (0, 255, 0), 2) - - x = int((int(self.screen_width) - int(self.img_input.shape[1]))/2) - - if self.endPoint == True: - Rectangle = self.RectPositioning(self.rect[0], self.rect[1], self.rect[2], self.rect[3]) - - if Rectangle[0] > 0 and Rectangle[1] > 0 and Rectangle[2] > 0 and Rectangle[3] > 0: - Rectangle = (int(self.ratio*Rectangle[0]), int(self.ratio*Rectangle[1]), int(self.ratio*Rectangle[2]), int(self.ratio*Rectangle[3])) - - self.initBB = Rectangle - self.initialization = (self.initBB[0], self.initBB[1], (self.initBB[2] - self.initBB[0]), (self.initBB[3] - self.initBB[1])) - - if self.initialization[2] >= 5 and self.initialization[3] >=5: - self.Verify() - self.Flag = True - - else: - print('Select a Bounding Box instead of a Click') - self.rect = (0,0,0,0) - self.startPoint = False - self.endPoint = False - self.initBB = (0,0,0,0) - self.initAA = (0,0,0,0) - self.initialization = (0,0,0,0) - self.Flag = False - - if self.rec_flag == True: - cv2.rectangle(self.img_input, (int(self.Trackerbox[0]), int(self.Trackerbox[1])), (int(self.Trackerbox[0]+self.Trackerbox[2]), int(self.Trackerbox[1]+self.Trackerbox[3])), (0, 0, 255), 2) - cv2.moveWindow("image",x,0) - cv2.imshow('image', self.img_input) - if cv2.waitKey(1) & 0xFF == ord('q'): - print("Quit program using keyboard Interrupt") - Message3 = "Close" - self.send_msg(self.UDPClientSocket, self.serverAddressPort, Message3) - - self.closing_threads(cam, snd, conn) - - return - - if cv2.waitKey(1) & 0xFF == ord('t'): - print("Terminate both GCS and Air Station") - Message3 = "Terminate" - self.send_msg(self.UDPClientSocket, self.serverAddressPort, Message3) - - self.closing_threads(cam, snd, conn) - - return - - if cv2.waitKey(1) & 0xFF == ord('r'): - print("Reset program using keyboard Interrupt") - Message3 = "Close" - self.send_msg(self.UDPClientSocket, self.serverAddressPort, Message3) - - self.thread_conn = True - conn.join() - - self.rect = (0,0,0,0) - self.startPoint = False - self.endPoint = False - self.initBB = (0,0,0,0) - self.initAA = (0,0,0,0) - self.Trackerbox = (0,0,0,0) - self.flag_recv = False - self.initialization = (0,0,0,0) - self.init_flag = False - self.Flag = False - - break - - self.camera_flag = False - - time.sleep(0.005) - - cv2.destroyAllWindows() - self.UDPClientSocket.close() - - time.sleep(0.005) - - except KeyboardInterrupt: - print("Closed program using keyboard Interrupt") - Message3 = "Close" - self.send_msg(self.UDPClientSocket, self.serverAddressPort, Message3) - - self.closing_threads(cam, snd, conn) - - cv2.destroyAllWindows() - self.UDPClientSocket.close() - - def Img2ScreenRatio(self, frame): - - image_height, image_width = frame.shape[:2] - - self.screen_width = GetSystemMetrics(0) # 1920 - screen_height = GetSystemMetrics(1) #1080 - - image_ratio = image_width / image_height - screen_ratio = self.screen_width / screen_height - - if image_ratio < screen_ratio: - img_input = cv2.resize(frame, (int(screen_height*image_ratio),screen_height)) - ratio = image_height / screen_height - - else: - img_input = cv2.resize(frame, (self.screen_width,int(self.screen_width/image_ratio))) - ratio = image_width / self.screen_width - - return img_input, ratio - - def GetCoordinates(self,event, x, y, flags, param): - - if event == cv2.EVENT_LBUTTONDOWN: - self.rect = (x, y, 0, 0) - self.startPoint = True - self.endPoint = False - self.rect = (self.rect[0], self.rect[1], x, y) - - elif event == cv2.EVENT_MOUSEMOVE: - - if self.endPoint == False: - self.rect = (self.rect[0], self.rect[1], x, y) - - elif event == cv2.EVENT_LBUTTONUP: - self.endPoint = True - - def RectPositioning(self,x1,y1,x2,y2): - - if x1 <= x2 and y1 <= y2: - rect = (x1, y1, x2, y2) - return rect - - elif x1 >= x2 and y1 >= y2: - rect = (x2, y2, x1, y1) - return rect - - elif x1 <= x2 and y1 >= y2: - rect = (x1, y2, x2, y1) - return rect - - elif x1 >= x2 and y1 <= y2: - rect = (x2, y1, x1, y2) - return rect - - - def Verify(self): - if self.initAA[0] != self.initBB[0] or self.initAA[1] != self.initBB[1] or self.initAA[2] != self.initBB[2] or self.initAA[3] != self.initBB[3]: - print("Bounding Box Selected from GCS: ", self.initialization) - self.init_flag = True - - self.initAA = self.initBB - - -Tracking().main() \ No newline at end of file From 22c51824e998b7043f759212f5467aafba81da99 Mon Sep 17 00:00:00 2001 From: Ahsan Raza Date: Wed, 20 Jul 2022 13:03:05 +0500 Subject: [PATCH 7/8] Ground Station (Client) This Ground_Station.py is used for communication with run_vide_communication.py from another PC and acts like Client. --- Ground_Station.py | 356 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 356 insertions(+) create mode 100644 Ground_Station.py diff --git a/Ground_Station.py b/Ground_Station.py new file mode 100644 index 00000000..a5d88e02 --- /dev/null +++ b/Ground_Station.py @@ -0,0 +1,356 @@ +''' +The Ground Station represents a client in the communication with pytracking (server). + +self.rtsp variable represents an rtsp stream, which should be set accordingly. + +self.serverAddressPort represents server ID and port for communication. + +Workflow of the Ground Station: + +1. Tries to connect with the server, unitl it is connected. + +2. After connection establishment, the ground station pop-up a window that shows continuous video feed. + Select a target object by drawing a bounding box using left mouse click. + +3. The Bounding Box is sent to the server end to initialize the tracker. + +4. The server after the initialization starts tracking the target object and sends back the tracked bounding box to Ground Station. + +5. The Ground Station displays the countinuous receving tracked object. + +Press Q for quit the Ground Station +Press R to re-select the object for tracking +Press T to Terminate both Ground Station and Server + +''' + +import cv2 +from win32api import GetSystemMetrics +import socket +import threading +import time + +class Tracking(): + + def __init__(self): + + # Initializing Parameters + + self.rect = (0,0,0,0) + self.startPoint = False + self.endPoint = False + self.Flag = False + self.init_flag = False + self.camera_flag = False + self.rec_flag = False + self.flag_recv = False + self.flag_sending = False + + # RTSP Stream + self.rtsp = 'rtsp://..' + + self.initBB = (0,0,0,0) + self.initAA = (0,0,0,0) + + # Server ID and Port No + self.serverAddressPort = ("127.0.0.1", 8554) + self.bufferSize = 1024 + + + def receive_msg(self, conn, bufferSize): + + bytesAddressPair = conn.recvfrom(bufferSize) + + message = b'' + message = bytesAddressPair[0] + message = message.decode('utf-8') + address = bytesAddressPair[1] + + return message, address + + def send_msg(self, conn, address, box): + + payload = str(box) + payload = payload.encode('utf-8') + conn.sendto(payload, address) + + def sending(self): + counter = 0 + while self.flag_recv == False: + Mess_conn = "Connection" + self.send_msg(self.UDPClientSocket, self.serverAddressPort, Mess_conn) + + if self.flag_sending == True: + break + + counter += 1 + if counter == 3: + print('Trying to connect ...') + counter = 0 + + time.sleep(1) + + def closing_threads(self, cm, sd, con): + + self.thread_flag = True + cm.join() + + self.flag_sending = True + sd.join() + + self.thread_conn = True + con.join() + + def connection(self): + + self.thread_conn = False + + msg_conn, addr = self.receive_msg(self.UDPClientSocket, self.bufferSize) + if msg_conn == "Connected": + print("Connection Establised.") + + self.flag_recv = True + + while True: + if self.init_flag == True: + if msg_conn == "Connected": + + if self.init_flag == True: + self.send_msg(self.UDPClientSocket, self.serverAddressPort, self.initialization) + + if self.Flag == True: + Message2 = "Send Tracker Coordinates" + self.send_msg(self.UDPClientSocket, self.serverAddressPort, Message2) + + msg, addr = self.receive_msg(self.UDPClientSocket, self.bufferSize) + + if self.thread_conn == True: + break + + if msg == "Tracker Lost": + print('Tracker Lost the Object') + cv2.destroyAllWindows() + break + + else: + self.rec_flag = True + Trackerbox = (float(msg.split(",")[0][1:]), float(msg.split(",")[1][1:]), float(msg.split(",")[2][1:]), float(msg.split(",")[3][1:(len(msg.split(",")[3])-1)])) + + self.Trackerbox = ((1/self.ratio)*Trackerbox[0], (1/self.ratio)*Trackerbox[1], (1/self.ratio)*Trackerbox[2], (1/self.ratio)*Trackerbox[3]) + + if self.thread_conn == True: + break + + time.sleep(0.005) + + + + def camera(self): + + while True: + cap = cv2.VideoCapture(self.rtsp) + self.thread_flag = False + + while cap.isOpened() == True: + self.success, self.frame = cap.read() + self.camera_flag = True + + if self.success == False: + break + + if self.thread_flag == True: + break + + time.sleep(0.005) + + if self.thread_flag == True: + break + + time.sleep(0.005) + + def main(self): + + while True: + + try: + self.UDPClientSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + + cam = threading.Thread(target=self.camera) + cam.start() + print('Camera thread Initiated') + + while True: + if self.camera_flag == True: + break + + snd = threading.Thread(target=self.sending) + snd.start() + print('Sending thread Initiated') + + conn = threading.Thread(target=self.connection) + conn.start() + print('Connection thread Initiated') + + while True: + if self.camera_flag == True: + frame_disp = self.frame.copy() + + self.img_input, self.ratio = self.Img2ScreenRatio(frame_disp) + + cv2.namedWindow("image") + cv2.setMouseCallback("image", self.GetCoordinates) + + if self.startPoint == True and self.Flag == False: + cv2.rectangle(self.img_input, (self.rect[0], self.rect[1]), (self.rect[2], self.rect[3]), (0, 255, 0), 2) + + x = int((int(self.screen_width) - int(self.img_input.shape[1]))/2) + + if self.endPoint == True: + Rectangle = self.RectPositioning(self.rect[0], self.rect[1], self.rect[2], self.rect[3]) + + if Rectangle[0] > 0 and Rectangle[1] > 0 and Rectangle[2] > 0 and Rectangle[3] > 0: + Rectangle = (int(self.ratio*Rectangle[0]), int(self.ratio*Rectangle[1]), int(self.ratio*Rectangle[2]), int(self.ratio*Rectangle[3])) + + self.initBB = Rectangle + self.initialization = (self.initBB[0], self.initBB[1], (self.initBB[2] - self.initBB[0]), (self.initBB[3] - self.initBB[1])) + + if self.initialization[2] >= 5 and self.initialization[3] >=5: + self.Verify() + self.Flag = True + + else: + print('Select a Bounding Box instead of a Click') + self.rect = (0,0,0,0) + self.startPoint = False + self.endPoint = False + self.initBB = (0,0,0,0) + self.initAA = (0,0,0,0) + self.initialization = (0,0,0,0) + self.Flag = False + + if self.rec_flag == True: + cv2.rectangle(self.img_input, (int(self.Trackerbox[0]), int(self.Trackerbox[1])), (int(self.Trackerbox[0]+self.Trackerbox[2]), int(self.Trackerbox[1]+self.Trackerbox[3])), (0, 0, 255), 2) + cv2.moveWindow("image",x,0) + cv2.imshow('image', self.img_input) + if cv2.waitKey(1) & 0xFF == ord('q'): + print("Quit program using keyboard Interrupt") + Message3 = "Close" + self.send_msg(self.UDPClientSocket, self.serverAddressPort, Message3) + + self.closing_threads(cam, snd, conn) + + return + + if cv2.waitKey(1) & 0xFF == ord('t'): + print("Terminate both GCS and Air Station") + Message3 = "Terminate" + self.send_msg(self.UDPClientSocket, self.serverAddressPort, Message3) + + self.closing_threads(cam, snd, conn) + + return + + if cv2.waitKey(1) & 0xFF == ord('r'): + print("Reset program using keyboard Interrupt") + Message3 = "Close" + self.send_msg(self.UDPClientSocket, self.serverAddressPort, Message3) + + self.thread_conn = True + conn.join() + + self.rect = (0,0,0,0) + self.startPoint = False + self.endPoint = False + self.initBB = (0,0,0,0) + self.initAA = (0,0,0,0) + self.Trackerbox = (0,0,0,0) + self.flag_recv = False + self.initialization = (0,0,0,0) + self.init_flag = False + self.Flag = False + + break + + self.camera_flag = False + + time.sleep(0.005) + + cv2.destroyAllWindows() + self.UDPClientSocket.close() + + time.sleep(0.005) + + except KeyboardInterrupt: + print("Closed program using keyboard Interrupt") + Message3 = "Close" + self.send_msg(self.UDPClientSocket, self.serverAddressPort, Message3) + + self.closing_threads(cam, snd, conn) + + cv2.destroyAllWindows() + self.UDPClientSocket.close() + + def Img2ScreenRatio(self, frame): + + image_height, image_width = frame.shape[:2] + + self.screen_width = GetSystemMetrics(0) # 1920 + screen_height = GetSystemMetrics(1) #1080 + + image_ratio = image_width / image_height + screen_ratio = self.screen_width / screen_height + + if image_ratio < screen_ratio: + img_input = cv2.resize(frame, (int(screen_height*image_ratio),screen_height)) + ratio = image_height / screen_height + + else: + img_input = cv2.resize(frame, (self.screen_width,int(self.screen_width/image_ratio))) + ratio = image_width / self.screen_width + + return img_input, ratio + + def GetCoordinates(self,event, x, y, flags, param): + + if event == cv2.EVENT_LBUTTONDOWN: + self.rect = (x, y, 0, 0) + self.startPoint = True + self.endPoint = False + self.rect = (self.rect[0], self.rect[1], x, y) + + elif event == cv2.EVENT_MOUSEMOVE: + + if self.endPoint == False: + self.rect = (self.rect[0], self.rect[1], x, y) + + elif event == cv2.EVENT_LBUTTONUP: + self.endPoint = True + + def RectPositioning(self,x1,y1,x2,y2): + + if x1 <= x2 and y1 <= y2: + rect = (x1, y1, x2, y2) + return rect + + elif x1 >= x2 and y1 >= y2: + rect = (x2, y2, x1, y1) + return rect + + elif x1 <= x2 and y1 >= y2: + rect = (x1, y2, x2, y1) + return rect + + elif x1 >= x2 and y1 <= y2: + rect = (x2, y1, x1, y2) + return rect + + + def Verify(self): + if self.initAA[0] != self.initBB[0] or self.initAA[1] != self.initBB[1] or self.initAA[2] != self.initBB[2] or self.initAA[3] != self.initBB[3]: + print("Bounding Box Selected from GCS: ", self.initialization) + self.init_flag = True + + self.initAA = self.initBB + + +Tracking().main() \ No newline at end of file From 4fb7874f29086605f8836cb534470c54ce23cdc7 Mon Sep 17 00:00:00 2001 From: Ahsan Raza Date: Wed, 20 Jul 2022 13:27:08 +0500 Subject: [PATCH 8/8] Update tracker.py --- pytracking/evaluation/tracker.py | 59 ++++++-------------------------- 1 file changed, 11 insertions(+), 48 deletions(-) diff --git a/pytracking/evaluation/tracker.py b/pytracking/evaluation/tracker.py index e088a0ac..526f75b8 100644 --- a/pytracking/evaluation/tracker.py +++ b/pytracking/evaluation/tracker.py @@ -9,7 +9,6 @@ ''' - import importlib import os import numpy as np @@ -21,12 +20,17 @@ import matplotlib.pyplot as plt import matplotlib.patches as patches from pytracking.utils.plotting import draw_figure, overlay_mask +from pytracking.utils.convert_vot_anno_to_rect import convert_vot_anno_to_rect +from ltr.data.bounding_box_utils import masks_to_bboxes from pytracking.evaluation.multi_object_wrapper import MultiObjectWrapper from pathlib import Path +import torch import threading import socket +import argparse +import imutils _tracker_disp_colors = {1: (0, 255, 0), 2: (0, 0, 255), 3: (255, 0, 0), 4: (255, 255, 255), 5: (0, 0, 0), 6: (0, 255, 128), @@ -74,25 +78,12 @@ def __init__(self, name: str, parameter_name: str, run_id: int = None, display_n self.distance_flag = False # Flag for distance calculation # Socket programming parameters - self.localIP = "127.0.0.1" # Server IP + self.localIP = "127.0.0.1" # Server IP self.localPort = 8554 # Server Port self.bufferSize = 1024 self.initBB = (0,0,0,0) self.initAA = (0,0,0,0) - # New parameters for NAHL - self.tilt_y = 0 # Title Angle of Drone - self.tilt_x = 0 # Roll Angle of Drone - self.height = 0 # Height of Drone in meters - self.p_pitch = 0 # Camera specification pixel pitch - self.F_lens = 0 # Camera specification lens focal length, changes with zoom - self.Text_File = [] - self.liny = 0 - self.linx = 0 - - self.BB_centroid_x = 0 # Bounding Box Centroid_x - self.BB_centroid_y = 0 # Bounding Box Centroid_y - env = env_settings() if self.run_id is None: self.results_dir = '{}/{}/{}'.format(env.results_path, self.name, self.parameter_name) @@ -113,7 +104,6 @@ def __init__(self, name: str, parameter_name: str, run_id: int = None, display_n def connection(self, localIP, localPort): # Create a datagram socket and bind IP/Port Address - UDPServerSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) UDPServerSocket.bind((localIP, localPort)) @@ -181,10 +171,10 @@ def camera_video(self, videofilepath, sf): txt = txt[2].split(".") txt = txt[0] + self.camera_thread = False # VIDEO Writing - frame_width = int(self.cap.get(3)) frame_height = int(self.cap.get(4)) self.out = cv.VideoWriter(txt + '_Result.avi',cv.VideoWriter_fourcc('M','J','P','G'), 15, (frame_width,frame_height)) @@ -317,6 +307,7 @@ def _build_init_info(box): else: time.sleep(0.01) + while True: if self.camera_flag == True: @@ -336,16 +327,6 @@ def _build_init_info(box): cv.putText(frame_disp, 'Press r to reset', (20, 55), cv.FONT_HERSHEY_COMPLEX_SMALL, 2, font_color, 1) cv.putText(frame_disp, 'Press q to quit', (20, 80), cv.FONT_HERSHEY_COMPLEX_SMALL, 2, font_color, 1) - # Tracked BoundBox Centroid - self.BB_centroid_x = state[0] + int(state[2]/2) - self.BB_centroid_y = state[1] + int(state[3]/2) - - if self.distance_flag == True: - self.distance_x , self.distance_y = self.im2distance(self.new_frame,self.BB_centroid_x,self.BB_centroid_y,self.liny,self.linx) - lst = [self.distance_x, self.distance_y] - - self.Text_File.append(lst) - # Display the resulting frame cv.imshow(display_name, frame_disp) self.out.write(frame_disp) @@ -376,6 +357,7 @@ def _build_init_info(box): self.cap.release() cv.destroyAllWindows() + if save_results: if not os.path.exists(self.results_dir): os.makedirs(self.results_dir) @@ -464,6 +446,7 @@ def run_video_comm(self, optional_box=None, debug=None, visdom_info=None, save_r break + while True: if self.camera_flag == True: @@ -481,6 +464,7 @@ def _build_init_info(box): frame_disp = self.frame.copy() if self.initBB is not None: + # Draw box out = tracker.track(self.frame) state = [int(s) for s in out['target_bbox'][1]] @@ -489,21 +473,10 @@ def _build_init_info(box): cv.rectangle(frame_disp, (state[0], state[1]), (state[2] + state[0], state[3] + state[1]), (0, 255, 0), 5) - # Tracked BoundBox Centroid - self.BB_centroid_x = state[0] + int(state[2]/2) - self.BB_centroid_y = state[1] + int(state[3]/2) - - if self.distance_flag == True: - self.distance_x , self.distance_y = self.im2distance(self.frame,self.BB_centroid_x,self.BB_centroid_y,self.liny,self.linx) - lst = [self.distance_x, self.distance_y] - - self.Text_File.append(lst) self.message2, self.address2 = self.receive_msg(self.conn, self.bufferSize) if self.message2 == "Send Tracker Coordinates": - - print('state', state) self.send_msg(self.conn, self.address2, state) elif self.message2 == "Close": @@ -656,15 +629,6 @@ def get_bb(self): cv.rectangle(frame_disp, (state[0], state[1]), (state[2] + state[0], state[3] + state[1]), _tracker_disp_colors[obj_id], 5) - # Tracked BoundBox Centroid - self.BB_centroid_x = state[0] + int(state[2]/2) - self.BB_centroid_y = state[1] + int(state[3]/2) - - if self.distance_flag == True: - self.distance_x , self.distance_y = self.im2distance(self.frame, self.BB_centroid_x, self.BB_centroid_y, self.liny, self.linx) - lst = [self.distance_x, self.distance_y] - - self.Text_File.append(lst) # Put text font_color = (0, 255, 0) @@ -764,4 +728,3 @@ def press(self, event): def _read_image(self, image_file: str): im = cv.imread(image_file) return cv.cvtColor(im, cv.COLOR_BGR2RGB) -