如何确保指定边界框内生成的随机8x8边界框互不重叠?
如何确保指定边界框内生成的随机8x8边界框互不重叠?
嘿,这个问题其实挺常见的,咱们一步步来解决它~
首先,你原来的代码已经能保证生成的小框都在大边界框里,但缺了检查小框之间是否重叠的核心步骤。下面给你几种不同的解决方案,按需选择就行:
方法一:直接检查与已有框的重叠(简单直观)
这是最容易理解的方式,每次生成新的8x8框后,不仅要确认它在大框内,还要遍历已经生成的所有框,确保新框和它们都不重叠。
修改后的代码如下:
import random from shapely.geometry import Polygon import shapely.geometry # 初始化大边界框 bbox = (233.9259, 16.3902, 356.8651, 426.9131) polygon = shapely.geometry.box(*bbox, ccw=True) min_x, min_y, max_x, max_y = polygon.bounds width = 8 height = 8 num_polygons = 10 random_poly = [] while len(random_poly) < num_polygons: # 优化随机范围,避免生成超出大框的无效框 rand_x = random.uniform(min_x, max_x - width) rand_y = random.uniform(min_y + height, max_y) # 构造新的8x8多边形 new_poly = Polygon([ (rand_x, rand_y), (rand_x, rand_y - height), (rand_x + width, rand_y - height), (rand_x + width, rand_y) ]) # 先检查是否在大框内(其实上面的随机范围已经保证了,留着更保险) if polygon.contains(new_poly): # 检查是否与已有框重叠 is_overlapping = False for existing in random_poly: if new_poly.intersects(existing): is_overlapping = True break if not is_overlapping: random_poly.append(new_poly)
这里用了shapely的intersects方法,只要两个框有重叠或者边缘接触,都会返回True,所以我们要确保新框和所有已有框都不满足这个条件。
方法二:用空间索引优化(适合大量生成)
如果需要生成的框数量很多(比如几百个),方法一的遍历检查效率会越来越低。这时候可以用shapely的STRtree空间索引,快速查询新框是否和已有框重叠,大大提升速度。
代码示例:
import random from shapely.geometry import Polygon import shapely.geometry from shapely.strtree import STRtree # 初始化大边界框 bbox = (233.9259, 16.3902, 356.8651, 426.9131) polygon = shapely.geometry.box(*bbox, ccw=True) min_x, min_y, max_x, max_y = polygon.bounds width = 8 height = 8 num_polygons = 10 random_poly = [] # 初始化空间索引 tree = STRtree([]) while len(random_poly) < num_polygons: rand_x = random.uniform(min_x, max_x - width) rand_y = random.uniform(min_y + height, max_y) new_poly = Polygon([ (rand_x, rand_y), (rand_x, rand_y - height), (rand_x + width, rand_y - height), (rand_x + width, rand_y) ]) if polygon.contains(new_poly): # 用空间索引快速查询重叠框 overlapping_boxes = tree.query(new_poly) if not overlapping_boxes: random_poly.append(new_poly) # 更新空间索引 tree = STRtree(random_poly)
方法三:网格划分法(零重叠,高效省心)
如果你能接受生成的8x8框是对齐网格的(不是完全随机的自由位置),那可以直接把大框划分成8x8的网格,然后随机挑选不同的网格位置,这样天然不会重叠,效率最高。
代码示例:
import random from shapely.geometry import Polygon import shapely.geometry # 初始化大边界框 bbox = (233.9259, 16.3902, 356.8651, 426.9131) polygon = shapely.geometry.box(*bbox, ccw=True) min_x, min_y, max_x, max_y = polygon.bounds width = 8 height = 8 num_polygons = 10 # 计算大框内可容纳的8x8网格数量 cols = int((max_x - min_x) // width) rows = int((max_y - min_y) // height) # 生成所有网格的左上角坐标(根据你的y轴方向调整) grid_positions = [] for col in range(cols): for row in range(rows): x = min_x + col * width y = max_y - (row + 1) * height grid_positions.append((x, y)) # 随机挑选10个不同的网格位置 selected = random.sample(grid_positions, num_polygons) # 构造对应的多边形 random_poly = [] for x, y in selected: new_poly = Polygon([ (x, y + height), (x, y), (x + width, y), (x + width, y + height) ]) random_poly.append(new_poly)
总结一下:
- 想要完全自由的随机位置,选方法一或方法二(大量生成选方法二)
- 可以接受网格对齐的话,方法三是最省心高效的选择
备注:内容来源于stack exchange,提问作者S.EB
相关产品推荐
相关产品推荐

