Esempio n. 1
0
class StruckTracker(GenericVisionTracker):
    """
    TODO
    """
    def __init__(self):
        """
        Initialize the tracker
        """
        self.name = 'struck_tracker'
        f = open("config.txt", "w")
        f.write(struck_config)
        f.close()
        self.reset()

    def reset(self):
        """
        Reset the tracker
        :return:
        """
        self._primed = False
        self.bbox = None

    def _prime(self, im, bounding_region):
        """
        prime tracker on image and bounding box

        :param im: input image (3 - channel numpy array)
        :type im: numpy.ndarray
        :param bounding_region: initial bounding region of the tracked object
        :type bounding_region: PVM_tools.bounding_region.BoundingRegion
        """
        self.bbox=bounding_region
        bounding_box = bounding_region.get_box_pixels()
        struck.STRUCK_init(im, bounding_box)
    
    def _track(self, im):
        """
        Track on given image, return a bounding box

        :param im: image (3 - channel numpy array)
        :type im: numpy.ndarray
        :return: bounding box of the tracker object
        :rtype: PVM_tools.bounding_region.BoundingRegion
        """
        #  this is required so that tracker is re-initialized if it is primed again
        self._primed = False
        struck.STRUCK_track(im)
        struck_bbox = struck.STRUCK_get_bbox()
        self.bounding_box = [struck_bbox["xmin"], struck_bbox["ymin"], struck_bbox["width"], struck_bbox["height"]]
        if self.bounding_box == ():
            self.bbox = BoundingRegion()
        else:
            self.bbox = BoundingRegion(image_shape=(im.shape[0], im.shape[1], 3), box=self.bounding_box)
        return self.bbox.copy()

    def get_heatmap(self, heatmap_name=None):
        return self.bbox.get_mask()
class CenterVisionTracker(GenericVisionTracker):
    """
    This class exposes the null vision tracker which just always
    returns its priming bounding box

    """
    def __init__(self, size_factor=0.2, new_name=None):
        """
        Initialize the tracker
        """
        if new_name is None:
            self.name = 'center_tracker'
        else:
            self.name = new_name
        self.size_factor = size_factor

    def reset(self):
        """
        Reset the tracker
        :return:
        """
        self._primed = False
        self.bbox = None

    def _prime(self, im, bounding_region):
        """
        prime tracker on image and bounding box

        :param im: input image (3 - channel numpy array)
        :type im: numpy.ndarray
        :param bounding_region: initial bounding region of the tracked object
        :type bounding_region: PVM_tools.bounding_region.BoundingRegion
        """
        box = np.array([(im.shape[1] - im.shape[1] * self.size_factor) / 2,
                        (im.shape[0] - im.shape[0] * self.size_factor) / 2,
                        im.shape[1] * self.size_factor,
                        im.shape[0] * self.size_factor]).astype(np.int)
        self.bbox = BoundingRegion(image_shape=im.shape, box=box)
        if not self._primed:
            self._primed = True

    def _track(self, im):
        """
        Track on given image, rseturn a bounding box

        :param im: image (3 - channel numpy array)
        :type im: numpy.ndarray
        :return: bounding box of the tracker object
        :rtype: PVM_tools.bounding_region.BoundingRegion
        """
        #  this is required so that tracker is re-initialized if it is primed again
        self._primed = False
        return self.bbox.copy()

    def get_heatmap(self, heatmap_name=None):
        return self.bbox.get_mask()
class CenterVisionTracker(GenericVisionTracker):
    """
    This class exposes the null vision tracker which just always
    returns its priming bounding box

    """
    def __init__(self, size_factor=0.2, new_name=None):
        """
        Initialize the tracker
        """
        if new_name is None:
            self.name = 'center_tracker'
        else:
            self.name = new_name
        self.size_factor = size_factor

    def reset(self):
        """
        Reset the tracker
        :return:
        """
        self._primed = False
        self.bbox = None

    def _prime(self, im, bounding_region):
        """
        prime tracker on image and bounding box

        :param im: input image (3 - channel numpy array)
        :type im: numpy.ndarray
        :param bounding_region: initial bounding region of the tracked object
        :type bounding_region: PVM_tools.bounding_region.BoundingRegion
        """
        box = np.array([(im.shape[1]-im.shape[1]*self.size_factor)/2,
                        (im.shape[0]-im.shape[0]*self.size_factor)/2,
                        im.shape[1]*self.size_factor,
                        im.shape[0]*self.size_factor]).astype(np.int)
        self.bbox = BoundingRegion(image_shape=im.shape, box=box)
        if not self._primed:
            self._primed = True

    def _track(self, im):
        """
        Track on given image, rseturn a bounding box

        :param im: image (3 - channel numpy array)
        :type im: numpy.ndarray
        :return: bounding box of the tracker object
        :rtype: PVM_tools.bounding_region.BoundingRegion
        """
        #  this is required so that tracker is re-initialized if it is primed again
        self._primed = False
        return self.bbox.copy()

    def get_heatmap(self, heatmap_name=None):
        return self.bbox.get_mask()
class TLDVisionTracker(GenericVisionTracker):
    """
    This class exposes the open tld tracker implemented in C++ by http://www.gnebehay.com/tld/.
    Originally OpenTLD that was originally published in MATLAB by Zdenek Kalal.

    """
    def __init__(self):
        """
        Initialize the tracker
        """
        self.name = 'tld_tracker'
        self.reset()

    def reset(self):
        """
        Reset the tracker
        :return:
        """
        self.tld = None
        self._primed = False
        self.bbox = None

    def _prime(self, im, bounding_region):
        """
        prime tracker on image and bounding box

        :param im: input image (3 - channel numpy array)
        :type im: numpy.ndarray
        :param bounding_region: initial bounding region of the tracked object
        :type bounding_region: PVM_tools.bounding_region.BoundingRegion
        """
        self.bbox = bounding_region
        bounding_box = bounding_region.get_box_pixels()

        if not self._primed:
            self.tld = tld.TLD2()
            self._primed = True

        self.height, self.width = im.shape[:2]
        self.tld.set_width_and_height((self.width, self.height))

        im = cv2.cvtColor(im, cv2.COLOR_RGB2GRAY)
        img_cvmat = cv2.cv.fromarray(im)
        if bounding_box[0] + bounding_box[2] > self.width:
            bounding_box[2] = self.width - bounding_box[0]
        if bounding_box[1] + bounding_box[3] > self.height:
            bounding_box[3] = self.height - bounding_box[1]

        self.tld.selectObject(
            img_cvmat,
            tuple([
                int(bounding_box[0]),
                int(bounding_box[1]),
                int(bounding_box[2]),
                int(bounding_box[3])
            ]))

    def _track(self, im):
        """
        Track on given image, return a bounding box

        :param im: image (3 - channel numpy array)
        :type im: numpy.ndarray
        :return: bounding box of the tracker object
        :rtype: PVM_tools.bounding_region.BoundingRegion
        """
        #  this is required so that tracker is re-initialized if it is primed again
        self._primed = False
        img_cvmat = cv2.cv.fromarray(im)
        self.tld.processImage(img_cvmat)
        self.bounding_box = self.tld.getCurrBB()
        self.confidence = self.tld.currConf
        if self.bounding_box == ():
            self.bbox = BoundingRegion()
        else:
            self.bbox = BoundingRegion(image_shape=(im.shape[0], im.shape[1],
                                                    3),
                                       box=self.bounding_box,
                                       confidence=self.confidence)
        return self.bbox.copy()

    def get_heatmap(self, heatmap_name=None):
        return self.bbox.get_mask()
