예제 #1
0
    def spatial_box_grouping(self, frame_bboxes, min_combined_ratio=None):
        if min_combined_ratio is None:
            min_combined_ratio = self.min_combined_ratio

        current_boxes = list(frame_bboxes)
        merged_boxes = True

        while merged_boxes:
            merged_boxes = False

            # sort bounding boxes by descending size ...
            boxes_by_size = []
            for x1, y1, x2, y2 in current_boxes:
                w = x2 - x1 + 1
                h = y2 - y1 + 1
                area = w * h

                boxes_by_size.append((area, (x1, y1, x2, y2)))

            boxes_by_size = sorted(boxes_by_size,
                                   reverse=True,
                                   key=lambda x: x[0])

            # print(boxes_by_size)

            # create interval index to find matches quicker (all boxes against all boxes from same frame)
            int_index_x = IntervalIndex(True)
            int_index_y = IntervalIndex(True)
            for box_idx, (area, (x1, y1, x2, y2)) in enumerate(boxes_by_size):
                int_index_x.add(x1, x2 + 1, box_idx)
                int_index_y.add(y1, y2 + 1, box_idx)

            # ... find pair-wise matches ...
            set_x = set(int_index_x.find_matches(int_index_x))
            set_y = set(int_index_y.find_matches(int_index_y))
            # .... list of all pairs of boxes with intersecting intervals in X and Y
            merge_candidates = sorted(list(set_x.intersection(set_y)))
            # ... filter self-matches and repetitions ...
            merge_candidates = [(box_idx1, box_idx2)
                                for box_idx1, box_idx2 in merge_candidates
                                if box_idx1 < box_idx2]
            # ... split by first box ..
            candidates_by_box = {idx: [] for idx in range(len(boxes_by_size))}
            for box_idx1, box_idx2 in merge_candidates:
                candidates_by_box[box_idx1].append(box_idx2)

            # print(merge_candidates)
            # print(candidates_by_box)

            box_added = [False] * len(boxes_by_size)
            current_boxes = []
            # for each box (sorted by size)
            for box_idx in range(len(boxes_by_size)):
                # if this box has been previously added (merged with ealier box)
                if box_added[box_idx]:
                    # skip ...
                    continue

                box_added[box_idx] = True

                # current box boundaries
                c_area, (c_x1, c_y1, c_x2, c_y2) = boxes_by_size[box_idx]

                for second_box_idx in candidates_by_box[box_idx]:
                    if box_added[second_box_idx]:
                        # skip merge candidate ...
                        continue

                    # get box boundaries ...
                    o_area, (o_x1, o_y1, o_x2,
                             o_y2) = boxes_by_size[second_box_idx]

                    comb_area_ratio = self.get_combined_box_area_ratio(
                        (c_x1, c_y1, c_x2, c_y2), (o_x1, o_y1, o_x2, o_y2))

                    # print(((c_x1, c_y1, c_x2, c_y2), boxes_by_size[second_box_idx], comb_area_ratio, box_idx, second_box_idx))

                    if comb_area_ratio >= min_combined_ratio:
                        # merge!
                        # expand current bounding box to include the smaller box ...
                        c_x1 = min(c_x1, o_x1)
                        c_y1 = min(c_y1, o_y1)
                        c_x2 = max(c_x2, o_x2)
                        c_y2 = max(c_y2, o_y2)

                        # mark second box as added, so it won't be added to the current list ..
                        box_added[second_box_idx] = True

                        merged_boxes = True

                # add to the next set of accepted boxes
                current_boxes.append((c_x1, c_y1, c_x2, c_y2))
        """
        if len(frame_bboxes) > 30:
            original_img = self.visualize_boxes(frame_bboxes, (255, 0, 0))
            final_img = self.visualize_boxes(current_boxes, (0, 255, 0))
            final_img[:, :, 0] = original_img[:, :, 0]
            debug_img = cv2.resize(final_img,(960, 540))
            cv2.imshow("check", debug_img)
            cv2.waitKey()
            raise Exception("Error!")
        """

        return current_boxes
