示例#1
0
 def _add_resized(self, image, bbox):
     h0, w0 = image_helper.image_h_w(image)
     image = image_helper.resize_if_larger(image, self._dim)
     h1, w1 = image_helper.image_h_w(image)
     self._ratio_h = h0 / h1
     self._ratio_w = w0 / w1
     tracker = self._create_tracker(self._tracker_algorithm)
     x1, y1, w, h = bbox
     bbox = (int(x1 / self._ratio_w), int(y1 / self._ratio_h),
             int(w / self._ratio_w), int(h / self._ratio_h))
     tracker.init(image, bbox)
     self._cv_trackers.append(tracker)
示例#2
0
def yolo_label_maker(frame, rects, class_id, save_dir):
    lines = []
    for rect in rects:
        y1, x1, y2, x2 = rect
        h, w = image_helper.image_h_w(frame)
        cx = ((x1 + x2) * 0.5) / w
        cy = ((y1 + y2) * 0.5) / h
        w = (x2 - x1) / w
        h = (y2 - y1) / h
        line = "{} {} {} {} {}".format(class_id, cx, cy, w, h)
        lines.append(line)

    name = str(uuid.uuid4().hex)
    image_fn = file_helper.path_join(save_dir, name + ".jpg")
    label_fn = file_helper.path_join(save_dir, name + ".txt")
    cv2.imwrite(image_fn, frame)
    file_helper.write_lines(label_fn, lines)
