Exemple #1
0
def shift_touching_upper_points(ground_truth):
    # Enforce a height of 2 to the ground truth lower polygon

    for index, step in enumerate(ground_truth):
        upper_as_point = Point(step[0][0].item(), step[0][1].item())
        base_as_point = Point(step[1][0].item(), step[1][1].item())
        lower_as_point = Point(step[2][0].item(), step[2][1].item())
        step_angle = angle_between_points(base_as_point, upper_as_point)
        lower_height = base_as_point.distance(lower_as_point)

        if lower_height < 2:
            lower_as_point = get_new_point(base_as_point, step_angle - 180, 2)

        # if index == 0:
        # If sol, push it backwards
        # angle_to_next = angle_between_points(base_as_point, Point(ground_truth[index + 1][1][0].item(),
        # ground_truth[index + 1][1][1].item()))
        # base_as_point = get_new_point(base_as_point, angle_to_next + 180, 2)
        # lower_as_point = get_new_point(lower_as_point, angle_to_next + 180, 2)

        # ground_truth[index][1][0] = torch.tensor(base_as_point.x).cuda()
        # ground_truth[index][1][1] = torch.tensor(base_as_point.y).cuda()
        ground_truth[index][2][0] = torch.tensor(lower_as_point.x).cuda()
        ground_truth[index][2][1] = torch.tensor(lower_as_point.y).cuda()

    return ground_truth
Exemple #2
0
    def intersections(self):

        # For each segment of the baseline, get its intersections
        # and pass the rest to the next segment
        segments_intersections = []
        rest = 0
        relevant_segments = list(
            filter(lambda x: x.segment.intersects(self.line.polygon.get()),
                   self.segments))

        # Trim leading segments
        while len(relevant_segments
                  ) > 0 and relevant_segments[0].get_first_section() is None:
            relevant_segments = relevant_segments[1:]

        for i in range(0, len(relevant_segments)):
            segment = relevant_segments[i]
            try:
                this_segment_intersections, rest = segment.intersections(
                    offset=rest, start_of_line=(i == 0))
                segments_intersections += this_segment_intersections
            except NoStartOfLine as e:
                print("[Segment #" + str(i) +
                      "] [Does not have a start of line]")

        relevant_segments.reverse()

        for i, segment in enumerate(relevant_segments):
            last_section = segment.get_last_section()
            if last_section is not None:
                segments_intersections = list(
                    filter(
                        lambda x: x.segment != segment or x.distance <
                        last_section.distance, segments_intersections))
                # segments_intersections.append(last_section)
                break

        segment_count = len(segments_intersections)

        if segment_count >= 1:
            last_section = segments_intersections[-1]
            reference = last_section
            last_angle = (90.0 +
                          angle_between_points(reference.p1, reference.p2))
            distance_multipler = 2 / 3
            p1 = get_new_point(reference.p1, last_angle,
                               distance_multipler * reference.height())
            p2 = get_new_point(reference.p2, last_angle,
                               distance_multipler * reference.height())
            new_section = VirtualSegmentSection(p1, p2, reference.confidence)
            segments_intersections.append(new_section)
            segments_intersections[-1].confidence = 0.0

        return segments_intersections
Exemple #3
0
 def draw_reach(self, b, target_point, range=(0, 360),
                color=(1, 1, 0, 0.5)):
     base_point = midpoint(b, target_point)
     angle = angle_between_points(base_point, target_point)
     self.context.move_to(base_point.x, base_point.y)
     self.context.arc(base_point.x, base_point.y,
                      base_point.distance(target_point),
                      math.radians(angle + range[0]),
                      math.radians(angle + range[1]))
     self.context.close_path()
     self.context.set_source_rgba(*color)
     self.context.fill()
Exemple #4
0
 def __init__(self, baseline, p1, p2, height_threshold):
     self.height_threshold = height_threshold
     self.baseline = baseline
     self.start = p1
     self.start_point = Point(*p1)
     self.end = p2
     self.end_point = Point(*p2)
     self.length = Point(*self.start).distance(Point(*self.end))
     self.segment = LineString([p1, p2])
     self.slope = (self.end[1] - self.start[1]) / (self.end[0] -
                                                   self.start[0])
     self.bearing = angle_between_points(Point(*p1), Point(*p2))
     self.vertical_sections = []