예제 #2
0
    def add_frame(self, frame_bboxes):
        current_bboxes = self.spatial_box_grouping(frame_bboxes,
                                                   self.min_combined_ratio)

        current_bboxes_idxs = []
        if self.img_idx == 0:
            # simply copy all
            for bbox_id, bbox in enumerate(current_bboxes):
                # add the box to list of unique boxes ...
                self.unique_bbox_objects.append(bbox)

                # frames on which the bbox appears, raw label assigned to that CC
                self.unique_bbox_frames.append([(0, bbox_id)])

                bbox_idx = len(self.unique_bbox_objects) - 1
                current_bboxes_idxs.append((bbox_idx, bbox))

                self.bbox_last_frame.append(0)
                self.bbox_active.append(bbox_idx)

                # add to indices ...
                x1, y1, x2, y2 = bbox
                self.bbox_int_index_x.add(x1, x2, bbox_idx)
                self.bbox_int_index_y.add(y1, y2, bbox_idx)
        else:
            # create indices for current bboxes
            other_index_x = IntervalIndex(True)
            other_index_y = IntervalIndex(True)

            for bbox_idx, (x1, y1, x2, y2) in enumerate(current_bboxes):
                other_index_x.add(x1, x2, bbox_idx)
                other_index_y.add(y1, y2, bbox_idx)

            # compute CC with matching regions
            set_x = set(other_index_x.find_matches(self.bbox_int_index_x))
            set_y = set(other_index_y.find_matches(self.bbox_int_index_y))

            # list of all pairs of CC with intersecting intervals in X and Y
            merged = sorted(list(set_x.intersection(set_y)))
            self.tempo_count += len(merged)

            # check every matching CC
            pre_add_size = len(self.bbox_active)
            next_match_idx = 0

            for bbox_idx, bbox in enumerate(current_bboxes):
                found = False

                # check all matches in the list of matches for current CC
                while next_match_idx < len(
                        merged) and merged[next_match_idx][0] == bbox_idx:
                    if not found:
                        prev_idx = merged[next_match_idx][1]
                        prev_bbox = self.unique_bbox_objects[prev_idx]

                        bbox_IOU = self.get_bboxes_IOU(bbox, prev_bbox)
                        # print(bbox_IOU)
                        if bbox_IOU >= self.min_temporal_IOU:
                            # assume they are equivalent
                            found = True
                            self.unique_bbox_frames[prev_idx].append(
                                (self.img_idx, bbox_idx))
                            current_bboxes_idxs.append((prev_idx, bbox))

                            # update last frame seen for this cc...
                            self.bbox_last_frame[prev_idx] = self.img_idx

                    next_match_idx += 1

                # Not match was found?
                if not found:
                    # add
                    self.unique_bbox_objects.append(bbox)
                    self.unique_bbox_frames.append([(self.img_idx, bbox_idx)])

                    new_bbox_idx = len(self.unique_bbox_objects) - 1
                    current_bboxes_idxs.append((new_bbox_idx, bbox))

                    self.bbox_last_frame.append(self.img_idx)
                    self.bbox_active.append(new_bbox_idx)

                    # add to indices ...
                    x1, y1, x2, y2 = bbox
                    self.bbox_int_index_x.add(x1, x2, new_bbox_idx)
                    self.bbox_int_index_y.add(y1, y2, new_bbox_idx)

            # remove CC that are no longer active
            pre_remove_size = len(self.bbox_active)
            tempo_pos = 0
            while tempo_pos < len(self.bbox_active):
                bbox_idx = self.bbox_active[tempo_pos]

                if self.img_idx - self.bbox_last_frame[
                        bbox_idx] >= self.max_gap:
                    # no longer active ..
                    # delete from active list
                    del self.bbox_active[tempo_pos]

                    # delete from interval indices
                    bbox = self.unique_bbox_objects[bbox_idx]
                    x1, y1, x2, y2 = bbox
                    self.bbox_int_index_x.remove(x1, x2, bbox_idx)
                    self.bbox_int_index_y.remove(y1, y2, bbox_idx)
                    #print self.cc_last_frame[cc_idx],
                else:
                    # still active
                    tempo_pos += 1
            """
            total_added = pre_remove_size - pre_add_size
            total_removed = pre_remove_size - len(self.bbox_active)
            msg = "{0:d} , (Added: {1:d}, Removed: {2:d})".format(len(self.bbox_active), total_added, total_removed)
            print(msg)
            """

        self.bbox_idx_per_frame.append(current_bboxes_idxs)

        self.img_idx += 1

        if self.verbose:
            msg = "[{0:d} ({1:d}, {2:d})]".format(
                self.img_idx, len(current_bboxes),
                len(self.unique_bbox_objects))
            print(msg, end="\r")