示例#3
0
    def process_frame(self, frame, extra_data=None):
        super().process_frame(frame)

        items_of_groups = {}
        results = extra_data.get(constants.EXTRA_DATA_KEY_RESULTS, None)
        if results is not None:
            h0, w0 = image_helper.image_h_w(frame)
            max_x = w0 - 1
            max_y = h0 - 1
            for runner_name, result in results.items():
                remove_indexes = []
                for result_index, item in enumerate(result):
                    rect = item.get(constants.RESULT_KEY_RECT, None)
                    if rect is not None:
                        class_name = item.get(constants.RESULT_KEY_CLASS_NAME,
                                              None)
                        group_name = self._get_group_name(class_name)
                        if group_name is not None:
                            if group_name not in items_of_groups:
                                items_of_groups[group_name] = []
                            items = items_of_groups[group_name]
                            bbox = self._rect_to_bbox(rect, max_x, max_y)
                            if bbox is not None:
                                item["tr_bbox"] = bbox
                                item["tr_group_name"] = group_name
                                remove_indexes.append(result_index)
                                handled = False
                                for i, item0 in enumerate(items):
                                    rect0 = item0[constants.RESULT_KEY_RECT]
                                    if geometry_helper.rects_overlap(
                                            rect, rect0, 0.75):
                                        handled = True
                                        if item.get(
                                                constants.RESULT_KEY_SCORE,
                                                0.9) > item0.get(
                                                    constants.RESULT_KEY_SCORE,
                                                    0.9):
                                            items[i] = item
                                        break
                                if not handled:
                                    items.append(item)
                remove_indexes.sort(reverse=True)
                for i in remove_indexes:
                    del result[i]

        res = []
        for group_name, items in items_of_groups.items():
            if len(items) > 0:
                self._cv_tracker[group_name] = CvTracker(
                    self._tracker_algorithm)
                self._last_items[group_name] = items
                for item in items:
                    bbox = item["tr_bbox"]
                    self._cv_tracker[group_name].add(frame, bbox)
            else:
                if group_name not in self._last_items[group_name]:
                    self._last_items[group_name] = []
                items = self._last_items[group_name]
                items_ok = []
                for i, (ok, bbox) in enumerate(
                        self._cv_tracker[group_name].update(frame)):
                    if ok:
                        item = items[i]
                        item["tr_bbox"] = bbox
                        item[constants.RESULT_KEY_RECT] = self._bbox_to_rect(
                            bbox)
                        items_ok.append(item)
                items = items_ok

            center_item_index = []
            active_counts = {}
            class_dets = {}
            for i, item in enumerate(items):
                if "tr_bbox" in item:
                    rect = item.get(constants.RESULT_KEY_RECT, None)
                    group_name1 = item["tr_group_name"]
                    if group_name1 not in class_dets:
                        class_dets[group_name1] = []
                    score = item.get(constants.RESULT_KEY_SCORE, 0.9)
                    det = [rect[1], rect[0], rect[3], rect[2], score]
                    if not self._det_exists(class_dets[group_name1], det):
                        class_dets[group_name1].append(det)
                        center_item_index.append(
                            (self._get_box_center(det), item, i))

            if group_name not in self._g:
                self._g[group_name] = {}
            g = self._g[group_name]
            g_sorts = g.get("sorts", {})
            g_memory = g.get("memory", {})

            previous = g_memory.copy()
            g_memory = {}

            for name, dets in class_dets.items():
                if name not in g_sorts:
                    g_sorts[name] = Sort(max_age=10,
                                         min_hits=1,
                                         iou_threshold=0.001)
                    # g_sorts[name] = Sort(max_age=1, min_hits=3, iou_threshold=0.3)
                    # g_sorts[name] = Sort()
                    # g_sorts[name] = Sort(max_age=1, min_hits=1, iou_threshold=0.03)
                    # g_sorts[name] = Sort(max_age=10, min_hits=0, iou_threshold=0.000001)
                    # g_sorts[name] = Sort(max_age=30, min_hits=1, iou_threshold=0.001)

                sort = g_sorts[
                    name]  # ref: https://github.com/abewley/sort   https://github.com/HodenX/python-traffic-counter-with-yolo-and-sort
                dets1 = np.array(dets)
                tracks = sort.update(dets1)

                active_counts[name] = len(tracks)

                boxes = []
                track_ids = []

                for track in tracks:
                    boxes.append(
                        [track[0], track[1], track[2], track[3], track[4]])
                    track_id = int(track[4])
                    track_ids.append(track_id)
                    if track_id in previous:
                        track0 = previous[track_id]
                        dist = (math.fabs(track[0] - track0[0]) +
                                math.fabs(track[1] - track0[1]) +
                                math.fabs(track[2] - track0[2]) +
                                math.fabs(track[3] - track0[3])) / 4.0
                        if dist > 30:
                            g_memory[track_id] = boxes[-1]
                        else:
                            g_memory[track_id] = track0
                    else:
                        g_memory[track_id] = boxes[-1]
                if len(boxes) > 0:
                    for i, box in enumerate(boxes):
                        track_id = track_ids[i]
                        if track_id in previous:
                            previous_box = previous.get(track_id, None)
                            if previous_box is not None:
                                c = self._get_box_center(box)
                                min_dist = sys.maxsize
                                result_item = None
                                for center, item, i0 in center_item_index:
                                    dist = geometry_helper.distance(c, center)
                                    if dist < min_dist:
                                        min_dist = dist
                                        result_item = item
                                if result_item is not None:
                                    result_item[constants.
                                                RESULT_KEY_TRACK_ID] = track_id
                                    result_item[
                                        constants.
                                        RESULT_KEY_PREVIEW_KEY] = track_id
                        else:
                            result_item = items[i]
                            result_item[
                                constants.RESULT_KEY_TRACK_ID] = track_id
                            result_item[
                                constants.RESULT_KEY_PREVIEW_KEY] = track_id
                else:
                    for i in range(len(items)):
                        result_item = items[i]
                        result_item[constants.RESULT_KEY_TRACK_ID] = -1
                        result_item[constants.RESULT_KEY_PREVIEW_KEY] = -1

            g["sorts"] = g_sorts
            g["memory"] = g_memory
            res.extend(items)
        return res
