EDIT: Collecting both Horizontal and Vertical lines, also I reduced some superfluous comparisons that I used in the first draft: when scanning there is one direction, thus only the right/bottom end coordinates have to be updated, while the left/top are constant, equal to the beginning of the scanning of the current line segment. There is still some superfluous code that can be compressed.
EDIT2: Added the final formatting of the list as in the question.
It finds and lists first the horizontal lines, if the vertical have to come first as in your example output, then just put the second traversal on top.
import numpy as np
gray_img = np.array([[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 255, 255, 255, 255, 255, 255, 255, 0],
[0, 255, 255, 255, 255, 255, 255, 255, 0],
[0, 255, 255, 0, 0, 0, 0, 0, 0],
[0, 255, 255, 0, 0, 0, 0, 0, 0],
[0, 255, 255, 0, 0, 0, 0, 0, 0],
[0, 255, 255, 0, 0, 255, 255, 255, 255],
[0, 255, 255, 0, 0, 255, 255, 255, 255],
[0, 255, 255, 0, 0, 0, 0, 0, 0],
[0, 255, 255, 0, 0, 0, 0, 0, 0],
[0, 255, 255, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0]])
bounds = []
a = gray_img
#SCANNING HORIZONTAL LINES
for y in range(0,a.shape[0]):
print("\nY=",y)
found = False #set to True when scanning a line
left_x, right_x = 0,0
top_y = y; bottom_y = y
if a[y,0]==255:
top_y = min(top_y, y)
bottom_y = max(bottom_y,y)
found = True
for x in range(0,a.shape[1]): #
#while x < len(a[1]) or x!==0 #...
if a[y,x]==255 and not found: #first item
found = True
right_x = x
left_x = x
#right_x = max(right_x, x)
#left_x = x # min(left_x, x)
print("START",top_y, bottom_y, left_x, right_x)
else:
if a[y,x]==255 and found: #running line
right_x = max(right_x, x)
#left_x = min(left_x, x)
#print(top_y, bottom_y, left_x, right_x)
if a[y,x]==0 and found: #end of a running line
bounds.append([top_y, left_x, bottom_y, right_x])
print(a[y,x],end=",")
found = False
if found: #end of a running line matches the end of the dimension/line
bounds.append([top_y, left_x, bottom_y, right_x])
print(a[y,x],end=",")
found = False
print("\n")
print(bounds)
print(a.shape)
#print(f"LEN= {a.shape[0])}, {a.shape[1])}")
#SCANNING VERTICAL LINES
for x in range(0,a.shape[1]):
print("\nY=",y)
found = False #set to True when scanning a line
left_x, right_x = x,x
top_y = 0; bottom_y = 0
if a[0,x]==255:
top_y = min(top_y, y)
bottom_y = max(bottom_y,y)
found = True
for y in range(0,a.shape[0]): #
#while x < len(a[1]) or x!==0 #...
if a[y,x]==255 and not found: #first item
found = True
#right_x = max(right_x, x)
bottom_y = y
top_y = y
left_x = x # min(left_x, x)
print("START",top_y, bottom_y, left_x, right_x)
else:
if a[y,x]==255 and found: #running line
bottom_y = y #max(right_x, x)
#top_y = min(left_x, x)
#print(top_y, bottom_y, left_x, right_x)
if a[y,x]==0 and found: #end of a running line
bounds.append([top_y, left_x, bottom_y, right_x])
print(a[y,x],end=",")
found = False
if found: #end of a running line matches the end of the dimension/line
bounds.append([top_y, left_x, bottom_y, right_x])
print(a[y,x],end=",")
found = False
print("\n")
print(bounds)
print(a.shape)
# [[1, 1, 1, 7], [2, 1, 2, 7], [3, 1, 3, 2], [4, 1, 4, 2], [5, 1, 5, 2], [6, 1, 6, 2], [6, 5, 6, 8], [7, 1, 7, 2], [7, 5, 7, 8], [8, 1, 8, 2], [9, 1, 9, 2], [10, 1, 10, 2], [1, 1, 10, 1], [1, 2, 10, 2], [1, 3, 2, 3], [1, 4, 2, 4], [1, 5, 2, 5], [6, 5, 7, 5], [1, 6, 2, 6], [6, 6, 7, 6], [1, 7, 2, 7], [6, 7, 7, 7], [6, 8, 7, 8]]
#(15, 9)
#This list has to be additionally traversed in order to form [ [[1,1][1,7]], [...]] e.g.:
fm = []
for i in bounds:
#i=[1,1,1,7] etc.
f = [[i[0],i[1]],[i[2],i[3]]]
fm.append(f)
print(fm)
[[[1, 1], [1, 7]], [[2, 1], [2, 7]], [[3, 1], [3, 2]], [[4, 1], [4, 2]], [[5, 1], [5, 2]], [[6, 1], [6, 2]], [[6, 5], [6, 8]], [[7, 1], [7, 2]], [[7, 5], [7, 8]], [[8, 1], [8, 2]], [[9, 1], [9, 2]], [[10, 1], [10, 2]], [[1, 1], [10, 1]], [[1, 2], [10, 2]], [[1, 3], [2, 3]], [[1, 4], [2, 4]], [[1, 5], [2, 5]], [[6, 5], [7, 5]], [[1, 6], [2, 6]], [[6, 6], [7, 6]], [[1, 7], [2, 7]], [[6, 7], [7, 7]], [[6, 8], [7, 8]]]
Then you may traverse the result list and compute that distance (or you mean the lenght of the lines) and transfer only the longer lines to another list.