示例#1
0
def extend_horizontal_lines(lines):
    vertical_lines = []
    horizontal_lines = []
    for line in lines:
        if lineprop.slope(line) > 100:
            vertical_lines.append(line)
        elif lineprop.slope(line) == 0:
            horizontal_lines.append(line)

    # Add logic to don't extend if already a vertical line present in X axis

    horizontal_df = pd.DataFrame(horizontal_lines,
                                 columns=['x1', 'y1', 'x2', 'y2'])
    vertical_df = pd.DataFrame(vertical_lines,
                               columns=['x1', 'y1', 'x2', 'y2'])

    horizontal_df['max_x'] = horizontal_df[['x1', 'x2']].max(axis=1)
    horizontal_df['min_x'] = horizontal_df[['x1', 'x2']].min(axis=1)
    horizontal_df['max_y'] = horizontal_df[['y1', 'y2']].max(axis=1)
    horizontal_df['min_y'] = horizontal_df[['y1', 'y2']].min(axis=1)

    vertical_df['max_x'] = vertical_df[['x1', 'x2']].max(axis=1)
    vertical_df['min_x'] = vertical_df[['x1', 'x2']].min(axis=1)
    vertical_df['max_y'] = vertical_df[['y1', 'y2']].max(axis=1)
    vertical_df['min_y'] = vertical_df[['y1', 'y2']].min(axis=1)

    x1coord = horizontal_df.columns.get_loc('x1')
    x2coord = horizontal_df.columns.get_loc('x2')
    for index, row in horizontal_df.iterrows():
        # extend left
        # if horizontal Y line falls in between Ymin and Ymax
        # Or, If it lies in some distance
        # And, It is left to it
        # And, left
        temp = vertical_df[(((vertical_df.max_y >= row.min_y) &
                             (vertical_df.min_y <= row.min_y)) |
                            (abs(vertical_df.min_y - row.min_y) < 30) |
                            (abs(vertical_df.max_y - row.max_y) < 30)) &
                           (vertical_df.max_x < row.min_x) &
                           (abs(row.min_x - vertical_df.max_x) < 100)]  #
        if len(temp) > 0:
            # horizontal_df.iloc[index,x2coord] = horizontal_df.iloc[index].max_x
            horizontal_df.iloc[index, x1coord] = temp.min_x.max()
        # extend right

        temp = vertical_df[(((vertical_df.max_y >= row.min_y) &
                             (vertical_df.min_y <= row.min_y)) |
                            (abs(vertical_df.min_y - row.min_y) < 30) |
                            (abs(vertical_df.max_y - row.max_y) < 30)) &
                           (vertical_df.min_x > row.max_x) &
                           (abs(vertical_df.min_x - row.max_x) < 100)]  #

        if len(temp) > 0:
            # horizontal_df.iloc[index,x1coord] = horizontal_df.iloc[index].min_x
            horizontal_df.iloc[index, x2coord] = temp.max_x.min()

    complete_list = pd.concat([horizontal_df, vertical_df], ignore_index=True)
    complete_list = complete_list[['x1', 'y1', 'x2', 'y2']]
    lines = complete_list.values.tolist()
    return lines
示例#2
0
def join_partial_lines(points, lines):
    x1, y1, x2, y2 = 0, 1, 2, 3

    points = sorted(points, key=itemgetter(1, 0))

    horizontal_lines = []
    vertical_lines = []
    for line in lines:
        if lineprop.slope(line) < 1:
            horizontal_lines.append(line)
        else:
            vertical_lines.append(line)

    new_lines = []
    # join horizontal lines
    previous_point = None
    for point in points:
        if previous_point is not None:
            for line in horizontal_lines:
                if abs(point[y1] - previous_point[y1]) < 10 and line[x1] >= previous_point[x1] and line[x2] <= \
                        point[
                            x1] and (abs(line[y1] - previous_point[y1]) < 10 or abs(line[y2] - point[y1]) < 10):
                    new_lines.append([
                        int(previous_point[x1]),
                        int(previous_point[y1]),
                        int(point[x1]),
                        int(point[y1])
                    ])
                else:
                    pass
        previous_point = point
    lines = lines + new_lines
    return lines