Esempio n. 5
0
class CMTVisionTracker(GenericVisionTracker):
    """
    This class exposes the CMT tracker implemented in http://www.gnebehay.com/CMT/.
    """
    def __init__(self):
        """
        Initialize the tracker
        """
        self.name = 'cmt_tracker'
        self.reset()

    def reset(self):
        """
        Reset the tracker
        :return:
        """
        self.cmt = None
        self._primed = False
        self.bbox = None

    def _prime(self, im, bounding_region):
        """
        prime tracker on image and bounding box
        :param im: input image (3 - channel numpy array)
        :type im: numpy.ndarray
        :param bounding_region: initial bounding region of the tracked object
        :type bounding_region: PVM_tools.bounding_region.BoundingRegion
        """
        self.bbox=bounding_region
        bounding_box = bounding_region.get_box_pixels()

        if not self._primed:
            this_dir = os.path.dirname(os.path.realpath(__file__))
            sys.path.append(this_dir+"/original_cmt/")
            from CMT import CMT
            self.cmt = CMT()
            self._primed = True

        self.height, self.width = im.shape[:2]
        im = cv2.cvtColor(im, cv2.COLOR_RGB2GRAY)
        self.cmt.initialise(im_gray0=im,
                            tl=tuple([bounding_box[0], bounding_box[1]]),
                            br=tuple([bounding_box[0]+bounding_box[2], bounding_box[1]+bounding_box[3]]))
        self.im_prev = im

    def _track(self, im):
        """
        Track on given image, return a bounding box
        :param im: image (3 - channel numpy array)
        :type im: numpy.ndarray
        :return: bounding box of the tracker object
        :rtype: PVM_tools.bounding_region.BoundingRegion
        """
        #  this is required so that tracker is re-initialized if it is primed again
        self._primed = False
        self.im_prev = im
        im = cv2.cvtColor(im, cv2.COLOR_RGB2GRAY)
        self.cmt.process_frame(im)
        self.confidence = 1
        if np.isnan(self.cmt.bb).any():
            self.bbox = BoundingRegion()
        else:
            self.bbox = BoundingRegion(image_shape=im.shape, box=self.cmt.bb, confidence=self.confidence)
        return self.bbox.copy()

    def get_heatmap(self, heatmap_name=None):
        return self.bbox.get_mask()
Esempio n. 6
0
class StruckTracker(GenericVisionTracker):
    """
    TODO
    """
    def __init__(self):
        """
        Initialize the tracker
        """
        self.name = 'struck_tracker'
        f = open("config.txt", "w")
        f.write(struck_config)
        f.close()
        self.reset()

    def reset(self):
        """
        Reset the tracker
        :return:
        """
        self._primed = False
        self.bbox = None

    def _prime(self, im, bounding_region):
        """
        prime tracker on image and bounding box

        :param im: input image (3 - channel numpy array)
        :type im: numpy.ndarray
        :param bounding_region: initial bounding region of the tracked object
        :type bounding_region: PVM_tools.bounding_region.BoundingRegion
        """
        self.bbox = bounding_region
        bounding_box = bounding_region.get_box_pixels()
        struck.STRUCK_init(im, bounding_box)

    def _track(self, im):
        """
        Track on given image, return a bounding box

        :param im: image (3 - channel numpy array)
        :type im: numpy.ndarray
        :return: bounding box of the tracker object
        :rtype: PVM_tools.bounding_region.BoundingRegion
        """
        #  this is required so that tracker is re-initialized if it is primed again
        self._primed = False
        struck.STRUCK_track(im)
        struck_bbox = struck.STRUCK_get_bbox()
        self.bounding_box = [
            struck_bbox["xmin"], struck_bbox["ymin"], struck_bbox["width"],
            struck_bbox["height"]
        ]
        if self.bounding_box == ():
            self.bbox = BoundingRegion()
        else:
            self.bbox = BoundingRegion(image_shape=(im.shape[0], im.shape[1],
                                                    3),
                                       box=self.bounding_box)
        return self.bbox.copy()

    def get_heatmap(self, heatmap_name=None):
        return self.bbox.get_mask()
