diff --git a/odm_preprocess.py b/odm_preprocess.py index 98969b2..07e164c 100644 --- a/odm_preprocess.py +++ b/odm_preprocess.py @@ -208,13 +208,14 @@ class ImagePreprocessor: self.logger.info(f"开始划分网格 (重叠率: {self.config.grid_overlap})") grid_divider = GridDivider( overlap=self.config.grid_overlap, + grid_size=self.config.grid_size, output_dir=self.config.output_dir ) - grids, translations = grid_divider.divide_grids( - self.gps_points, grid_size=self.config.grid_size + grids, translations, grid_points = grid_divider.adjust_grid_size_and_overlap( + self.gps_points ) - grid_points = grid_divider.assign_to_grids(self.gps_points, grids) self.logger.info(f"成功划分为 {len(grid_points)} 个网格") + grid_divider.visualize_grids(self.gps_points, grids) return grid_points, translations @@ -279,8 +280,8 @@ class ImagePreprocessor: if __name__ == "__main__": # 创建配置 config = PreprocessConfig( - image_dir=r"G:\error_data\ODMTestData", - output_dir=r"G:\ODM_output\1w", + image_dir=r"/home/cug/datasets/1815/project/images", + output_dir=r"/home/cug/ODM_output/1815", cluster_eps=0.01, cluster_min_samples=5, @@ -296,7 +297,7 @@ if __name__ == "__main__": filter_dense_distance_threshold=10, filter_time_threshold=timedelta(minutes=5), - grid_size=1000, + grid_size=800, grid_overlap=0.05, diff --git a/utils/grid_divider.py b/utils/grid_divider.py index b7f79f5..b15dbdb 100644 --- a/utils/grid_divider.py +++ b/utils/grid_divider.py @@ -5,17 +5,74 @@ import os class GridDivider: - """划分九宫格,并将图片分配到对应网格""" + """划分网格,并将图片分配到对应网格""" - def __init__(self, overlap=0.1, output_dir=None): + def __init__(self, overlap=0.1, grid_size=500, output_dir=None): self.overlap = overlap + self.grid_size = grid_size self.output_dir = output_dir self.logger = logging.getLogger('UAV_Preprocess.GridDivider') self.logger.info(f"初始化网格划分器,重叠率: {overlap}") self.num_grids_width = 0 # 添加网格数量属性 self.num_grids_height = 0 + + def adjust_grid_size(self, points_df): + """动态调整网格大小 + + Args: + points_df: 包含GPS点的DataFrame + + Returns: + tuple: (grids, translations, grid_points, final_grid_size) + """ + self.logger.info(f"开始动态调整网格大小,初始大小: {self.grid_size}米") + + while True: + # 使用当前grid_size划分网格 + grids, translations = self.divide_grids(points_df) + grid_points, multiple_grid_points = self.assign_to_grids(points_df, grids) + + # 检查每个网格中的点数 + max_points = 0 + for grid_id, points in grid_points.items(): + max_points = max(max_points, len(points)) + + self.logger.info(f"当前网格大小: {self.grid_size}米, 单个网格最大点数: {max_points}") + + # 如果最大点数超过1500,减小网格大小 + if max_points > 1500: + self.grid_size -= 100 + self.logger.info(f"点数超过1500,减小网格大小至: {self.grid_size}米") + if self.grid_size < 500: # 设置一个最小网格大小限制 + self.logger.warning("网格大小已达到最小值500米,停止调整") + break + else: + self.logger.info(f"找到合适的网格大小: {self.grid_size}米") + break + return grids + - def divide_grids(self, points_df, grid_size=500): + def adjust_grid_size_and_overlap(self, points_df): + """动态调整网格重叠率""" + grids = self.adjust_grid_size(points_df) + self.logger.info(f"开始动态调整网格重叠率,初始重叠率: {self.overlap}") + while True: + # 使用调整好的网格大小划分网格 + grids, translations = self.divide_grids(points_df) + grid_points, multiple_grid_points = self.assign_to_grids(points_df, grids) + + if len(grids) == 1: + self.logger.info(f"网格数量为1,跳过重叠率调整") + break + elif multiple_grid_points < 0.1*len(points_df): + self.overlap += 0.02 + self.logger.info(f"重叠率增加到: {self.overlap}") + else: + self.logger.info(f"找到合适的重叠率: {self.overlap}, 有{multiple_grid_points}个点被分配到多个网格") + break + return grids, translations, grid_points + + def divide_grids(self, points_df): """计算边界框并划分网格 Returns: tuple: (grids, translations) @@ -33,9 +90,18 @@ class GridDivider: self.logger.info(f"区域宽度: {width:.2f}米, 高度: {height:.2f}米") + # 精细调整网格的长宽,避免出现2*grid_size-1的情况的影响 + grid_size_lt = [self.grid_size -200, self.grid_size -100, self.grid_size , self.grid_size +100, self.grid_size +200] + + width_modulus_lt = [width % grid_size for grid_size in grid_size_lt] + grid_width = grid_size_lt[width_modulus_lt.index(min(width_modulus_lt))] + height_modulus_lt = [height % grid_size for grid_size in grid_size_lt] + grid_height = grid_size_lt[height_modulus_lt.index(min(height_modulus_lt))] + self.logger.info(f"网格宽度: {grid_width:.2f}米, 网格高度: {grid_height:.2f}米") + # 计算需要划分的网格数量 - self.num_grids_width = max(int(width / grid_size), 1) - self.num_grids_height = max(int(height / grid_size), 1) + self.num_grids_width = max(int(width / grid_width), 1) + self.num_grids_height = max(int(height / grid_height), 1) # 计算每个网格对应的经纬度步长 lat_step = (max_lat - min_lat) / self.num_grids_height @@ -78,9 +144,6 @@ class GridDivider: self.logger.info( f"成功划分为 {len(grids)} 个网格 ({self.num_grids_width}x{self.num_grids_height})") - - # 添加可视化调用 - self.visualize_grids(points_df, grids) return grids, grid_translations @@ -122,7 +185,7 @@ class GridDivider: f"{multiple_grid_points} 个点被分配到多个网格" ) - return grid_points + return grid_points, multiple_grid_points def visualize_grids(self, points_df, grids): """可视化网格划分和GPS点的分布""" @@ -132,7 +195,7 @@ class GridDivider: # 绘制GPS点 plt.scatter(points_df['lon'], points_df['lat'], - c='blue', s=10, alpha=0.6, label='GPS点') + c='blue', s=10, alpha=0.6, label='GPS points') # 绘制网格 for i in range(self.num_grids_height): @@ -140,14 +203,21 @@ class GridDivider: grid_idx = i * self.num_grids_width + j min_lat, max_lat, min_lon, max_lon = grids[grid_idx] + # 计算网格的实际长度和宽度(米) + width = geodesic((min_lat, min_lon), (min_lat, max_lon)).meters + height = geodesic((min_lat, min_lon), (max_lat, min_lon)).meters + plt.plot([min_lon, max_lon, max_lon, min_lon, min_lon], [min_lat, min_lat, max_lat, max_lat, min_lat], 'r-', alpha=0.5) - # 在网格中心添加网格编号 + # 在网格中心添加网格编号和尺寸信息 center_lon = (min_lon + max_lon) / 2 center_lat = (min_lat + max_lat) / 2 - plt.text(center_lon, center_lat, f"({i},{j})", # 显示(i,j) - horizontalalignment='center', verticalalignment='center') + plt.text(center_lon, center_lat, + f"({i},{j})\n{width:.0f}m×{height:.0f}m", # 显示(i,j)和尺寸 + horizontalalignment='center', + verticalalignment='center', + fontsize=8) plt.title('Grid Division and GPS Point Distribution') plt.xlabel('Longitude')