示例#3
0
def remove_short_horizontal_lines(lines, length):
    # remove lines which has some min length and gradient of less than 1(45 degrees)
    # so that we dont remove short vertical lines
    # slope(line)<1 and
    long_lines = []
    for line in lines:
        if lineprop.line_length(line) < length and lineprop.slope(line) < 1:
            pass
        else:
            long_lines.append(line)
    return long_lines
示例#4
0
def join_vertical_lines(lines):
    import copy
    x1, y1, x2, y2 = 0, 1, 2, 3
    lines = arrange_lines(lines, 0, 1)

    joined_lines = []
    vertical_lines = []
    for line in lines:
        if lineprop.slope(line) > 100:
            vertical_lines.append(line)
        else:
            joined_lines.append(line)

    previous_line = None
    for line in vertical_lines:

        if previous_line is not None and (abs(
                max(previous_line[y1], previous_line[y2]) -
                min(line[y1], line[y2])) < Y_DEVIATION_VERTCAL_DISTANCE):
            new_line = copy.deepcopy(line)

            new_line[x1] = min(previous_line[x1], previous_line[x2], line[x1],
                               line[x2])
            new_line[y1] = min(previous_line[y1], previous_line[y2], line[y1],
                               line[y2])
            new_line[x2] = max(previous_line[x1], previous_line[x2], line[x1],
                               line[x2])
            new_line[y2] = max(previous_line[y1], previous_line[y2], line[y1],
                               line[y2])

            if lineprop.slope(new_line) > 100:
                line = copy.deepcopy(new_line)
            else:
                joined_lines.append(previous_line)
        elif previous_line is not None:
            joined_lines.append(previous_line)

        previous_line = copy.deepcopy(line)

    joined_lines.append(previous_line)
    return joined_lines
示例#5
0
def join_horizontal_lines(lines):
    x1, y1, x2, y2 = 0, 1, 2, 3
    lines = arrange_lines(lines, 1, 0)
    joined_lines = []
    previous_line = ''

    horizontal_lines = []
    for line in lines:
        if lineprop.slope(line) < 1:
            horizontal_lines.append(line)
        else:
            joined_lines.append(line)

    for line in horizontal_lines:
        if type(previous_line) is not str \
                and line[x1] - previous_line[x2] < X_DEVIATION \
                and line[y1] - previous_line[y1] < Y_DEVIATION \
                and (line[y2] - line[y1]) == (previous_line[y2] - previous_line[y1]):
            line[x1] = previous_line[x1]
            line[y1] = previous_line[y1]
        else:
            if type(previous_line) is not str and abs(
                    previous_line[y2] - previous_line[y1]) < Y_DEVIATION:
                joined_lines.append(previous_line)
            elif type(previous_line
                      ) is not str and lineprop.slope(previous_line) > 1:
                joined_lines.append(previous_line)
        previous_line = copy.deepcopy(line)

    # final line join
    if abs(previous_line[y2] - previous_line[y1]) < Y_DEVIATION:
        joined_lines.append(previous_line)

    elif lineprop.slope(previous_line) > 1:
        joined_lines.append(previous_line)

    joined_lines = arrange_lines(joined_lines, 1, 0)

    return joined_lines
