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
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
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
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
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
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
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