I trained a model with Detectron2 to detect windows on an image of building.
As output I also get bounding boxes around each window with x,y-coordinates of top-right and bottom-left corner.
I want to derive info about the number of floors from this output.
The idea is to get centroids of each bbox and to draw a line connecting centroids on one line. The number of lines means then the number of floors. See the desirable output:
I obtained x,y-coordinates of each centroid, but can't get how to draw lines. Please, any ideas?
#for snapshot-10.png choose only bboxes for class 0 (fenster)
bbox = output['instances'][output['instances'].pred_classes==0].pred_boxes
box_cent = bbox.get_centers()
box_cent = box_cent.cpu().numpy()
#sort centroids by y-coordinates
box_cent[box_cent[:,1].argsort()]
The sorted by y-coordinates output is:
[[540.9429, 233.10698],
[406.09546, 236.09201],
[769.1001, 236.3072],
[655.85944, 236.33795],
[883.7689, 241.99356],
[998.5099, 244.86237],
[532.45764, 381.28082],
[653.0167, 386.0125],
[891.9795, 387.96347],
[1140.524, 388.55304],
[1008.31445, 390.77576],
[771.84033, 390.8385],
[390.84647, 394.80884],
[522.44476, 559.79565],
[899.99866, 560.30835],
[1022.31305, 562.9693],
[650.5117, 563.4512],
[772.411, 565.10144],
[1162.2795, 565.864],
[1269.4834, 566.28735],
[373.81348, 575.3587],
[907.84314, 768.63293],
[509.22638, 770.1798],
[643.81964, 770.6924],
[775.07874, 771.9369],
[234.46616, 775.37305],
[117.903625, 776.7884],
[350.1, 776.8995]]
UPD: I tried a simple solution which clusters y-coordinates of centroids, but there is a specific threshold here. And I would like to find an universal algorithm that counts the number of floors regardless of the height of the windows or the distance between them. Here's my try:
y_cent = []
for b in box_cent:
(x, y) = (int(b[0]), int(b[1]))
y_cent.append(y)
#group values of centroid y-coordinates
def cluster(array, maxdiff):
tmp = array.copy()
groups = []
while len(tmp):
# select seed
seed = tmp.min()
mask = (tmp - seed) <= maxdiff
groups.append(tmp[mask, None])
tmp = tmp[~mask]
return groups