Esempio n. 7
0
class PVMVisionTracker(GenericVisionTracker):
    """
    This class exposes the null vision tracker which just always
    returns its priming bounding box

    """
    def __init__(self,
                 filename="",
                 remote_filename="",
                 cores="4",
                 storage=None,
                 steps_per_frame=1):
        """
        Initialize the tracker
        """
        self.name = 'PVMtracker'
        if filename == "":
            filename = storage.get(remote_filename)
        self.prop_dict = CoreUtils.load_model(filename)
        logging.info("Loaded the dictionary %s", filename)
        PVM_Create.upgrade_dictionary_to_ver1_0(self.prop_dict)
        self.prop_dict['num_proc'] = int(cores)
        for k in range(len(self.prop_dict['learning_rates'])):
            self.prop_dict['learning_rates'][k][0] = 0.0
            logging.info("Setting learning rate in layer %d to zero" % k)
        self.prop_dict["readout_learning_rate"][0] = 0.0
        logging.info("Setting readout learning rate to zero")
        self.manager = Manager(self.prop_dict, 1000)
        self.executor = CoreUtils.ModelExecution(prop_dict=self.prop_dict,
                                                 manager=self.manager,
                                                 port=9100)
        self.executor.start(blocking=False)
        self.threshold = 32
        self.image_size = self.prop_dict['input_array'].shape[:2][::-1]
        self.readout_heatmap = np.zeros(self.image_size, dtype=np.float)
        self.step_per_frame = steps_per_frame

    def reset(self):
        """
        Reset the tracker
        :return:
        """
        self._primed = False
        self.bbox = None

    def _prime(self, im, bounding_region):
        """
        prime tracker on image and bounding box

        :param im: input image (3 - channel numpy array)
        :type im: numpy.ndarray
        :param bounding_region: initial bounding region of the tracked object
        :type bounding_region: PVM_tools.bounding_region.BoundingRegion
        """
        if not self._primed:
            logging.info("Priming the PVM tracker")
            logging.info("Setting up the tracker threshold to %d" %
                         self.threshold)
            self._primed = True

    def _track(self, im):
        """
        Track on given image, rseturn a bounding box

        :param im: image (3 - channel numpy array)
        :type im: numpy.ndarray
        :return: bounding box of the tracker object
        :rtype: PVM_tools.bounding_region.BoundingRegion
        """
        #  this is required so that tracker is re-initialized if it is primed again
        current_frame = cv2.resize(im, dsize=self.image_size)
        self.prop_dict['input_array'][:] = current_frame
        self.prop_dict['input_array_float'][:] = current_frame.astype(
            np.float) / 255
        for i in range(self.step_per_frame):
            self.executor.step()
        norm = 1.0 / len(self.prop_dict['predicted_readout_arrays'])
        self.readout_heatmap[:] = 0
        for k in self.prop_dict['predicted_readout_arrays']:
            self.readout_heatmap[:] += cv2.resize(k.view(np.ndarray),
                                                  dsize=self.image_size) * norm
        am = np.unravel_index(np.argmax(self.readout_heatmap),
                              self.readout_heatmap.shape)
        if len(am) == 3:
            for d in range(3):
                if am[2] != d:
                    self.readout_heatmap[:, :, d] = 0

        self.heatmap = self.readout_heatmap.view(np.ndarray)
        if len(self.heatmap.shape) == 3:
            self.heatmap = np.max(self.heatmap, axis=2)
        self.heatmap = cv2.resize(self.heatmap,
                                  dsize=(im.shape[1], im.shape[0]),
                                  interpolation=cv2.INTER_CUBIC)
        self.heatmap = (self.heatmap * 255).astype(np.uint8)
        if np.max(self.heatmap) > (np.median(self.heatmap) + self.threshold):
            threshold = (np.max(self.heatmap) - np.median(
                self.heatmap)) * 0.5 + np.median(self.heatmap)
            ret, thresh = cv2.threshold(self.heatmap, threshold, 255, 0)
            contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE,
                                                   cv2.CHAIN_APPROX_SIMPLE)
            if len(contours) > 0:
                max_cnt = None
                for cnt in contours:
                    pt = np.unravel_index(np.argmax(self.heatmap),
                                          self.heatmap.shape)
                    if cv2.pointPolygonTest(cnt, (pt[1], pt[0]), False) >= 0:
                        max_cnt = cnt
                        break
                if max_cnt is None:
                    self.bbox = BoundingRegion()
                else:
                    x, y, w, h = cv2.boundingRect(max_cnt)
                    if w * h > 25:
                        self.bbox = BoundingRegion(image_shape=im.shape,
                                                   box=[x, y, w, h])
                        self.bbox.scale(1.1)
                    else:
                        self.bbox = BoundingRegion()
            else:
                self.bbox = BoundingRegion()
        else:
            self.bbox = BoundingRegion()
        self._primed = False
        return self.bbox.copy()

    def get_heatmap(self, heatmap_name=None):
        return self.heatmap()

    def finish(self):
        self.manager._running = False
        self.executor.step()
        self.executor.finish()
Esempio n. 8
0
class TLDVisionTracker(GenericVisionTracker):
    """
    This class exposes the open tld tracker implemented in C++ by http://www.gnebehay.com/tld/.
    Originally OpenTLD that was originally published in MATLAB by Zdenek Kalal.

    """
    def __init__(self):
        """
        Initialize the tracker
        """
        self.name = 'tld_tracker'
        self.reset()

    def reset(self):
        """
        Reset the tracker
        :return:
        """
        self.tld = None
        self._primed = False
        self.bbox = None

    def _prime(self, im, bounding_region):
        """
        prime tracker on image and bounding box

        :param im: input image (3 - channel numpy array)
        :type im: numpy.ndarray
        :param bounding_region: initial bounding region of the tracked object
        :type bounding_region: PVM_tools.bounding_region.BoundingRegion
        """
        self.bbox=bounding_region
        bounding_box = bounding_region.get_box_pixels()

        if not self._primed:
            self.tld = tld.TLD2()
            self._primed = True

        self.height, self.width = im.shape[:2]
        self.tld.set_width_and_height((self.width, self.height))

        im = cv2.cvtColor(im, cv2.COLOR_RGB2GRAY)
        img_cvmat = cv2.cv.fromarray(im)
        if bounding_box[0] + bounding_box[2] > self.width:
            bounding_box[2] = self.width - bounding_box[0]
        if bounding_box[1] + bounding_box[3] > self.height:
            bounding_box[3] = self.height - bounding_box[1]

        self.tld.selectObject(img_cvmat, tuple([int(bounding_box[0]), int(bounding_box[1]), int(bounding_box[2]), int(bounding_box[3])]))

    def _track(self, im):
        """
        Track on given image, return a bounding box

        :param im: image (3 - channel numpy array)
        :type im: numpy.ndarray
        :return: bounding box of the tracker object
        :rtype: PVM_tools.bounding_region.BoundingRegion
        """
        #  this is required so that tracker is re-initialized if it is primed again
        self._primed = False
        img_cvmat = cv2.cv.fromarray(im)
        self.tld.processImage(img_cvmat)
        self.bounding_box = self.tld.getCurrBB()
        self.confidence = self.tld.currConf
        if self.bounding_box == ():
            self.bbox = BoundingRegion()
        else:
            self.bbox = BoundingRegion(image_shape=(im.shape[0], im.shape[1], 3), box=self.bounding_box, confidence=self.confidence)
        return self.bbox.copy()

    def get_heatmap(self, heatmap_name=None):
        return self.bbox.get_mask()