示例#6
0
def _merge_nearby_horizontal_lines(lines):
    Y_LAG = 15
    vertical_lines = []
    horizontal_lines = []
    for line in lines:
        if lineprop.slope(line) == float('inf'):
            vertical_lines.append(line)
        else:
            horizontal_lines.append(line)

    horizontal_df = pd.DataFrame(horizontal_lines,
                                 columns=['x1', 'y1', 'x2', 'y2'])
    vertical_df = pd.DataFrame(vertical_lines,
                               columns=['x1', 'y1', 'x2', 'y2'])

    horizontal_df['xdiff'] = abs(horizontal_df['x1'] - horizontal_df['x2'])
    horizontal_df['ydiff'] = abs(horizontal_df['y1'] - horizontal_df['y2'])

    vertical_df['xdiff'] = abs(horizontal_df['x1'] - horizontal_df['x2'])
    vertical_df['ydiff'] = abs(horizontal_df['y1'] - horizontal_df['y2'])

    horizontal_df['ignore'] = 0
    vertical_df['ignore'] = 0

    horizontal_df['lag1'] = horizontal_df['y1'] - horizontal_df['y1'].shift(1)
    horizontal_df = horizontal_df.fillna(0.0)
    i = 1
    yccord = horizontal_df.columns.get_loc('lag1')
    for index, row in horizontal_df.iterrows():
        if row['lag1'] < Y_LAG:
            horizontal_df.iloc[index, yccord] = str(i) + 'a'
        else:
            i += 1  # save this i for further processing

    for j in range(i):

        temp1 = horizontal_df[horizontal_df['lag1'] == str(j + 1) + 'a']
        if temp1.empty:
            continue
        if j > 0:
            temp1 = pd.concat([
                pd.DataFrame(horizontal_df.iloc[temp1.index[0] -
                                                1]).transpose(), temp1
            ])
            for i in temp1.index:
                horizontal_df.iloc[i,
                                   horizontal_df.columns.get_loc('ignore')] = 1
            yvalue = temp1[temp1['xdiff'] == temp1.xdiff.max()].y1
            yvalue = yvalue.iloc(yvalue.index)[0]
            df = pd.DataFrame([[
                temp1.x1.min(), yvalue,
                temp1.x2.max(), yvalue,
                abs(temp1.x1.min() - temp1.x2.max()), 0, 0, 0
            ]],
                              columns=horizontal_df.columns,
                              index=[len(horizontal_df)])
            horizontal_df = pd.concat([horizontal_df, df])
        else:
            for i in temp1.index:
                horizontal_df.iloc[i,
                                   horizontal_df.columns.get_loc('ignore')] = 1
            yvalue = temp1[temp1['xdiff'] == temp1.xdiff.max()].y1
            yvalue = yvalue.iloc(yvalue.index)[0]
            df = pd.DataFrame([[
                temp1.x1.min(), yvalue,
                temp1.x2.max(), yvalue,
                abs(temp1.x1.min() - temp1.x2.max()), 0, 0, 0
            ]],
                              columns=horizontal_df.columns,
                              index=[len(horizontal_df)])
            horizontal_df = pd.concat([horizontal_df, df])

    complete_list = pd.concat([horizontal_df, vertical_df], ignore_index=True)
    complete_list = complete_list[complete_list['ignore'] == 0]
    complete_list = complete_list[['x1', 'y1', 'x2', 'y2']]
    lines = complete_list.values.tolist()
    return lines
