绘制连接不同级别边界框质心的线
我使用 Detectron2 训练了一个模型来检测建筑物图像上的窗户。 作为输出,我还得到每个窗口周围的边界框,其中包含右上角和左下角的 x、y 坐标。
我想从此输出中获取有关楼层数的信息。 这个想法是获取每个 bbox 的质心并在一条线上画一条连接质心的线。线路的数量意味着楼层的数量。查看所需的输出:
我获得了每个质心的x,y坐标,但不知道如何画线。请问,有什么想法吗?
#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()]
按 y 坐标排序的输出为:
[[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:我尝试了一个简单的解决方案,该解决方案对质心的 y 坐标进行聚类,但这里有一个特定的阈值。我想找到一种通用算法,可以计算楼层数,而不管窗户的高度或窗户之间的距离如何。这是我的尝试:
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
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我尝试了一下,这就是我的想法。它不是世界上最好的算法,但它可以完成工作。但请记住,它仅在照片直立时才有效。
这会计算楼层数。如果您想绘制穿过这些点的线,您可以分别存储每个楼层的窗户:
循环遍历楼层列表中的每个列表,并根据 x 坐标对列表进行排序,并为每个相邻的窗口绘制一条线cv2.line方法。 (https://python.engineering/python-opencv-cv2-line-method/ )
I gave it a try and here is what I came up with. It is not the best algorithm in the word, but it gets the job done. Keep in mind though that it only works when the photo is upright.
This counts the number of floors. If you want to draw lines going through those points you can store the windows of each floor separately:
The loop though every list in the floors list and sort the list with respect to the x-coordinates and for every neighboring window draw a line with the cv2.line method. (https://python.engineering/python-opencv-cv2-line-method/)