class LabelingApp(object):
    def __init__(self,
                 filename,
                 output=None,
                 channel="default",
                 target="default"):
        self.input_filename = filename
        if output is None:
            self.output_file = self.input_filename
        else:
            self.output_file = output
        self.channel = channel
        self.target = target
        self.reset()

    def reset(self, reload=False):
        cv2.destroyAllWindows()
        fc = FrameCollection()
        if reload:
            fc.load_from_file(filename=self.output_file)
        else:
            fc.load_from_file(filename=self.input_filename)
        self.movie = fc
        self.tracker = None
        self.current_frame_index = 0
        self.right_button_pressed = False
        self.left_button_pressed = False
        self._anchor = None
        self.x_size = 30
        self.y_size = 30
        self._tracked_bounds = None
        self._stored_bounds = None
        self._current_bounds = BoundingRegion()
        # Make sure self.timer is set
        self.schedule_callback()
        # Initialization of the Graphic User Interface
        self.ready_to_refresh = threading.Lock()
        self.timer_lock = threading.Lock()
        self.win_name = 'Labeling video GUI'
        self.image = self.movie.Frame(
            self.current_frame_index).get_image(channel=self.channel)
        self.display_image = self.movie.Frame(
            self.current_frame_index).get_image(channel=self.channel)
        self.image_shape = self.image.shape
        self.create_windows()
        self.set_target_absent()
        self.image_buffer = {}
        self._last_update = time.time()
        self.refresh_timer = threading.Timer(0.05, self.refresh)
        self.refresh_timer.start()
        self.needs_refresh = True
        self.trim_end = len(self.movie) - 1
        self.trim_start = 0

    def fill_up_the_buffer(self):
        r0 = max(self.current_frame_index - 5, 0)
        r1 = min(self.current_frame_index + 5, len(self.movie))
        for i in xrange(r0, r1, 1):
            if i not in self.image_buffer.keys():
                self.image_buffer[i] = self.movie.Frame(i).get_image(
                    channel=self.channel)
        for i in self.image_buffer.keys():
            if i < r0 or i > r1:
                del self.image_buffer[i]

    def create_windows(self):
        ''' Create playback progress bar (allow user to move along the movie) '''
        cv2.namedWindow(self.win_name)
        cv2.moveWindow(self.win_name, 150, 150)
        cv2.namedWindow("completeness")
        cv2.moveWindow("completeness", 150, 50)
        cv2.setMouseCallback(self.win_name, self.trackbar_window_onMouse)
        cv2.createTrackbar("Frame", self.win_name, 0,
                           len(self.movie) - 1, self.jump_to_frame_callback)
        cv2.createTrackbar("Trim start", self.win_name, 0,
                           len(self.movie) - 1, self.set_trim_start)
        cv2.createTrackbar("Trim end", self.win_name,
                           len(self.movie) - 1,
                           len(self.movie) - 1, self.set_trim_end)
        im_height = 30  # 30 pixels high completeness bar
        im_width = len(self.movie)
        self.completeness_image = np.zeros((im_height, im_width, 3))
        current_frame_index = int(im_width * float(self.current_frame_index) /
                                  len(self.movie))
        self.completeness_image[:, current_frame_index, :] = 1.
        self.completeness = np.zeros(im_width, dtype=np.uint8)
        for i in xrange(len(self.movie)):
            bounds = self.movie.Frame(i).get_label(channel=self.channel,
                                                   target=self.target)
            if bounds is None or bounds.empty:
                if bounds is None:
                    self.movie.Frame(i).set_label(channel=self.channel,
                                                  target=self.target,
                                                  label=BoundingRegion())
                self.completeness[i] = 2
            else:
                if bounds.is_keyframe():
                    self.completeness[i] = 1
                else:
                    self.completeness[i] = 0

    def set_trim_start(self, frame_index):
        self.trim_start = frame_index + 0

    def set_trim_end(self, frame_index):
        self.trim_end = frame_index + 0

    def jump_to_frame_callback(self, frame_index):
        self.current_frame_index = frame_index
        self.image = self.movie.Frame(
            self.current_frame_index).get_image(channel=self.channel)
        self.needs_refresh = True

    def update_completeness_window(self):
        if self.ready_to_refresh.acquire(False):
            self.completeness_image *= 0
            self.completeness_image[:, self.current_frame_index, :] = 255
            for i in xrange(len(self.movie)):
                self.completeness_image[:, i, self.completeness[i]] = 255
            cv2.putText(self.completeness_image,
                        '%i' % self.current_frame_index, (10, 10),
                        cv2.FONT_HERSHEY_PLAIN,
                        1.0, (255, 255, 255),
                        lineType=cv2.CV_AA)
            cv2.imshow('completeness', self.completeness_image)
            self.ready_to_refresh.release()

    def update_trackbar_window(self):
        if self.ready_to_refresh.acquire():
            image = self.image.copy()
            self._stored_bounds = self.movie.Frame(
                self.current_frame_index).get_label(channel=self.channel,
                                                    target=self.target)
            # display rectangle over selected area
            self._current_bounds.draw_box(image, color=(255, 255, 255))
            self._current_bounds.draw_box(image, color=(0, 0, 0), thickness=1)
            # display rectangle over stored area
            if self._stored_bounds is not None:
                self._stored_bounds.draw_box(image, color=(255, 0, 0))
            if self._tracked_bounds is not None:
                self._tracked_bounds.draw_box(image, color=(0, 255, 0))
            # reshape to display if too small
            min_width = 320
            if image.shape[1] < min_width:
                resize_height = int(0.5 + image.shape[0] * min_width /
                                    float(image.shape[1]))
                image = cv2.resize(image, (min_width, resize_height),
                                   interpolation=cv2.INTER_NEAREST)
            self.display_image = image
            self.ready_to_refresh.release()

    def refresh(self):
        if self.timer_lock.acquire():
            if self.needs_refresh:
                self.update_trackbar_window()
                self.update_completeness_window()
                self.needs_refresh = False
            self.refresh_timer = threading.Timer(0.05, self.refresh)
            self.refresh_timer.start()
            self.timer_lock.release()

    def trackbar_window_onMouse(self, event, x, y, flags, _):
        cv2.imshow(self.win_name, self.display_image)
        # Update state
        self.right_button_pressed = (flags & cv2.EVENT_FLAG_RBUTTON
                                     ) != 0 and event != cv2.EVENT_RBUTTONUP
        self.left_button_pressed = (flags & cv2.EVENT_FLAG_LBUTTON
                                    ) != 0 and event != cv2.EVENT_LBUTTONUP

        # Set bounding box
        if event == cv2.EVENT_MBUTTONDOWN:
            if self._anchor is None:
                # Setting the anchor
                self._anchor = (x, y)
            else:
                # Defining the box
                self.save_and_advance()

        elif self._anchor is not None and event != cv2.EVENT_MBUTTONUP:
            # We are creating new bounding box from anchor to current position
            self.x_size = max(5, int(abs(x - self._anchor[0]) + 0.5))
            self.y_size = max(5, int(abs(y - self._anchor[1]) + 0.5))
            center_x = (x + self._anchor[0]) / 2
            center_y = (y + self._anchor[1]) / 2
            self.set_bounding_box_with_center(center_x, center_y)
        elif event == cv2.EVENT_MBUTTONUP:
            self.x_size = max(5, int(abs(x - self._anchor[0]) + 0.5))
            self.y_size = max(5, int(abs(y - self._anchor[1]) + 0.5))
            center_x = (x + self._anchor[0]) / 2
            center_y = (y + self._anchor[1]) / 2
            self.set_bounding_box_with_center(center_x, center_y)
            keyframe = False
            if flags & cv2.EVENT_FLAG_CTRLKEY != 0:
                keyframe = True
            self.save_and_advance(keyframe=keyframe)
        else:
            self.set_bounding_box_with_center(x, y)

        # If this is a left/right button down event,
        # we can advance one frame immediately
        # and then start the timer
        if event == cv2.EVENT_RBUTTONDOWN:
            self.set_target_absent()
            self.save_and_advance()
            self.right_button_pressed = True
            if self.timer.finished:
                # Rearm the timer
                self.schedule_callback()
        elif event == cv2.EVENT_LBUTTONDOWN:
            self.set_bounding_box_with_center(x, y)
            keyframe = False
            if flags & cv2.EVENT_FLAG_CTRLKEY != 0:
                keyframe = True
            self.save_and_advance(keyframe=keyframe)
            self.left_button_pressed = True
            if self.timer.finished:
                # Rearm the timer
                self.schedule_callback()
        elif not (self.right_button_pressed or self.left_button_pressed):
            # No mouse button pressed, so cancel the timer if it's running
            self.timer.cancel()
        if time.time() - self._last_update > 0.1:
            self._last_update = time.time()
            self.needs_refresh = True

    def set_target_absent(self):
        self._current_bounds = BoundingRegion()

    def set_bounding_box_with_center(self, x, y):
        box = [
            np.clip(int(x + 0.5) - self.x_size / 2, 0, self.image_shape[1]),
            np.clip(int(y + 0.5) - self.y_size / 2, 0, self.image_shape[0]),
            self.x_size + min(int(x + 0.5) - self.x_size / 2, 0),
            self.y_size + min(int(y + 0.5) - self.y_size / 2, 0)
        ]
        self._current_bounds = BoundingRegion(box=box)
        self.needs_refresh = True

    def schedule_callback(self):
        # 0.2 secs => 5 Hz
        self.timer = threading.Timer(0.1, self.timer_callback)
        self.timer.start()

    def timer_callback(self):
        if self.right_button_pressed or self.left_button_pressed:
            self.save_and_advance()
            self.schedule_callback()

    def advance_current_frame(self, increment=1):
        self.current_frame_index = min(
            len(self.movie) - 1, max(0, self.current_frame_index + increment))
        self.image = self.movie.Frame(
            self.current_frame_index).get_image(channel=self.channel)
        cv2.setTrackbarPos("Frame", self.win_name, self.current_frame_index)
        if self.tracker is not None:
            self._tracked_bounds = self.tracker.track(
                self.movie.Frame(
                    self.current_frame_index).get_image(channel=self.channel))

    def save_and_advance(self, keyframe=False):
        self._anchor = None
        self.movie.Frame(self.current_frame_index).set_label(
            self._current_bounds.copy(),
            channel=self.channel,
            target=self.target)
        if self._current_bounds.empty:
            self.completeness[self.current_frame_index] = 2
        else:
            if self._current_bounds.is_keyframe():
                self.completeness[self.current_frame_index] = 1
            else:
                self.completeness[self.current_frame_index] = 0
        if keyframe:
            self.make_keyframe()
            self.advance_current_frame(15)
        else:
            self.advance_current_frame(1)

    def toggle_tracker(self):
        if self.tracker is None:
            self.tracker = CMTVisionTracker()
            self.tracker.prime(
                self.movie.Frame(
                    self.current_frame_index).get_image(channel=self.channel),
                self._current_bounds)
            logging.warning("Tracker is enabled")
        else:
            self.tracker = None
            self._tracked_bounds = None
            logging.warning("Tracker is disabled")

    def advance_tracker(self):
        if self._tracked_bounds is not None:
            self._current_bounds = self._tracked_bounds
            self.save_and_advance()

    def export_movie(self):
        trim_frames_front = self.trim_start
        trim_frames_end = (len(self.movie) - 1) - self.trim_end
        if trim_frames_end > 0:
            for i in range(trim_frames_end):
                self.movie.delete(-1)
        if trim_frames_front > 0:
            for i in range(trim_frames_front):
                self.movie.delete(0)
        logging.warning("Exporting result in file " + self.output_file)
        self.movie.write_to_file(self.output_file)
        logging.warning("Exporting completed !")

    def interpolate(self, start, end):
        print "Interpolating %d %d" % (start, end)
        label0 = self.movie.Frame(start).get_label(channel=self.channel,
                                                   target=self.target)
        label1 = self.movie.Frame(end).get_label(channel=self.channel,
                                                 target=self.target)
        if (label0.empty) or (label1.empty):
            return
        box0 = label0.get_box_pixels()
        box1 = label1.get_box_pixels()

        for i in xrange(start + 1, end, 1):
            alpha = (end - i) * 1.0 / (end - start)
            box2 = alpha * np.array(box0) + (1 - alpha) * np.array(box1)
            box2 = map(lambda x: int(x), box2)
            self.movie.Frame(i).set_label(BoundingRegion(
                box=box2,
                image_shape=self.movie.Frame(i).get_image(
                    channel=self.channel).shape),
                                          channel=self.channel,
                                          target=self.target)
            self.completeness[i] = 0

    def make_keyframe(self):
        self.completeness[self.current_frame_index] = 1
        self.movie.Frame(self.current_frame_index).get_label(
            channel=self.channel, target=self.target).set_keyframe(True)

        # find previous keyframe
        next_keyframe = -1
        for i in xrange(self.current_frame_index + 1, len(self.movie), 1):
            bounds = self.movie.Frame(i).get_label(channel=self.channel,
                                                   target=self.target)
            if bounds.is_keyframe():
                next_keyframe = i
                break
        if next_keyframe >= 0:
            print next_keyframe
            self.interpolate(self.current_frame_index, next_keyframe)
        # find next keyframe
        prev_keyframe = -1
        for i in xrange(self.current_frame_index - 1, -1, -1):
            bounds = self.movie.Frame(i).get_label(channel=self.channel,
                                                   target=self.target)
            if bounds.is_keyframe():
                prev_keyframe = i
                break
        if prev_keyframe >= 0:
            print prev_keyframe
            self.interpolate(prev_keyframe, self.current_frame_index)

    def run(self):
        while True:
            key = cv2.waitKey(0)
            cv2.imshow(self.win_name, self.display_image)

            if key == 65361:  # left arrow
                # Go to previous frame
                self.advance_current_frame(-1)
            elif key == 65362:
                self.advance_current_frame(-10)
            elif key == 65363:  # right arrow
                # Go to next frame
                self.advance_current_frame()
            elif key == 65364:
                self.advance_current_frame(10)
            elif key == ord('w'):  # Write
                self.export_movie()
                if self.timer_lock.acquire():
                    if not self.refresh_timer.finished:
                        self.refresh_timer.cancel()
                    self.timer_lock.release()
                self.timer.cancel()
                self.reset()
            elif key == ord('t'):  # Tracker
                self.toggle_tracker()
            elif key == ord(' '):  # Advance tracker
                self.advance_tracker()
                self.needs_refresh = True
            elif key == ord('a'):
                self.x_size = int(self.x_size * 1.1)
                self.y_size = int(self.y_size * 1.1)
                self.needs_refresh = True
            elif key == ord('z'):
                self.x_size = int(self.x_size * 1 / 1.1)
                self.y_size = int(self.y_size * 1 / 1.1)
                self.needs_refresh = True
            elif key == ord('s'):
                self.y_size = int(self.y_size * 1.1)
                self.needs_refresh = True
            elif key == ord('k'):
                self.make_keyframe()
            elif key == ord('x'):
                self.y_size = int(self.y_size * 1 / 1.1)
                self.needs_refresh = True
            elif key == ord('q'):  # Export
                while key != -1:
                    for k in range(10):
                        key = cv2.waitKey(10)
                print "Quiting! Do you want to save your work? [Y/N]"
                while True:
                    key = cv2.waitKey(0)
                    if key == ord('Y') or key == ord('y'):
                        self.export_movie()
                        break
                    if key == ord('N') or key == ord('n'):
                        break
                break
        logging.warning('Exiting')
        self.refresh_timer.cancel()