Exemple #5
0
    def upper_concat(self, img):

        upper_image = None

        steps = self.valid_steps(img)
        box_height = max([step.calculate_upper_height() for step in steps])

        for step in steps:
            if step.calculate_upper_height() < 16:
                step.upper_point = get_new_point(step.base_point,
                                                 step.angle - 90, 16)

        for step_index, step in enumerate(steps[:-1]):
            next_step = steps[step_index + 1]
            angle = angle_between_points(step.base_point, next_step.base_point)

            width = step.base_point.distance(next_step.base_point)

            left_upper_height = step.calculate_upper_height()
            right_upper_height = next_step.calculate_upper_height()

            # Trapezoids
            upper_src = np.array(
                [[step.upper_point.x, step.upper_point.y],
                 [next_step.upper_point.x, next_step.upper_point.y],
                 [next_step.base_point.x, next_step.base_point.y],
                 [step.base_point.x, step.base_point.y]])
            # Destination rectangles
            upper_dst = np.array([[0, box_height - left_upper_height],
                                  [width, box_height - right_upper_height],
                                  [width, box_height], [0.0, box_height]])

            # White background
            upper_background = np.ones((int(box_height), int(width), 3),
                                       np.uint8)

            upper_perspective, _ = cv2.findHomography(upper_src, upper_dst)
            upper_out = cv2.warpPerspective(
                img, upper_perspective,
                (upper_background.shape[1], upper_background.shape[0]))
            upper_image = upper_out if upper_image is None else hconcat_resize_min(
                [upper_image, upper_out])

            # cv2.waitKey(0)
            # cv2.destroyAllWindows()

        return upper_image
Exemple #6
0
    def section(self):
        interpolated_baseline = []

        ending_angle = self.steps[0].angle - 90

        for step_index, step in enumerate(self.steps[:-1]):
            next_step = self.steps[step_index + 1]

            this_angle = (step.angle - 90)
            next_angle = (next_step.angle - 90)

            starting_angle = ending_angle
            middle_angle = this_angle
            ending_angle = self.angleLerp(this_angle, next_angle, 0.5)

            # Add first point itself
            # interpolated_baseline.append(step.base_point)

            angle = angle_between_points(step.base_point, next_step.base_point)
            distance = step.base_point.distance(next_step.base_point)
            walked = 0
            step_size = 1
            while walked < distance:
                percent_walked = walked / distance

                if percent_walked < 0.5:
                    intersection_angle = self.angleLerp(
                        starting_angle, middle_angle, percent_walked * 2)
                else:
                    assert 0 <= (percent_walked - 0.5) * 2 <= 1
                    intersection_angle = self.angleLerp(
                        middle_angle, ending_angle, (percent_walked - 0.5) * 2)

                baseline_point = get_new_point(step.base_point, angle, walked)
                upper_point = get_new_point(baseline_point, intersection_angle,
                                            80)
                lower_point = get_new_point(baseline_point,
                                            intersection_angle - 180, 20)

                interpolated_baseline.append(
                    [upper_point, baseline_point, lower_point])
                walked += step_size

        return interpolated_baseline
Exemple #7
0
def to_steps(data, pairs, visualize=True):
    result = {"images": []}

    for i, page_index in enumerate(data):
        pair = pairs[i]

        print("Stepping pair #" + str(pair.index))

        image_data = {"index": pair.index, "filename": pair.img, "lines": []}

        image = cairo.ImageSurface.create_from_png(pair.img)
        context = cairo.Context(image)

        if visualize:
            for component in pair.get_components():
                context.rectangle(
                    component["x"],
                    component["y"],
                    component["width"],
                    component["height"],
                )
                context.set_source_rgba(0, 0, 1, 0.1)
                context.fill()

        for line_index in data[page_index]:

            line = data[page_index][line_index]
            baseline = line["baseline"]
            hull = line["hull"]
            line_data = {"text": line["text"], "steps": []}

            line_slope = slope(baseline)
            start_point = baseline[0]
            distance_walked = 0
            total_distance = distance(baseline[0], baseline[1])

            height_threshold = 20
            context.set_operator(cairo.OPERATOR_MULTIPLY)
            context.set_line_width(5)
            upper_points = []
            lower_points = []
            baseline_points = []

            while distance_walked < total_distance:
                intersecting_line = perpendicular(start_point, baseline)
                intersection = intersecting_line.intersection(hull)

                upper_point = None
                lower_point = None

                if isinstance(intersection, MultiPoint) and len(
                        intersection.bounds) == 4:
                    upper_point = [
                        intersection.bounds[0], intersection.bounds[1]
                    ]
                    lower_point = [
                        intersection.bounds[2], intersection.bounds[3]
                    ]
                elif isinstance(intersection, LineString) and len(
                        intersection.bounds) == 4:
                    upper_point = [
                        intersection.bounds[0], intersection.bounds[1]
                    ]
                    lower_point = [
                        intersection.bounds[2], intersection.bounds[3]
                    ]
                elif isinstance(intersection, Point):
                    print("Intersection was point, moving forward")
                    start_point = walk(start_point, line_slope, 4)
                    continue
                else:
                    if distance_walked == 0:
                        start_point = walk(start_point, line_slope, 4)
                    else:
                        print("No intersection, skipping line " +
                              str(line_index) + " of " + str(pair.index) +
                              " after walking" + str(distance_walked))
                        distance_walked = total_distance
                    continue

                if upper_point is not None and lower_point is not None:

                    upper_points.append(upper_point)
                    lower_points.append(lower_point)

                    baseline_intersection = LineString(
                        [Point(upper_point[0], upper_point[1]), Point(lower_point[0], lower_point[1])]) \
                        .intersection(LineString(to_points(baseline)))

                    baseline_point = None
                    if isinstance(
                            baseline_intersection,
                            Point) and len(baseline_intersection.bounds) > 1:
                        baseline_point = [
                            baseline_intersection.bounds[0],
                            baseline_intersection.bounds[1]
                        ]
                    else:
                        baseline_point = lower_point
                    baseline_points.append(baseline_point)

                    height = distance(upper_point, baseline_point)

                    if height < height_threshold and distance_walked == 0:
                        # The first point doesnt have a height
                        if distance_walked == 0:
                            angle = angle_between_points(
                                to_points(baseline)[0],
                                to_points(baseline)[1])
                            new_upper_point = get_new_point(
                                to_points(baseline)[0], angle - 90,
                                height_threshold)
                            upper_point = [
                                new_upper_point.x, new_upper_point.y
                            ]

                    if height < height_threshold:
                        height = height_threshold

                    context.set_source_rgba(1, 0, 1, 1)
                    context.move_to(upper_point[0], upper_point[1])
                    context.line_to(lower_point[0], lower_point[1])
                    context.stroke()

                    context.set_source_rgba(0, 0, 1, 0.1)
                    context.move_to(start_point[0], start_point[1])
                    start_point = walk(start_point, line_slope, height)
                    distance_walked += height
                    context.line_to(start_point[0], start_point[1])
                    context.stroke()

                else:
                    distance_walked = total_distance

            for pc in [baseline_points, upper_points, lower_points]:
                if len(pc) == 0:
                    continue
                context.set_source_rgba(1, 0, 1, 0.3)
                context.move_to(pc[0][0], pc[0][1])
                for bp in pc:
                    context.line_to(bp[0], bp[1])
                context.stroke()

            for i in range(len(baseline_points)):
                line_data["steps"].append({
                    "upper_point": upper_points[i],
                    "lower_point": lower_points[i],
                    "base_point": baseline_points[i],
                })

            line_data["index"] = line_index
            image_data["lines"].append(line_data)

        result["images"].append(image_data)
        save_path = os.path.join(pair.base, "json",
                                 str(image_data["index"]) + ".json")
        save_to_json(image_data, save_path)
        if visualize:
            visualization_path = os.path.join(pair.base, "stepped",
                                              str(pair.index) + ".png")
            create_folders(visualization_path)
            image.write_to_png(visualization_path)

    return result