示例#4
0
    def _get_preview(self, image, results):
        def get_color(obj, class_preview_key_, color=None):
            if color is None:
                color = [255, 255, 255]
                if class_preview_key_ is not None:
                    if not hasattr(obj, "__colors"):
                        setattr(obj, "__colors", {})
                    dic = getattr(obj, "__colors")
                    if class_preview_key_ in dic:
                        color = dic[class_preview_key_]
                    else:
                        color = dic[class_preview_key_] = self._new_color()
            return color

        def draw_rect(obj, img, c1_, c2_, class_preview_key_, color=None):
            if color is None:
                color = get_color(obj, class_preview_key_, color)
            cv2.rectangle(img, (c1_[0], c1_[1]), (c2_[0], c2_[1]), color=[1, 1, 1], thickness=3)
            cv2.rectangle(img, (c1_[0], c1_[1]), (c2_[0], c2_[1]), color=color, thickness=2)

        show_debug_texts = self.__preview_show_debug_texts
        show_runner_info = self.__preview_show_runner_info
        show_score = self.__preview_show_score
        rect_filters = self.__preview_show_rect_filters
        show_rect_name = self.__preview_show_rect_name
        show_track_id = self.__preview_show_track_id
        show_track_pnt = self.__preview_show_track_pnt

        h, w, *_ = image.shape
        line_height = 20
        font_scale = 0.4
        current_line = [20, 0]
        current_line_bottom = [20, h]
        data_added = []
        if results is not None:
            for result in results:
                debug_texts = []
                text_type = ""
                has_data = False

                if show_runner_info:
                    total_elapsed_time = result.get("total_elapsed_time", None)
                    if total_elapsed_time is not None:
                        image_helper.put_text(image, total_elapsed_time, [w - 150, h - 30], color=[200, 200, 128],
                                              font_scale=0.4)
                        continue

                values = {}
                elapsed_time = values["elapsed_time"] = result.get("elapsed_time", None)
                class_name = values[constants.RESULT_KEY_CLASS_NAME] = result.get(constants.RESULT_KEY_CLASS_NAME, None)
                class_preview_key = values[constants.RESULT_KEY_PREVIEW_KEY] = result.get(
                    constants.RESULT_KEY_PREVIEW_KEY, class_name)
                score = values[constants.RESULT_KEY_SCORE] = result.get(constants.RESULT_KEY_SCORE, None)
                rect = values[constants.RESULT_KEY_RECT] = result.get(constants.RESULT_KEY_RECT, None)
                rect_debug_text = values[constants.RESULT_KEY_RECT_DEBUG_TEXT] = result.get(
                    constants.RESULT_KEY_RECT_DEBUG_TEXT, None)
                data = values[constants.RESULT_KEY_DATA] = result.get(constants.RESULT_KEY_DATA, None)
                debug_text = values[constants.RESULT_KEY_DEBUG] = result.get(constants.RESULT_KEY_DEBUG, None)

                if debug_text is not None:
                    debug_texts.append(debug_text)

                def _get_score_txt(text_, score_):
                    res = "%{:.2f} ".format(score_ * 100) if isinstance(score_, float) else score_
                    if text_ is not None and len(text_) > 0:
                        return "{}- {} ".format(text_, res)
                    else:
                        return res

                text = ""
                if class_name is not None:
                    text = NDUUtility.debug_conv_turkish(class_name) + " "
                    if show_score and score is not None:
                        text = _get_score_txt(text, score)
                elif show_score and score is not None:
                    text = _get_score_txt(None, score)

                if data is not None:
                    add_txt = " data: " + str(data)
                    data_added.append(add_txt)
                    text = text + add_txt
                    has_data = True
                if rect is not None:
                    c = np.array(rect[:4], dtype=np.int32)
                    c1, c2 = [c[1], c[0]], (c[3], c[2])
                    color_rect = get_color(self, class_preview_key, result.get(constants.RESULT_KEY_RECT_COLOR, None))
                    show_rect = True
                    if rect_filters is not None:
                        show_rect = False
                        for rect_filter in rect_filters:
                            if string_helper.wildcard(class_name, rect_filter):
                                show_rect = True
                                break
                    if show_rect:
                        draw_rect(self, image, c1, c2, class_preview_key, color_rect)
                    else:
                        text = ""
                    if show_rect and show_rect_name and len(text) > 0:
                        # c1[1] = c1[1] + line_height
                        c1[1] -= 10
                        if rect_debug_text is not None:
                            text += " - " + rect_debug_text
                        image_helper.put_text(image, text, c1)
                        text = ""
                    if show_rect and show_track_id:
                        track_id = result.get(constants.RESULT_KEY_TRACK_ID, None)
                        if track_id is not None:
                            # c1[1] -= line_height * 1.5
                            c1[1] -= 15
                            image_helper.put_text(image, "{}".format(track_id), c1)
                    if show_track_pnt:
                        track_id = result.get(constants.RESULT_KEY_TRACK_ID, None)
                        if track_id is not None:
                            if self._track_pnt_layer is None:
                                h, w = image_helper.image_h_w(image)
                                self._track_pnt_layer = np.zeros((h, w, 3), np.uint8)
                            self._track_pnt_layer = image_helper.change_brightness(self._track_pnt_layer, -1)
                            y1, x1, y2, x2 = tuple(rect)
                            pnt = (int(x1 + (x2 - x1) * 0.5), int(y2))
                            pnts_key = str(track_id)
                            pnts = self._track_pnts.get(pnts_key, [])
                            pnts.append(pnt)
                            self._track_pnts[pnts_key] = pnts
                            if len(pnts) > 1:
                                pts = np.array(pnts, np.int32)
                                # cv2.polylines(self._track_pnt_layer, [pts], False, color, 5)
                                # cv2.polylines(image, [pts], False, color_rect, 5)
                                thickness = 10
                                for i in range(len(pnts) - 1, 0, -1):
                                    p0 = pnts[i]
                                    p1 = pnts[i - 1]
                                    cv2.line(image, p0, p1, color_rect, thickness)
                                    if i % 10 == 0:
                                        thickness -= 1
                                        if thickness < 1:
                                            # pnts = pnts[i: len(pnts)]
                                            break

                            # color = [255,255,255]
                            # cv2.circle(self._track_pnt_layer, pnt, 1, color, 8)
                            # image = cv2.addWeighted(image, 1, self._track_pnt_layer, 1,)
                            # ret, mask = cv2.threshold(self._track_pnt_layer, 1, 255, cv2.THRESH_BINARY)
                            # mask = cv2.bitwise_not(mask)
                            # mask = cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY)
                            # image = cv2.bitwise_and(image, image, mask=mask)
                            # image = cv2.addWeighted(image, 1, self._track_pnt_layer, 0.1, 1)
                            # image += self._track_pnt_layer
                            # image = self._track_pnt_layer.copy()

                if elapsed_time is not None:
                    text_type = elapsed_time + " " + text_type
                if len(text) > 0:
                    text_type = text_type + text + " "
                if show_runner_info and len(text_type) > 0:
                    current_line[1] += line_height
                    if show_runner_info:
                        if not has_data:
                            image_helper.put_text(image, text_type, current_line, font_scale=font_scale)
                        else:
                            image_helper.put_text(image, text_type, current_line, color=[0, 0, 255],
                                                  font_scale=font_scale)
                if show_debug_texts and len(debug_texts) > 0:
                    for debug_text in debug_texts:
                        current_line_bottom[1] -= line_height * 2
                        image_helper.put_text(image, debug_text, current_line_bottom, color=[255, 250, 99],
                                              font_scale=font_scale * 2.75, thickness=2, back_color=[1, 1, 1])

        if show_runner_info:
            if len(data_added) > 0:
                show_last_data_frame_time = time.time()
                for data in data_added:
                    if data not in self.__preview_last_data:
                        self.__preview_last_data.append(data)
                        self.__preview_last_data_show_times.append(show_last_data_frame_time)
                    else:
                        self.__preview_last_data_show_times[
                            self.__preview_last_data.index(data)] = show_last_data_frame_time
            for i in reversed(range(len(self.__preview_last_data))):
                elapsed = time.time() - self.__preview_last_data_show_times[i]
                if elapsed > 5:
                    del self.__preview_last_data_show_times[i]
                    del self.__preview_last_data[i]
            for last_data in self.__preview_last_data:
                current_line[1] += line_height
                image_helper.put_text(image, last_data, current_line, color=[0, 255, 255])

        return image