Esempio n. 10
0
class LabelingApp(object):
    def __init__(self, filename, output=None, channel="default", target="default"):
        self.input_filename = filename
        if output is None:
            self.output_file = self.input_filename
        else:
            self.output_file = output
        self.channel = channel
        self.target = target
        self.reset()

    def reset(self, reload=False):
        cv2.destroyAllWindows()
        fc = FrameCollection()
        if reload:
            fc.load_from_file(filename=self.output_file)
        else:
            fc.load_from_file(filename=self.input_filename)
        self.movie = fc
        self.tracker = None
        self.current_frame_index = 0
        self.right_button_pressed = False
        self.left_button_pressed = False
        self._anchor = None
        self.x_size = 30
        self.y_size = 30
        self._tracked_bounds = None
        self._stored_bounds = None
        self._current_bounds = BoundingRegion()
        # Make sure self.timer is set
        self.schedule_callback()
        # Initialization of the Graphic User Interface
        self.ready_to_refresh = threading.Lock()
        self.timer_lock = threading.Lock()
        self.win_name = 'Labeling video GUI'
        self.image = self.movie.Frame(self.current_frame_index).get_image(channel=self.channel)
        self.display_image = self.movie.Frame(self.current_frame_index).get_image(channel=self.channel)
        self.image_shape = self.image.shape
        self.create_windows()
        self.set_target_absent()
        self.image_buffer = {}
        self._last_update = time.time()
        self.refresh_timer = threading.Timer(0.05, self.refresh)
        self.refresh_timer.start()
        self.needs_refresh = True
        self.trim_end = len(self.movie)-1
        self.trim_start = 0

    def fill_up_the_buffer(self):
        r0 = max(self.current_frame_index-5, 0)
        r1 = min(self.current_frame_index+5, len(self.movie))
        for i in xrange(r0, r1, 1):
            if i not in self.image_buffer.keys():
                self.image_buffer[i] = self.movie.Frame(i).get_image(channel=self.channel)
        for i in self.image_buffer.keys():
            if i < r0 or i > r1:
                del self.image_buffer[i]

    def create_windows(self):
        ''' Create playback progress bar (allow user to move along the movie) '''
        cv2.namedWindow(self.win_name)
        cv2.moveWindow(self.win_name, 150, 150)
        cv2.namedWindow("completeness")
        cv2.moveWindow("completeness", 150, 50)
        cv2.setMouseCallback(self.win_name, self.trackbar_window_onMouse)
        cv2.createTrackbar("Frame", self.win_name, 0, len(self.movie) - 1, self.jump_to_frame_callback)
        cv2.createTrackbar("Trim start", self.win_name, 0, len(self.movie) - 1, self.set_trim_start)
        cv2.createTrackbar("Trim end", self.win_name, len(self.movie) - 1, len(self.movie) - 1, self.set_trim_end)
        im_height = 30  # 30 pixels high completeness bar
        im_width = len(self.movie)
        self.completeness_image = np.zeros((im_height, im_width, 3))
        current_frame_index = int(im_width * float(self.current_frame_index) / len(self.movie))
        self.completeness_image[:, current_frame_index, :] = 1.
        self.completeness = np.zeros(im_width, dtype=np.uint8)
        for i in xrange(len(self.movie)):
            bounds = self.movie.Frame(i).get_label(channel=self.channel, target=self.target)
            if bounds is None or bounds.empty:
                if bounds is None:
                    self.movie.Frame(i).set_label(channel=self.channel, target=self.target, label=BoundingRegion())
                self.completeness[i] = 2
            else:
                if bounds.is_keyframe():
                    self.completeness[i] = 1
                else:
                    self.completeness[i] = 0

    def set_trim_start(self, frame_index):
        self.trim_start = frame_index + 0

    def set_trim_end(self, frame_index):
        self.trim_end = frame_index + 0

    def jump_to_frame_callback(self, frame_index):
        self.current_frame_index = frame_index
        self.image = self.movie.Frame(self.current_frame_index).get_image(channel=self.channel)
        self.needs_refresh = True

    def update_completeness_window(self):
        if self.ready_to_refresh.acquire(False):
            self.completeness_image *= 0
            self.completeness_image[:, self.current_frame_index, :] = 255
            for i in xrange(len(self.movie)):
                    self.completeness_image[:, i, self.completeness[i]] = 255
            cv2.putText(self.completeness_image, '%i' % self.current_frame_index,
                        (10, 10), cv2.FONT_HERSHEY_PLAIN, 1.0, (255, 255, 255), lineType=cv2.CV_AA)
            cv2.imshow('completeness', self.completeness_image)
            self.ready_to_refresh.release()

    def update_trackbar_window(self):
        if self.ready_to_refresh.acquire():
            image = self.image.copy()
            self._stored_bounds = self.movie.Frame(self.current_frame_index).get_label(channel=self.channel, target=self.target)
            # display rectangle over selected area
            self._current_bounds.draw_box(image, color=(255, 255, 255))
            self._current_bounds.draw_box(image, color=(0, 0, 0), thickness=1)
            # display rectangle over stored area
            if self._stored_bounds is not None:
                self._stored_bounds.draw_box(image, color=(255, 0, 0))
            if self._tracked_bounds is not None:
                self._tracked_bounds.draw_box(image, color=(0, 255, 0))
            # reshape to display if too small
            min_width = 320
            if image.shape[1] < min_width:
                resize_height = int(0.5 + image.shape[0] * min_width / float(image.shape[1]))
                image = cv2.resize(image, (min_width, resize_height), interpolation=cv2.INTER_NEAREST)
            self.display_image=image
            self.ready_to_refresh.release()

    def refresh(self):
        if self.timer_lock.acquire():
            if self.needs_refresh:
                self.update_trackbar_window()
                self.update_completeness_window()
                self.needs_refresh = False
            self.refresh_timer = threading.Timer(0.05, self.refresh)
            self.refresh_timer.start()
            self.timer_lock.release()

    def trackbar_window_onMouse(self, event, x, y, flags, _):
        cv2.imshow(self.win_name, self.display_image)
        # Update state
        self.right_button_pressed = (flags & cv2.EVENT_FLAG_RBUTTON) != 0 and event != cv2.EVENT_RBUTTONUP
        self.left_button_pressed = (flags & cv2.EVENT_FLAG_LBUTTON) != 0 and event != cv2.EVENT_LBUTTONUP

        # Set bounding box
        if event == cv2.EVENT_MBUTTONDOWN:
            if self._anchor is None:
                # Setting the anchor
                self._anchor = (x, y)
            else:
                # Defining the box
                self.save_and_advance()

        elif self._anchor is not None and event != cv2.EVENT_MBUTTONUP:
            # We are creating new bounding box from anchor to current position
            self.x_size = max(5, int(abs(x - self._anchor[0])+0.5))
            self.y_size = max(5, int(abs(y - self._anchor[1])+0.5))
            center_x = (x + self._anchor[0]) / 2
            center_y = (y + self._anchor[1]) / 2
            self.set_bounding_box_with_center(center_x, center_y)
        elif event == cv2.EVENT_MBUTTONUP:
            self.x_size = max(5, int(abs(x - self._anchor[0])+0.5))
            self.y_size = max(5, int(abs(y - self._anchor[1])+0.5))
            center_x = (x + self._anchor[0]) / 2
            center_y = (y + self._anchor[1]) / 2
            self.set_bounding_box_with_center(center_x, center_y)
            keyframe = False
            if flags & cv2.EVENT_FLAG_CTRLKEY != 0:
                keyframe = True
            self.save_and_advance(keyframe=keyframe)
        else:
            self.set_bounding_box_with_center(x, y)

        # If this is a left/right button down event,
        # we can advance one frame immediately
        # and then start the timer
        if event == cv2.EVENT_RBUTTONDOWN:
            self.set_target_absent()
            self.save_and_advance()
            self.right_button_pressed=True
            if self.timer.finished:
                # Rearm the timer
                self.schedule_callback()
        elif event == cv2.EVENT_LBUTTONDOWN:
            self.set_bounding_box_with_center(x, y)
            keyframe = False
            if flags & cv2.EVENT_FLAG_CTRLKEY != 0:
                keyframe = True
            self.save_and_advance(keyframe=keyframe)
            self.left_button_pressed=True
            if self.timer.finished:
                # Rearm the timer
                self.schedule_callback()
        elif not (self.right_button_pressed or self.left_button_pressed):
            # No mouse button pressed, so cancel the timer if it's running
            self.timer.cancel()
        if time.time()-self._last_update > 0.1:
            self._last_update = time.time()
            self.needs_refresh = True

    def set_target_absent(self):
        self._current_bounds = BoundingRegion()

    def set_bounding_box_with_center(self, x, y):
        box = [np.clip(int(x+0.5)-self.x_size/2, 0, self.image_shape[1]),
               np.clip(int(y+0.5)-self.y_size/2, 0, self.image_shape[0]),
               self.x_size + min(int(x+0.5)-self.x_size/2, 0),
               self.y_size + min(int(y+0.5)-self.y_size/2, 0)]
        self._current_bounds = BoundingRegion(box=box)
        self.needs_refresh = True

    def schedule_callback(self):
        # 0.2 secs => 5 Hz
        self.timer = threading.Timer(0.1, self.timer_callback)
        self.timer.start()

    def timer_callback(self):
        if self.right_button_pressed or self.left_button_pressed:
            self.save_and_advance()
            self.schedule_callback()

    def advance_current_frame(self, increment=1):
        self.current_frame_index = min(len(self.movie)-1, max(0, self.current_frame_index + increment))
        self.image = self.movie.Frame(self.current_frame_index).get_image(channel=self.channel)
        cv2.setTrackbarPos("Frame", self.win_name, self.current_frame_index)
        if self.tracker is not None:
            self._tracked_bounds = self.tracker.track(self.movie.Frame(self.current_frame_index).get_image(channel=self.channel))

    def save_and_advance(self, keyframe=False):
        self._anchor = None
        self.movie.Frame(self.current_frame_index).set_label(self._current_bounds.copy(), channel=self.channel, target=self.target)
        if self._current_bounds.empty:
            self.completeness[self.current_frame_index] = 2
        else:
            if self._current_bounds.is_keyframe():
                self.completeness[self.current_frame_index] = 1
            else:
                self.completeness[self.current_frame_index] = 0
        if keyframe:
            self.make_keyframe()
            self.advance_current_frame(15)
        else:
            self.advance_current_frame(1)

    def toggle_tracker(self):
        if self.tracker is None:
            self.tracker = CMTVisionTracker()
            self.tracker.prime(self.movie.Frame(self.current_frame_index).get_image(channel=self.channel), self._current_bounds)
            logging.warning("Tracker is enabled")
        else:
            self.tracker = None
            self._tracked_bounds = None
            logging.warning("Tracker is disabled")

    def advance_tracker(self):
        if self._tracked_bounds is not None:
            self._current_bounds=self._tracked_bounds
            self.save_and_advance()

    def export_movie(self):
        trim_frames_front = self.trim_start
        trim_frames_end = (len(self.movie) -1) - self.trim_end
        if trim_frames_end > 0:
            for i in range(trim_frames_end):
                self.movie.delete(-1)
        if trim_frames_front>0:
            for i in range(trim_frames_front):
                self.movie.delete(0)
        logging.warning("Exporting result in file " + self.output_file)
        self.movie.write_to_file(self.output_file)
        logging.warning("Exporting completed !")

    def interpolate(self, start, end):
        print "Interpolating %d %d" % (start, end)
        label0 = self.movie.Frame(start).get_label(channel=self.channel, target=self.target)
        label1 = self.movie.Frame(end).get_label(channel=self.channel, target=self.target)
        if (label0.empty) or (label1.empty):
            return
        box0 = label0.get_box_pixels()
        box1 = label1.get_box_pixels()

        for i in xrange(start+1, end, 1):
            alpha = (end-i)*1.0/(end-start)
            box2 = alpha*np.array(box0)+(1-alpha)*np.array(box1)
            box2 = map(lambda x: int(x), box2)
            self.movie.Frame(i).set_label(BoundingRegion(box=box2, image_shape=self.movie.Frame(i).get_image(channel=self.channel).shape), channel=self.channel, target=self.target)
            self.completeness[i] = 0

    def make_keyframe(self):
        self.completeness[self.current_frame_index] = 1
        self.movie.Frame(self.current_frame_index).get_label(channel=self.channel, target=self.target).set_keyframe(True)

        # find previous keyframe
        next_keyframe = -1
        for i in xrange(self.current_frame_index+1, len(self.movie), 1):
            bounds = self.movie.Frame(i).get_label(channel=self.channel, target=self.target)
            if bounds.is_keyframe():
                next_keyframe = i
                break
        if next_keyframe >= 0:
            print next_keyframe
            self.interpolate(self.current_frame_index, next_keyframe)
        # find next keyframe
        prev_keyframe = -1
        for i in xrange(self.current_frame_index-1, -1, -1):
            bounds = self.movie.Frame(i).get_label(channel=self.channel, target=self.target)
            if bounds.is_keyframe():
                prev_keyframe = i
                break
        if prev_keyframe >= 0:
            print prev_keyframe
            self.interpolate(prev_keyframe, self.current_frame_index)

    def run(self):
        while True:
            key = cv2.waitKey(0)
            cv2.imshow(self.win_name, self.display_image)

            if key == 65361:  # left arrow
                # Go to previous frame
                self.advance_current_frame(-1)
            elif key == 65362:
                self.advance_current_frame(-10)
            elif key == 65363:  # right arrow
                # Go to next frame
                self.advance_current_frame()
            elif key == 65364:
                self.advance_current_frame(10)
            elif key == ord('w'):  # Write
                self.export_movie()
                if self.timer_lock.acquire():
                    if not self.refresh_timer.finished:
                        self.refresh_timer.cancel()
                    self.timer_lock.release()
                self.timer.cancel()
                self.reset()
            elif key == ord('t'):  # Tracker
                self.toggle_tracker()
            elif key == ord(' '):  # Advance tracker
                self.advance_tracker()
                self.needs_refresh = True
            elif key == ord('a'):
                self.x_size = int(self.x_size*1.1)
                self.y_size = int(self.y_size*1.1)
                self.needs_refresh = True
            elif key == ord('z'):
                self.x_size = int(self.x_size*1/1.1)
                self.y_size = int(self.y_size*1/1.1)
                self.needs_refresh = True
            elif key == ord('s'):
                self.y_size = int(self.y_size*1.1)
                self.needs_refresh = True
            elif key == ord('k'):
                self.make_keyframe()
            elif key == ord('x'):
                self.y_size = int(self.y_size*1/1.1)
                self.needs_refresh = True
            elif key == ord('q'):  # Export
                while key != -1:
                    for k in range(10):
                        key = cv2.waitKey(10)
                print "Quiting! Do you want to save your work? [Y/N]"
                while True:
                    key = cv2.waitKey(0)
                    if key == ord('Y') or key == ord('y'):
                        self.export_movie()
                        break
                    if key == ord('N') or key == ord('n'):
                        break
                break
        logging.warning('Exiting')
        self.refresh_timer.cancel()