Exemple #8
0
def to_steps(line):
    if line.baseline is None or line.coords is None:
        return None

    full_baseline = line.baseline
    hull = Polygon(line.coords)
    baseline_segment_count = len(full_baseline) - 1
    baseline_lenghts = [
        distance(full_baseline[i], full_baseline[i + 1])
        for i in range(baseline_segment_count)
    ]
    total_distance = sum(baseline_lenghts)
    line_data = {
        "index": line.index,
        "text": line.text,
        "steps": [],
    }

    walked = 0

    def get_point_from_walked(walked):
        acc = 0
        baseline_index = 0
        for index, length in enumerate(baseline_lenghts):
            acc += length
            if walked < acc:
                baseline_index = index
                acc -= length
                break
        baseline = full_baseline[baseline_index:baseline_index + 2]
        return baseline, point_at(baseline, walked - acc)

    while walked < total_distance:
        baseline, point = get_point_from_walked(walked)

        # Intersect hull to get upper and lower
        try:
            intersecting_line = perpendicular(point, baseline)
        except:
            return None

        if not hull.is_simple:
            print("[SELF INTERSECTING HULL]")
            return

        intersection = intersecting_line.intersection(hull)

        base_point = Point(point)
        upper_point = None
        lower_point = None

        if isinstance(intersection, MultiPoint) and len(
                intersection.bounds) == 4:
            upper_point = Point(
                [intersection.bounds[0], intersection.bounds[1]])
            lower_point = Point(
                [intersection.bounds[2], intersection.bounds[3]])
        elif isinstance(intersection, LineString) and len(
                intersection.bounds) == 4:
            upper_point = Point(
                [intersection.bounds[0], intersection.bounds[1]])
            lower_point = Point(
                [intersection.bounds[2], intersection.bounds[3]])
        elif isinstance(intersection, Point):
            print("Intersection was point, moving forward")
            walked += 4
            continue
        else:
            if walked < 40:
                walked += 4
            else:
                print("No intersection found ")
                return None

        if any([p is None for p in [base_point, lower_point, upper_point]]):
            continue

        height = base_point.distance(upper_point)

        height_threshold = 16

        angle = angle_between_points(base_point, upper_point)

        if height < height_threshold:
            # project upper point
            upper_point = get_new_point(base_point, angle, height_threshold)
            height = height_threshold

        # Check for lower point above base point
        lower_angle = angle_between_points(base_point, lower_point)

        if abs(angle - lower_angle) < 90:
            lower_point = base_point

        line_data["steps"].append({
            "upper_point": [upper_point.x, upper_point.y],
            "base_point": [base_point.x, base_point.y],
            "lower_point": [lower_point.x, lower_point.y],
        })
        walked += height

    return line_data