Exemple #1
0
    def parse_txt(gt_path):
        """
        .mat file parser
        :param gt_path: (str), mat file path
        :return: (list), TextInstance
        """
        lines = read_lines(gt_path + ".txt")
        polygons = []
        for line in lines:
            line = strs.remove_all(line.strip('\ufeff'), '\xef\xbb\xbf')
            gt = line.split(',')
            x1, y1, x2, y2, x3, y3, x4, y4 = list(map(int, gt[:8]))
            xx = [x1, x2, x3, x4]
            yy = [y1, y2, y3, y4]

            if gt[-1].strip() == "###":
                label = gt[-1].strip().replace("###", "#")
            else:
                label = "GG"
            pts = np.stack([xx, yy]).T.astype(np.int32)

            d1 = norm2(pts[0] - pts[1])
            d2 = norm2(pts[1] - pts[2])
            d3 = norm2(pts[2] - pts[3])
            d4 = norm2(pts[3] - pts[0])
            if min([d1, d2, d3, d4]) < 2:
                continue
            polygons.append(TextInstance(pts, 'c', label))

        return polygons
    def adjust_contours(self, image, all_contours):
        mask = np.zeros(image.shape[0:2])
        # image_show = image.copy()

        bbox_contours = list()
        for idx, (boundary_point, line) in enumerate(all_contours):
            deal_mask = mask.copy()
            cv2.drawContours(deal_mask, [boundary_point], -1, 1, -1)
            deal_contours, _ = cv2.findContours(deal_mask.astype(np.uint8), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
            new_line = list()
            for ip, _ in enumerate(line):
                if not (self.in_contour(deal_contours[0], line[ip, 0, :])\
                        or self.in_contour(deal_contours[0], line[ip, 1, :])):
                    new_line.append(line[ip])
            try:
                new_line = np.array(new_line)
                vet10 = np.array(new_line[0:-1, 0, :]) - np.array(new_line[1:, 0, :])
                vet20 = np.array(new_line[0:-1, 1, :]) - np.array(new_line[1:, 1, :])
            except:
                continue
            cosin0 = np.sum(vet10 * vet20, axis=1) / (norm2(vet10, axis=1) * norm2(vet20, axis=1))

            vet11 = np.array(new_line[0:-1, 0, :]) - np.array(new_line[0:-1, 1, :])
            vet21 = np.array(new_line[1:, 0, :]) - np.array(new_line[1:, 1, :])
            cosin1 = np.sum(vet11 * vet21, axis=1) / (norm2(vet11, axis=1) * norm2(vet21, axis=1))
            defect_point = (np.where((cosin0 < 0.6) & (cosin1 < 0.6))[0]).tolist()
            defect_size = (np.where((cosin0 < 0.6) & (cosin1 < 1))[0])

            if len(defect_point):
                defect_point = sorted(defect_point)
                dps = list()
                for index in defect_point:
                    iip = defect_size[np.where(np.abs(defect_size - index) <= 5)].tolist()
                    min_iip = min(iip)-1
                    max_iip = max(iip)+1
                    dps += list(range(min_iip, max_iip+1))

                defect_point.insert(0, 0)
                defect_point.append(len(new_line))
                defect_point = sorted(list(set(defect_point)))
                segline = np.stack([defect_point[0:-1], defect_point[1:]], axis=1)
                for seg in segline[1::2]:
                    new_line[seg[0]:seg[1]] = new_line[seg[0]:seg[1], ::-1, :]
                new_line = np.delete(new_line, dps, axis=0)

            if new_line.shape[0] < 4:
                continue
            boundary_point = np.concatenate([new_line[:, 0, :], new_line[::-1, 1, :]], axis=0)
            bbox_contours.append([boundary_point, new_line])

        return bbox_contours
Exemple #3
0
 def find_min_radii(self,pts):
     
     bottom = find_bottom(pts)
     e1, e2 = find_long_edges(pts, bottom)  # find two long edge sequence
     inner_points1 = split_edge_seqence(pts, e1, 16)
     inner_points2 = split_edge_seqence(pts, e2, 16)
     inner_points2 = inner_points2[::-1]
     center_points = (inner_points1 + inner_points2) / 2  # disk center
     radii = norm2(inner_points1 - center_points, axis=1)
     return inner_points1,inner_points2,center_points
Exemple #4
0
    def disk_cover(self, unit_disk):
        n_disk = get_n_parts(self.points, self.bottoms, self.e1, self.e2,
                             unit_disk)
        inner_points1 = split_edge_seqence(self.points, self.e1, n_disk)
        inner_points2 = split_edge_seqence(self.points, self.e2, n_disk)
        inner_points2 = inner_points2[::-1]  # inverse one of long edge

        center_points = (inner_points1 + inner_points2) / 2  # disk center
        radii = norm2(inner_points1 - center_points, axis=1)  # disk radius

        return inner_points1, inner_points2, center_points, radii
Exemple #5
0
    def disk_cover(self, n_disk=15):
        """
        cover text region with several disks
        :param n_disk: number of disks
        :return:
        """
        inner_points1 = split_edge_seqence(self.points, self.e1, n_disk)
        inner_points2 = split_edge_seqence(self.points, self.e2, n_disk)
        inner_points2 = inner_points2[::-1]  # innverse one of long edge

        center_points = (inner_points1 + inner_points2) / 2  # disk center
        radii = norm2(inner_points1 - center_points, axis=1)  # disk radius

        return inner_points1, inner_points2, center_points, radii
Exemple #6
0
def graph_propagation_naive(edges,
                            score,
                            th,
                            bboxs=None,
                            dis_thresh=50,
                            pool='avg'):

    edges = np.sort(edges, axis=1)

    score_dict = {}  # score lookup table
    if pool is None:
        for i, e in enumerate(edges):
            score_dict[e[0], e[1]] = score[i]
    elif pool == 'avg':
        for i, e in enumerate(edges):
            if bboxs is not None:
                box1 = bboxs[e[0]][:8].reshape(4, 2)
                box2 = bboxs[e[1]][:8].reshape(4, 2)
                c1 = np.mean(box1, 0)
                c2 = np.mean(box2, 0)
                dst = norm2(c1 - c2)
                if dst > dis_thresh:
                    score[i] = 0
            if (e[0], e[1]) in score_dict:
                score_dict[e[0],
                           e[1]] = 0.5 * (score_dict[e[0], e[1]] + score[i])
            else:
                score_dict[e[0], e[1]] = score[i]

    elif pool == 'max':
        for i, e in enumerate(edges):
            if (e[0], e[1]) in score_dict:
                score_dict[e[0], e[1]] = max(score_dict[e[0], e[1]], score[i])
            else:
                score_dict[e[0], e[1]] = score[i]
    else:
        raise ValueError('Pooling operation not supported')

    nodes = np.sort(np.unique(edges.flatten()))
    mapping = -1 * np.ones((nodes.max() + 1), dtype=np.int)
    mapping[nodes] = np.arange(nodes.shape[0])
    link_idx = mapping[edges]
    vertex = [Data(n) for n in nodes]
    for l, s in zip(link_idx, score):
        vertex[l[0]].add_link(vertex[l[1]], s)

    # first iteration
    comps = connected_components(vertex, score_dict, th)

    return comps
Exemple #7
0
    def mask_to_tcl(self,
                    pred_sin,
                    pred_cos,
                    pred_radii,
                    tcl_mask,
                    init_xy,
                    direct=1):
        """
        Iteratively find center line in tcl mask using initial point (x, y)
        :param pred_sin: predict sin map
        :param pred_cos: predict cos map
        :param tcl_mask: predict tcl mask
        :param init_xy: initial (x, y)
        :param direct: direction [-1|1]
        :return:
        """

        H, W = pred_sin.shape
        x_init, y_init = init_xy

        sin = pred_sin[int(y_init), int(x_init)]
        cos = pred_cos[int(y_init), int(x_init)]
        radii = pred_radii[int(y_init), int(x_init)]

        x_shift, y_shift = self.centerlize(x_init, y_init, cos, sin, tcl_mask)
        result = []

        while tcl_mask[int(y_shift), int(x_shift)]:

            result.append(np.array([x_shift, y_shift, radii]))
            x, y = x_shift, y_shift

            sin = pred_sin[int(y), int(x)]
            cos = pred_cos[int(y), int(x)]

            x_c, y_c = self.centerlize(x, y, cos, sin, tcl_mask)

            sin_c = pred_sin[int(y_c), int(x_c)]
            cos_c = pred_cos[int(y_c), int(x_c)]
            radii = pred_radii[int(y_c), int(x_c)]

            # shift stride
            for shrink in np.arange(0.5, 0.0,
                                    -0.1):  # [0.5, 0.4, 0.3, 0.2, 0.1]
                t = shrink * radii  # stride = +/- 0.5 * [sin|cos](theta), if new point is outside, shrink it until shrink < 0.1, hit ends
                x_shift_pos = x_c + cos_c * t * direct  # positive direction
                y_shift_pos = y_c + sin_c * t * direct  # positive direction
                x_shift_neg = x_c - cos_c * t * direct  # negative direction
                y_shift_neg = y_c - sin_c * t * direct  # negative direction

                # if first point, select positive direction shift
                if len(result) == 1:
                    x_shift, y_shift = x_shift_pos, y_shift_pos
                else:
                    # else select point further with second last point
                    dist_pos = norm2(result[-2][:2] -
                                     (x_shift_pos, y_shift_pos))
                    dist_neg = norm2(result[-2][:2] -
                                     (x_shift_neg, y_shift_neg))
                    if dist_pos > dist_neg:
                        x_shift, y_shift = x_shift_pos, y_shift_pos
                    else:
                        x_shift, y_shift = x_shift_neg, y_shift_neg
                # if out of bounds, skip
                if int(x_shift) >= W or int(x_shift) < 0 or int(
                        y_shift) >= H or int(y_shift) < 0:
                    continue
                # found an inside point
                if tcl_mask[int(y_shift), int(x_shift)]:
                    break
            # if out of bounds, break
            if int(x_shift) >= W or int(x_shift) < 0 or int(
                    y_shift) >= H or int(y_shift) < 0:
                break
        return result
Exemple #8
0
    def mask_to_tcl(self,
                    pred_sin,
                    pred_cos,
                    pred_radii,
                    tcl_contour,
                    init_xy,
                    direct=1):
        """
        Iteratively find center line in tcl mask using initial point (x, y)
        :param pred_sin: predict sin map
        :param pred_cos: predict cos map
        :param tcl_contour: predict tcl contour
        :param init_xy: initial (x, y)
        :param direct: direction [-1|1]
        :return:
        """

        H, W = pred_sin.shape
        x_shift, y_shift = init_xy

        result = []
        max_attempt = 200
        attempt = 0

        while self.in_contour(tcl_contour, (x_shift, y_shift)):

            attempt += 1

            sin = pred_sin[int(y_shift), int(x_shift)]
            cos = pred_cos[int(y_shift), int(x_shift)]
            x_c, y_c = self.centerlize(x_shift, y_shift, H, W, cos, sin,
                                       tcl_contour)

            sin_c = pred_sin[int(y_c), int(x_c)]
            cos_c = pred_cos[int(y_c), int(x_c)]
            radii_c = pred_radii[int(y_c), int(x_c)]

            result.append(np.array([x_c, y_c, radii_c]))

            # shift stride
            for shrink in [1 / 2., 1 / 4., 1 / 8., 1 / 16., 1 / 32.]:
                t = shrink * radii_c  # stride = +/- 0.5 * [sin|cos](theta), if new point is outside, shrink it until shrink < 1/32., hit ends
                x_shift_pos = x_c + cos_c * t * direct  # positive direction
                y_shift_pos = y_c + sin_c * t * direct  # positive direction
                x_shift_neg = x_c - cos_c * t * direct  # negative direction
                y_shift_neg = y_c - sin_c * t * direct  # negative direction

                # if first point, select positive direction shift
                if len(result) == 1:
                    x_shift, y_shift = x_shift_pos, y_shift_pos
                else:
                    # else select point further with second last point
                    dist_pos = norm2(result[-2][:2] -
                                     (x_shift_pos, y_shift_pos))
                    dist_neg = norm2(result[-2][:2] -
                                     (x_shift_neg, y_shift_neg))
                    if dist_pos > dist_neg:
                        x_shift, y_shift = x_shift_pos, y_shift_pos
                    else:
                        x_shift, y_shift = x_shift_neg, y_shift_neg
                # if out of bounds, skip
                if int(x_shift) >= W or int(x_shift) < 0 or int(
                        y_shift) >= H or int(y_shift) < 0:
                    continue
                # found an inside point
                if self.in_contour(tcl_contour, (x_shift, y_shift)):
                    break
            # if out of bounds, break
            if int(x_shift) >= W or int(x_shift) < 0 or int(
                    y_shift) >= H or int(y_shift) < 0:
                break
            if attempt > max_attempt:
                break
        return np.array(result)