示例#7
0
def find_points_of_intersection_and_extend_lines(lines):
    points = []
    x1, y1, x2, y2 = 0, 1, 2, 3
    intersection_lines = []
    for line1 in lines:
        line1_copy = line1.copy()
        for line2 in lines:
            line2_copy = line2.copy()
            if line1 != line2 and abs(
                    lineprop.slope(line1) - lineprop.slope(line2)) > 1:
                A = [line1[x1], line1[y1]]
                B = [line1[x2], line1[y2]]
                C = [line2[x1], line2[y1]]
                D = [line2[x2], line2[y2]]

                try:
                    X, Y = lineprop.line_intersection((A, B), (C, D))
                except:
                    continue
                X = int(X)
                Y = int(Y)
                if X < X_MAX and Y < Y_MAX and X > 0 and Y > 0:
                    # find slope of both lines
                    slope_line1 = lineprop.slope(line1)
                    slope_line2 = lineprop.slope(line2)

                    if slope_line1 < 1 and slope_line2 > 1:  # line1 is horizontal and line2 is vertical
                        if X <= min(line1[x1], line1[x2]) and Y <= min(
                                line2[y1], line2[y2]):

                            # condition: line1 is right, line2 is below
                            if abs(X - min(line1[x1], line1[x2])
                                   ) < LINE_POINT_X_DISTANCE and abs(
                                       Y - min(line2[y1], line2[y2])
                                   ) < LINE_POINT_Y_DISTANCE:
                                points.append((X, Y))
                                if line1[x1] > X:
                                    line1_copy[x1] = X
                                if line2[y1] > Y:
                                    line2_copy[y1] = Y
                                intersection_lines.append(line1_copy)
                                intersection_lines.append(line2_copy)

                        # condition: line1 is left, line2 is  below
                        elif X >= max(line1[x1], line1[x2]) and Y <= min(
                                line2[y1], line2[y2]):
                            if ((abs(X - max(line1[x1], line1[x2])) <
                                 LINE_POINT_X_DISTANCE
                                 and abs(Y - min(line2[y1], line2[y2])) <
                                 LINE_POINT_Y_DISTANCE)):
                                points.append((X, Y))
                                if line1[x2] < X:
                                    line1_copy[x2] = X
                                if line2[y1] > Y:
                                    line2_copy[y1] = Y
                                intersection_lines.append(line1_copy)
                                intersection_lines.append(line2_copy)

                        # condition: line1 is left, line2 is above
                        elif X >= max(line1[x1], line1[x2]) and Y >= max(
                                line2[y1], line2[y2]):
                            if ((abs(X - max(line1[x1], line1[x2])) <
                                 LINE_POINT_X_DISTANCE
                                 and abs(Y - max(line2[y1], line2[y2])) <
                                 LINE_POINT_Y_DISTANCE)):
                                points.append((X, Y))
                                if line1[x2] < X:
                                    line1_copy[x2] = X
                                if line2[y2] < Y:
                                    line2_copy[y2] = Y
                                intersection_lines.append(line1_copy)
                                intersection_lines.append(line2_copy)

                        # condition: line1 is right, line2 is above
                        if X <= min(line1[x1], line1[x2]) and Y >= max(
                                line2[y1], line2[y2]):
                            if ((abs(X - min(line1[x1], line1[x2])) <
                                 LINE_POINT_X_DISTANCE
                                 and abs(Y - max(line2[y1], line2[y2])) <
                                 LINE_POINT_Y_DISTANCE)):
                                points.append((X, Y))
                                if line1[x1] > X:
                                    line1_copy[x1] = X
                                if line2[y2] < Y:
                                    line2_copy[y2] = Y
                                intersection_lines.append(line1_copy)
                                intersection_lines.append(line2_copy)
                    elif slope_line1 > 1 and slope_line2 < 1:  # line1 is vertical and line2 is horizontal
                        # condition: line1 is right, line2 is below
                        if X <= min(line2[x1], line2[x2]) and Y <= min(
                                line1[y1], line1[y2]):
                            if ((abs(X - min(line2[x1], line2[x2])) <
                                 LINE_POINT_X_DISTANCE
                                 and abs(Y - min(line1[y1], line1[y2])) <
                                 LINE_POINT_Y_DISTANCE)):
                                points.append((X, Y))
                                if line2[x1] > X:
                                    line2_copy[x1] = X
                                if line1[y1] > Y:
                                    line1_copy[y1] = Y
                                intersection_lines.append(line1_copy)
                                intersection_lines.append(line2_copy)

                        # condition: line1 is left, line2 is below
                        elif X >= max(line2[x1], line2[x2]) and Y <= min(
                                line1[y1], line1[y2]):
                            if ((abs(X - max(line2[x1], line2[x2])) <
                                 LINE_POINT_X_DISTANCE
                                 and abs(Y - min(line1[y1], line1[y2])) <
                                 LINE_POINT_Y_DISTANCE)):
                                points.append((X, Y))
                                if line2[x2] < X:
                                    line2_copy[x2] = X
                                if line1[y1] > Y:
                                    line1_copy[y1] = Y
                                intersection_lines.append(line1_copy)
                                intersection_lines.append(line2_copy)

                        # condition: line1 is left, line2 is above
                        elif X >= max(line2[x1], line2[x2]) and Y >= max(
                                line1[y1], line1[y2]):
                            if ((abs(X - max(line2[x1], line2[x2])) <
                                 LINE_POINT_X_DISTANCE
                                 and abs(Y - max(line1[y1], line1[y2])) <
                                 LINE_POINT_Y_DISTANCE)):
                                points.append((X, Y))
                                if line2[x2] < X:
                                    line2_copy[x2] = X
                                if line1[y2] < Y:
                                    line1_copy[y2] = Y
                                intersection_lines.append(line1_copy)
                                intersection_lines.append(line2_copy)

                        # condition: line1 is right, line2 is above
                        if X <= min(line2[x1], line2[x2]) and Y >= max(
                                line1[y1], line1[y2]):
                            if ((abs(X - min(line2[x1], line2[x2])) <
                                 LINE_POINT_X_DISTANCE
                                 and abs(Y - max(line1[y1], line1[y2])) <
                                 LINE_POINT_Y_DISTANCE)):
                                points.append((X, Y))
                                if line2[x1] > X:
                                    line2_copy[x1] = X
                                if line1[y2] < Y:
                                    line1_copy[y2] = Y
                                intersection_lines.append(line1_copy)
                                intersection_lines.append(line2_copy)

                    # find is lines passes through these points
                    if slope_line1 < 1 and slope_line2 > 1:  # line1 is horizontal and line2 is vertical
                        if (X <= max(line1[x1], line1[x2])
                                and X >= min(line1[x1], line1[x2])
                            ):  # line1 passes through this point
                            if Y <= max(line2[y1], line2[y2]) and Y >= min(
                                    line2[y1], line2[y2]
                            ):  # line2 also passes through this point
                                points.append((X, Y))
                                intersection_lines.append(line1_copy)
                                intersection_lines.append(line2_copy)

                            elif abs(
                                    Y - line2[y1]
                            ) < LINE_POINT_Y_DISTANCE or abs(
                                    Y - line2[y2]
                            ) < LINE_POINT_Y_DISTANCE:  # Y lies in some distance
                                points.append((X, Y))
                                if line2[y1] > Y:
                                    line2_copy[y1] = Y
                                elif line2[y2] < Y:
                                    line2_copy[y2] = Y
                                intersection_lines.append(line1_copy)
                                intersection_lines.append(line2_copy)

                        elif (Y <= max(line2[y1], line2[y2])
                              and Y >= min(line2[y1], line2[y2])
                              ):  # line2 passes through this point
                            if (X <= max(line1[x1], line1[x2])
                                    and X >= min(line1[x1], line1[x2])
                                ):  # line1 also passes through this point
                                points.append((X, Y))
                                intersection_lines.append(line1_copy)
                                intersection_lines.append(line2_copy)

                            elif abs(
                                    X - line1[x1]
                            ) < LINE_POINT_X_DISTANCE or abs(
                                    X - line1[x2]
                            ) < LINE_POINT_X_DISTANCE:  # X lies in some distance
                                points.append((X, Y))
                                if line1[x2] < X:
                                    line1_copy[x2] = X
                                elif line1[x1] > X:
                                    line1_copy[x1] = X
                                intersection_lines.append(line1_copy)
                                intersection_lines.append(line2_copy)

    points = list(set(points))
    unique_data = [list(y) for y in set(tuple(x) for x in intersection_lines)]
    return points, unique_data