예제 #3
0
    def add_frame(self, img, input_binary=False):
        # get the CC
        if input_binary:
            # use given binary
            binary = img
        else:
            # binarize
            binary = Binarizer.backgroundSubtractionBinarization(img.astype('uint8'))

        current_cc = Labeler.extractSpatioTemporalContent(binary, self.fake_age)
        current_cc_idxs = []
        if self.img_idx == 0:
            # simply copy all
            for cc in current_cc:
                self.unique_cc_objects.append(cc) # CC objet

                # frames on which the CC appears, raw label assigend to that CC
                self.unique_cc_frames.append([(0, cc.cc_id + 1)])

                cc_idx = len(self.unique_cc_objects) - 1
                current_cc_idxs.append((cc_idx, cc))

                self.cc_last_frame.append(0)
                self.cc_active.append(cc_idx)


                # add to indices ...
                self.cc_int_index_x.add(cc.min_x, cc.max_x + 1, cc_idx)
                self.cc_int_index_y.add(cc.min_y, cc.max_y + 1, cc_idx)

        else:
            # create indices for current CC
            other_index_x = IntervalIndex(True)
            other_index_y = IntervalIndex(True)
            for cc_idx, cc in enumerate(current_cc):
                other_index_x.add(cc.min_x, cc.max_x + 1, cc_idx)
                other_index_y.add(cc.min_y, cc.max_y + 1, cc_idx)

            # compute CC with matching regions
            set_x = set(other_index_x.find_matches(self.cc_int_index_x))
            set_y = set(other_index_y.find_matches(self.cc_int_index_y))

            # list of all pairs of CC with intersecting intervals in X and Y
            merged = sorted(list(set_x.intersection(set_y)))
            self.tempo_count += len(merged)

            # check every matching CC
            pre_add_size = len(self.cc_active)
            next_match_idx = 0
            for cc_idx, cc in enumerate(current_cc):
                found = False
                # check all matches in the list of matches for current CC
                while next_match_idx < len(merged) and merged[next_match_idx][0] == cc_idx:
                    if not found:
                        prev_idx = merged[next_match_idx][1]
                        prev_cc = self.unique_cc_objects[prev_idx]

                        recall, precision = cc.getOverlapFMeasure(prev_cc, False, False)
                        if recall >= self.min_recall and precision >= self.min_precision:
                            # assume they are equivalent
                            found = True
                            self.unique_cc_frames[prev_idx].append((self.img_idx, cc.cc_id + 1))
                            current_cc_idxs.append((prev_idx, cc))

                            # update last frame seen for this cc...
                            self.cc_last_frame[prev_idx] = self.img_idx

                    next_match_idx += 1

                # Not match was found?
                if not found:
                    # add
                    self.unique_cc_objects.append(cc)
                    self.unique_cc_frames.append([(self.img_idx, cc.cc_id + 1)])

                    new_cc_idx = len(self.unique_cc_objects) - 1
                    current_cc_idxs.append((new_cc_idx, cc))

                    self.cc_last_frame.append(self.img_idx)
                    self.cc_active.append(new_cc_idx)

                    # add to indices ...
                    self.cc_int_index_x.add(cc.min_x, cc.max_x + 1, new_cc_idx)
                    self.cc_int_index_y.add(cc.min_y, cc.max_y + 1, new_cc_idx)

            # remove CC that are no longer active
            pre_remove_size = len(self.cc_active)
            tempo_pos = 0
            while tempo_pos < len(self.cc_active):
                cc_idx = self.cc_active[tempo_pos]

                if self.img_idx - self.cc_last_frame[cc_idx] >= self.max_gap:
                    # no longer active ..
                    # delete from active list
                    del self.cc_active[tempo_pos]

                    # delete from interval indices
                    cc = self.unique_cc_objects[cc_idx]
                    self.cc_int_index_x.remove(cc.min_x, cc.max_x + 1, cc_idx)
                    self.cc_int_index_y.remove(cc.min_y, cc.max_y + 1, cc_idx)

                    #print self.cc_last_frame[cc_idx],
                else:
                    # still active
                    tempo_pos += 1

            #print(str(len(self.cc_active)) + ", (Added: " + str(pre_remove_size - pre_add_size) + ", Removed: " + str(pre_remove_size - len(self.cc_active)) + ")")


        self.cc_idx_per_frame.append(current_cc_idxs)

        self.img_idx += 1

        if self.verbose:
            print("[" + str(self.img_idx) + " (" +  str(len(current_cc)) + ", " + str(len(self.unique_cc_objects)) + ")]", end="\r")