Esempio n. 11
0
class PVMVisionTracker(GenericVisionTracker):
    """
    This class exposes the null vision tracker which just always
    returns its priming bounding box

    """
    def __init__(self, filename="", remote_filename="", cores="4", storage=None, steps_per_frame=1):
        """
        Initialize the tracker
        """
        self.name = 'PVMtracker'
        if filename == "":
            filename = storage.get(remote_filename)
        self.prop_dict = CoreUtils.load_model(filename)
        logging.info("Loaded the dictionary %s", filename)
        PVM_Create.upgrade_dictionary_to_ver1_0(self.prop_dict)
        self.prop_dict['num_proc'] = int(cores)
        for k in range(len(self.prop_dict['learning_rates'])):
            self.prop_dict['learning_rates'][k][0] = 0.0
            logging.info("Setting learning rate in layer %d to zero" % k)
        self.prop_dict["readout_learning_rate"][0] = 0.0
        logging.info("Setting readout learning rate to zero")
        self.manager = Manager(self.prop_dict, 1000)
        self.executor = CoreUtils.ModelExecution(prop_dict=self.prop_dict, manager=self.manager, port=9100)
        self.executor.start(blocking=False)
        self.threshold = 32
        self.image_size = self.prop_dict['input_array'].shape[:2][::-1]
        self.readout_heatmap = np.zeros(self.image_size, dtype=np.float)
        self.step_per_frame = steps_per_frame

    def reset(self):
        """
        Reset the tracker
        :return:
        """
        self._primed = False
        self.bbox = None

    def _prime(self, im, bounding_region):
        """
        prime tracker on image and bounding box

        :param im: input image (3 - channel numpy array)
        :type im: numpy.ndarray
        :param bounding_region: initial bounding region of the tracked object
        :type bounding_region: PVM_tools.bounding_region.BoundingRegion
        """
        if not self._primed:
            logging.info("Priming the PVM tracker")
            logging.info("Setting up the tracker threshold to %d" % self.threshold)
            self._primed = True

    def _track(self, im):
        """
        Track on given image, rseturn a bounding box

        :param im: image (3 - channel numpy array)
        :type im: numpy.ndarray
        :return: bounding box of the tracker object
        :rtype: PVM_tools.bounding_region.BoundingRegion
        """
        #  this is required so that tracker is re-initialized if it is primed again
        current_frame = cv2.resize(im, dsize=self.image_size)
        self.prop_dict['input_array'][:] = current_frame
        self.prop_dict['input_array_float'][:] = current_frame.astype(np.float)/255
        for i in range(self.step_per_frame):
            self.executor.step()
        norm = 1.0 / len(self.prop_dict['predicted_readout_arrays'])
        self.readout_heatmap[:] = 0
        for k in self.prop_dict['predicted_readout_arrays']:
            self.readout_heatmap[:] += cv2.resize(k.view(np.ndarray), dsize=self.image_size) * norm
        am = np.unravel_index(np.argmax(self.readout_heatmap), self.readout_heatmap.shape)
        if len(am) == 3:
            for d in range(3):
                if am[2] != d:
                    self.readout_heatmap[:, :, d] = 0

        self.heatmap = self.readout_heatmap.view(np.ndarray)
        if len(self.heatmap.shape) == 3:
            self.heatmap = np.max(self.heatmap, axis=2)
        self.heatmap = cv2.resize(self.heatmap, dsize=(im.shape[1], im.shape[0]), interpolation=cv2.INTER_CUBIC)
        self.heatmap = (self.heatmap * 255).astype(np.uint8)
        if np.max(self.heatmap) > (np.median(self.heatmap)+self.threshold):
            threshold=(np.max(self.heatmap)-np.median(self.heatmap))*0.5+np.median(self.heatmap)
            ret, thresh = cv2.threshold(self.heatmap, threshold, 255, 0)
            contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
            if len(contours) > 0:
                max_cnt=None
                for cnt in contours:
                    pt = np.unravel_index(np.argmax(self.heatmap), self.heatmap.shape)
                    if cv2.pointPolygonTest(cnt, (pt[1], pt[0]), False)>=0:
                        max_cnt = cnt
                        break
                if max_cnt is None:
                    self.bbox = BoundingRegion()
                else:
                    x, y, w, h = cv2.boundingRect(max_cnt)
                    if w*h > 25:
                        self.bbox = BoundingRegion(image_shape=im.shape, box=[x, y, w, h])
                        self.bbox.scale(1.1)
                    else:
                        self.bbox = BoundingRegion()
            else:
                self.bbox = BoundingRegion()
        else:
            self.bbox = BoundingRegion()
        self._primed = False
        return self.bbox.copy()

    def get_heatmap(self, heatmap_name=None):
        return self.heatmap()

    def finish(self):
        self.manager._running = False
        self.executor.step()
        self.executor.finish()