示例#5
0
    def process_frame(self, frame, extra_data=None):
        def to_bbox(coordinates, rect_, rh_, rw_):
            x1 = coordinates[0]["x"] * rw_
            y1 = coordinates[0]["y"] * rh_
            x2 = coordinates[2]["x"] * rw_
            y2 = coordinates[2]["y"] * rh_
            if rect_ is not None:
                x1 += rect_[1]
                y1 += rect_[0]
                x2 += rect_[1]
                y2 += rect_[0]
            return [y1, x1, y2, x2]

        def enumerate_images(frame_):
            result = yolo_helper.predict_v4(self.sess_tuple, self.input_size,
                                            self.class_names, frame)
            for _class_name, _score, rect0, item_ in NDUUtility.enumerate_result_items(
                    result, return_item=True):
                rect1 = geometry_helper.add_padding_rect(rect0, 0.5)
                yield image_helper.crop(frame, rect1), rect0, item_

        res = []
        for image, rect, item in enumerate_images(frame):
            h0, w0 = image_helper.image_h_w(image)

            # def order_points(pts):
            #     # initialzie a list of coordinates that will be ordered
            #     # such that the first entry in the list is the top-left,
            #     # the second entry is the top-right, the third is the
            #     # bottom-right, and the fourth is the bottom-left
            #     rect = np.zeros((4, 2), dtype="float32")
            #
            #     # the top-left point will have the smallest sum, whereas
            #     # the bottom-right point will have the largest sum
            #     s = pts.sum(axis=1)
            #     rect[0] = pts[np.argmin(s)]
            #     rect[2] = pts[np.argmax(s)]
            #
            #     # now, compute the difference between the points, the
            #     # top-right point will have the smallest difference,
            #     # whereas the bottom-left will have the largest difference
            #     diff = np.diff(pts, axis=1)
            #     rect[1] = pts[np.argmin(diff)]
            #     rect[3] = pts[np.argmax(diff)]
            #
            #     # return the ordered coordinates
            #     return rect
            #
            # def four_point_transform(image, pts):
            #     # obtain a consistent order of the points and unpack them
            #     # individually
            #     rect = order_points(pts)
            #     (tl, tr, br, bl) = rect
            #
            #     # compute the width of the new image, which will be the
            #     # maximum distance between bottom-right and bottom-left
            #     # x-coordiates or the top-right and top-left x-coordinates
            #     widthA = np.sqrt(((br[0] - bl[0]) ** 2) + ((br[1] - bl[1]) ** 2))
            #     widthB = np.sqrt(((tr[0] - tl[0]) ** 2) + ((tr[1] - tl[1]) ** 2))
            #     maxWidth = max(int(widthA), int(widthB))
            #
            #     # compute the height of the new image, which will be the
            #     # maximum distance between the top-right and bottom-right
            #     # y-coordinates or the top-left and bottom-left y-coordinates
            #     heightA = np.sqrt(((tr[0] - br[0]) ** 2) + ((tr[1] - br[1]) ** 2))
            #     heightB = np.sqrt(((tl[0] - bl[0]) ** 2) + ((tl[1] - bl[1]) ** 2))
            #     maxHeight = max(int(heightA), int(heightB))
            #
            #     # now that we have the dimensions of the new image, construct
            #     # the set of destination points to obtain a "birds eye view",
            #     # (i.e. top-down view) of the image, again specifying points
            #     # in the top-left, top-right, bottom-right, and bottom-left
            #     # order
            #     dst = np.array([
            #         [0, 0],
            #         [maxWidth - 1, 0],
            #         [maxWidth - 1, maxHeight - 1],
            #         [0, maxHeight - 1]], dtype="float32")
            #
            #     # compute the perspective transform matrix and then apply it
            #     M = cv2.getPerspectiveTransform(rect, dst)
            #     warped = cv2.warpPerspective(image, M, (maxWidth, maxHeight))
            #     return warped
            #
            # def deskew(image):
            #     gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
            #     gray = cv2.bitwise_not(gray)
            #     thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
            #     coords = np.column_stack(np.where(thresh > 0))
            #     angle = cv2.minAreaRect(coords)[-1]
            #     if angle < -45:
            #         angle = -(90 + angle)
            #     else:
            #         angle = -angle
            #     (h, w) = image.shape[:2]
            #     center = (w // 2, h // 2)
            #     M = cv2.getRotationMatrix2D(center, angle, 1.0)
            #     return cv2.warpAffine(image, M, (w, h), flags=cv2.INTER_CUBIC, borderMode=cv2.BORDER_REPLICATE)
            #
            # # def remove_noise_and_smooth(file_name):
            # #     img = cv2.imread(file_name, 0)
            # #     filtered = cv2.adaptiveThreshold(img.astype(np.uint8), 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 9, 41)
            # #     kernel = np.ones((1, 1), np.uint8)
            # #     opening = cv2.morphologyEx(filtered, cv2.MORPH_OPEN, kernel)
            # #     closing = cv2.morphologyEx(opening, cv2.MORPH_CLOSE, kernel)
            # #     img = image_smoothening(img)
            # #     or_image = cv2.bitwise_or(img, closing)
            # #     return or_image
            #
            # # image = deskew(image)
            # # image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

            h1, w1 = image_helper.image_h_w(image)
            while w1 < 400:
                image = cv2.pyrUp(image)
                h1, w1 = image_helper.image_h_w(image)
            # cv2.imshow("lpr", image)
            # cv2.waitKey(500)

            success, encoded_image = cv2.imencode('.jpg', image)
            content2 = encoded_image.tobytes()
            results = self._alpr.recognize_array(content2)

            added = False
            #print("LPR: ", item.get(constants.RESULT_KEY_RECT))
            for plate in results['results']:
                txt = plate["plate"]
                if len(txt) > 2:
                    score = plate["confidence"] / 100.0
                    if score > 0.01:
                        city_code = txt[0:2]
                        city_name = None
                        if city_code in self._cities:
                            city_name = self._cities[city_code]
                        if city_name is None:
                            class_name = "PL: {}".format(txt)
                        else:
                            class_name = "PL: {} {}".format(city_name, txt)

                        val = {
                            constants.RESULT_KEY_RECT: rect,
                            constants.RESULT_KEY_SCORE: score,
                            constants.RESULT_KEY_CLASS_NAME: class_name
                        }

                        if self._send_data:
                            if city_name is None:
                                val[constants.RESULT_KEY_DATA] = {"pl": txt}
                            else:
                                val[constants.RESULT_KEY_DATA] = {
                                    "pl": txt,
                                    "city": city_name
                                }

                        res.append(val)
                        added = True
            if not added:
                val = {
                    constants.RESULT_KEY_RECT: rect,
                    constants.RESULT_KEY_SCORE: 0,
                    constants.RESULT_KEY_CLASS_NAME: "PL: "
                }
                res.append(val)
        return res