예제 #1
0
def clip_with_centroids(image_path, save_dir, centroids_dict, shape):
    """ 裁剪得到ROI

    以给定点为中心裁剪固定大小(取决于shape)的区域得到ROI, 并保存为.tif文件

    Args:
        image_path: 原始影像路径
                    str
        save_dir: ROI影像保存目录
                  str
        centroids_dict: 中心点字典
                        dict{'polygon_name': array([lon, lat]), ...}
        shape: 裁剪ROI大小
               tuple(height, width)
    """

    gdal.AllRegister()
    data_set = gdal.Open(image_path)
    if data_set is None:
        raise FileNotFoundError('File %s not found' % image_path)
    if not os.path.exists(save_dir):
        os.makedirs(save_dir)

    img_tran = data_set.GetGeoTransform()
    img_proj = data_set.GetProjection()
    img_data = data_set.ReadAsArray()
    raster_num, img_rows, img_cols = img_data.shape
    for plg_name, centroid in centroids_dict.items():
        geo_x, geo_y = transform.lonlat2geo(data_set, centroid[0], centroid[1])
        centroid_grid = transform.geo2imagexy(data_set, geo_x, geo_y)
        sys.stdout.write(
            '\rProcessing centroid (%f, %f) --> (%d, %d) ...' %
            (centroid[0], centroid[1], centroid_grid[0], centroid_grid[1]))
        sys.stdout.flush()

        row_min = int(centroid_grid[0] - int(shape[0] / 2))
        if row_min < 0:
            row_min = 0
        col_min = int(centroid_grid[1] - int(shape[1] / 2))
        if col_min < 0:
            col_min = 0
        row_max = int(centroid_grid[0] + shape[0] - int(shape[0] / 2))
        col_max = int(centroid_grid[1] + shape[1] - int(shape[1] / 2))
        roi_arr = img_data[:, row_min:row_max, col_min:col_max].copy()
        roi_tran = list(img_tran)
        roi_tran[0], roi_tran[3] = transform.imagexy2geo(
            data_set, row_min, col_min)

        save_name = os.path.join(save_dir, '%s.tif' % plg_name)
        save_tiff(save_name, roi_arr, roi_arr.shape[1], roi_arr.shape[2],
                  raster_num, roi_tran, img_proj)
    del data_set
    print('\nMission completed!')
예제 #2
0
def clip(image_path, save_path, x_size, y_size, offset_x=0, offset_y=0):
    """
    裁剪影像至指定大小

    Args:
        image_path: 原始影像路径
                    str
        save_path: 结果保存路径
                   str
        x_size: 行大小
                int
        y_size: 列大小
                int
        offset_x: 行偏移量,默认为0
                  int
        offset_y: 列偏移量,默认为0
                  int
    """

    gdal.AllRegister()
    print('Reading raw image ...')
    data_set = gdal.Open(image_path)
    if data_set is None:
        raise FileNotFoundError('File %s Not found' % image_path)
    img_tran = data_set.GetGeoTransform()
    img_proj = data_set.GetProjection()
    img_data = data_set.ReadAsArray()
    raster_num, img_rows, img_cols = img_data.shape

    if offset_x + x_size > img_rows:
        end_x = img_rows
    else:
        end_x = offset_x + x_size
    if offset_y + y_size > img_cols:
        end_y = img_cols
    else:
        end_y = offset_y + y_size

    res_data = img_data[:, offset_x:end_x, offset_y:end_y]
    save_tiff(save_path,
              res_data,
              end_x - offset_x,
              end_y - offset_y,
              raster_num,
              geotran_info=img_tran,
              proj_info=img_proj)
예제 #3
0
def clip_with_sliding_window(image_path, save_dir, shape, step, save_img=True):
    """ 以滑动窗口截取ROI

    以固定大小的窗口、以固定步长在影像中滑动,截取ROI

    Args:
        image_path: 原始影像路径
                    str
        save_dir: ROI保存目录
                  str
        shape: 窗口大小
               tuple(height, width)
        step: 步长
              int
        save_img: 保存图像
                  bool
    """

    gdal.AllRegister()
    data_set = gdal.Open(image_path)
    if data_set is None:
        raise FileNotFoundError('File %s not found' % image_path)
    if not os.path.exists(save_dir):
        os.makedirs(save_dir)

    img_tran = data_set.GetGeoTransform()
    img_proj = data_set.GetProjection()
    img_data = data_set.ReadAsArray()
    rect_dict = {}
    raster_num, img_rows, img_cols = img_data.shape
    box_rows = int((img_rows - shape[0]) / step + 1)
    box_cols = int((img_cols - shape[1]) / step + 1)
    total_num = box_rows * box_cols
    roi_idx = 1
    for i in range(0, img_rows, step):
        for j in range(0, img_cols, step):
            roi_arr = img_data[:, i:i + shape[0], j:j + shape[1]].copy()
            if roi_arr.shape[1:3] != shape:
                continue
            sys.stdout.write('\rProcessing %d/%d ...' % (roi_idx, total_num))
            sys.stdout.flush()
            geo_x_nw, geo_y_nw = transform.imagexy2geo(data_set, i, j)
            lon_nw, lat_nw = transform.geo2lonlat(data_set, geo_x_nw, geo_y_nw)
            geo_x_se, geo_y_se = transform.imagexy2geo(data_set, i + shape[0],
                                                       j + shape[1])
            lon_se, lat_se = transform.geo2lonlat(data_set, geo_x_se, geo_y_se)
            rect_str = '%0.6f,%0.6f,%0.6f,%0.6f' % (lon_nw, lat_nw, lon_se,
                                                    lat_se)
            rect_dict['%05d' % roi_idx] = rect_str

            roi_tran = list(img_tran)
            roi_tran[0], roi_tran[3] = geo_x_nw, geo_y_nw
            if save_img:
                save_name = os.path.join(
                    save_dir, '%03d%03d_%06d.tif' %
                    (roi_idx / box_cols, roi_idx % box_cols, roi_idx))
                save_tiff(save_name, roi_arr, shape[0], shape[1], raster_num,
                          roi_tran, img_proj)
            roi_idx += 1
    del data_set
    rect_save_name = os.path.join(save_dir,
                                  'rect_dict_%d_%d.json' % (shape[0], step))
    with open(rect_save_name, 'w') as d_f:
        json.dump(rect_dict, d_f)
예제 #4
0
def mask_roi(image_path, mask_path, save_dir):
    """ 从tif格式的掩膜文件中提取roi

    可实现从包含多个ROI的.tif文件中自动提取所有ROI的所有区域,
    并将每块影像保存至.tif文件中, ROI多边形dict保存至.json文件中
    保存每个块的面积保存至area.json中

    Args:
        image_path: 带有地理信息的原始影像文件路径
                  str
        mask_path: 与影像地理信息相同的tif格式的掩膜文件路径
                   str
        save_dir: 保存文件目录
                  str
    """

    gdal.AllRegister()
    print('Reading raw image ...')
    img_data_set = gdal.Open(image_path)
    print('Reading mask image ...')
    mask_data_set = gdal.Open(mask_path)
    if img_data_set is None:
        raise FileNotFoundError('File %s not found' % image_path)
    if mask_data_set is None:
        raise FileNotFoundError('File %s not found!' % mask_path)
    img_tran = img_data_set.GetGeoTransform()
    img_proj = img_data_set.GetProjection()
    mask_proj = mask_data_set.GetProjection()
    if img_proj != mask_proj:
        raise ValueError('Wrong mask file!')
    if not os.path.exists(save_dir):
        os.makedirs(save_dir)

    img_data = img_data_set.ReadAsArray()
    mask_data = mask_data_set.ReadAsArray()
    dict_save_name = os.path.join(save_dir, 'all_polygons.json')
    plg_str_list = []
    region_dict = {}
    area_dict = {}
    raster_num, img_rows, img_cols = img_data.shape
    rois_num = mask_data.max()
    for i in range(1, rois_num + 1):
        sys.stdout.write('\rProcessing %dth polygon ...' % i)
        sys.stdout.flush()
        mask_idxs = np.argwhere(mask_data == i)
        if mask_idxs.shape[0] == 0:
            continue
        rect = get_extent(mask_idxs)
        plg_row_min, plg_row_max, plg_col_min, plg_col_max = limit_boundary(
            rect, (0, img_rows, 0, img_cols))
        mask_rows = plg_row_max - plg_row_min + 1
        mask_cols = plg_col_max - plg_col_min + 1
        mask = mask_data[plg_row_min:plg_row_max + 1,
                         plg_col_min:plg_col_max + 1].copy()
        mask_flag = mask.copy()
        mask[mask_flag == i] = 1
        mask[mask_flag != i] = 0
        del mask_flag
        area = mask.sum()
        area_dict['%04d' % i] = int(area)

        # 提取并保存凸包
        plg = array2vector(mask)
        plg_str = ''
        for point in plg:
            p_geo_x, p_geo_y = transform.imagexy2geo(mask_data_set,
                                                     plg_row_min + point[0],
                                                     plg_col_min + point[1])
            p_lon, p_lat = transform.geo2lonlat(mask_data_set, p_geo_x,
                                                p_geo_y)
            plg_str += '%f,%f|' % (p_lon, p_lat)
        print(plg_str)
        print()
        plg_str_list.append(plg_str[:-1])
        region_dict['all_polygons'] = plg_str_list
        with open(dict_save_name, 'w') as d_f:
            js = json.dumps(region_dict)
            d_f.write(js)

        # 提取并保存影像
        masked = img_data[:, plg_row_min:(plg_row_min + mask_rows),
                          plg_col_min:(plg_col_min + mask_cols)].copy()
        if masked.shape[1:3] != mask.shape:
            continue
        for j in range(0, raster_num):
            masked[j][mask != 1] = 0
        save_name = os.path.join(save_dir, '%04d.tif' % i)
        geo_x, geo_y = transform.imagexy2geo(img_data_set, plg_row_min,
                                             plg_col_min)
        masked_tran = list(img_tran)
        masked_tran[0] = geo_x
        masked_tran[3] = geo_y
        save_tiff(save_name, masked, mask_rows, mask_cols, raster_num,
                  masked_tran, img_proj)
    area_path = os.path.join(save_dir, 'area.json')
    with open(area_path, 'w') as a_f:
        json.dump(area_dict, a_f)
    del mask_data_set
    del img_data_set
    print('\nMission completed!')
예제 #5
0
def extract_roi(image_path, xml_file_path, save_dir):
    """ ROI提取

    可实现从包含多个ROI的.xml文件中自动提取所有ROI的所有区域,并保存至.tif文件中

    Args:
        image_path: 带有地理信息的原始影像文件路径
                  str
        xml_file_path: 带含多个ROI且具有与img_path文件相同地理参考信息的.xml文件路径
                       str
        save_dir: 保存文件目录
                   str
    """

    gdal.AllRegister()
    print('Reading raw image ...')
    data_set = gdal.Open(image_path)
    if data_set is None:
        raise FileNotFoundError('File %s Not found' % image_path)
    img_tran = data_set.GetGeoTransform()
    img_proj = data_set.GetProjection()
    img_data = data_set.ReadAsArray()
    raster_num, img_rows, img_cols = img_data.shape

    print('Reading .xml file ...')
    if xml_file_path[-4:] != '.xml':
        raise TypeError('Unrecognizable type: \'%s\'' % xml_file_path[-4:])
    xml_proj, regions_dict = extract_xml_info(xml_file_path)
    print('Image Projection: %s' % img_proj)
    print('ROI Projection: %s' % xml_proj)
    if 'PROJCS' in xml_proj:
        with_projcs = True
    else:
        with_projcs = False
    roi_dict = transform_geo_to_ctype(data_set,
                                      regions_dict,
                                      ctype='grid',
                                      with_projcs=with_projcs)

    for region_name in roi_dict.keys():
        plg_list = roi_dict[region_name]
        i = 0
        for plg in plg_list:
            i += 1
            sys.stdout.write('\rProcessing \"%s\" %04d ...' % (region_name, i))
            sys.stdout.flush()
            plg_points = np.array(plg[:-1], dtype='int32')
            rect = get_extent(plg_points)

            plg_row_min, plg_row_max, plg_col_min, plg_col_max = limit_boundary(
                rect, (0, img_rows, 0, img_cols))

            plg_points[:, 0] = plg_points[:, 0] - plg_row_min
            plg_points[:, 1] = plg_points[:, 1] - plg_col_min
            plg_points[:, [0, 1]] = plg_points[:, [1, 0]]
            plg_points = plg_points[np.newaxis]
            mask_rows = plg_row_max - plg_row_min
            mask_cols = plg_col_max - plg_col_min
            mask = np.zeros((mask_rows, mask_cols), dtype='uint8')
            cv2.polylines(mask, plg_points, 1, 255)
            cv2.fillPoly(mask, plg_points, 255)
            cond = mask == 0

            masked = img_data[:, plg_row_min:(plg_row_min + mask_rows),
                              plg_col_min:(plg_col_min + mask_cols)].copy()
            for j in range(0, raster_num):
                masked[j][cond] = 0

            directory = os.path.join(save_dir, region_name)
            folder = os.path.exists(directory)
            if not folder:
                os.makedirs(directory)
            save_name = os.path.join(directory, '%04d.tif' % i)

            geo_x, geo_y = transform.imagexy2geo(data_set, plg_row_min,
                                                 plg_col_min)
            masked_tran = list(img_tran)
            masked_tran[0] = geo_x
            masked_tran[3] = geo_y
            save_tiff(save_name, masked, mask_rows, mask_cols, raster_num,
                      masked_tran, img_proj)
    del data_set
    print('\nMission completed!')
예제 #6
0
def extract_roi_box(image_path, xml_file_path, save_dir):
    """ ROI最小外接矩形提取

    可实现从包含多个ROI的.xml文件中自动提取所有ROI的所有区域的最小外接矩形,并保存至.tif文件中

    Args:
        image_path: 带有地理信息的原始影像文件路径
                  str
        xml_file_path: 带含多个ROI且具有与img_path文件相同地理参考信息的.xml文件路径
                       str
        save_dir: 保存文件目录
                   str
    Returns:
        res: 外接矩形列表
    """
    gdal.AllRegister()
    print('Reading raw image ...')
    data_set = gdal.Open(image_path)
    if data_set is None:
        raise FileNotFoundError('File %s Not found' % image_path)
    img_tran = data_set.GetGeoTransform()
    img_proj = data_set.GetProjection()
    img_data = data_set.ReadAsArray()
    raster_num, img_rows, img_cols = img_data.shape

    print('Reading .xml file ...')
    if xml_file_path[-4:] != '.xml':
        raise TypeError('Unrecognizable type: \'%s\'' % xml_file_path[-4:])
    xml_proj, regions_dict = extract_xml_info(xml_file_path)
    print('Image Projection: %s' % img_proj)
    print('ROI Projection: %s' % xml_proj)
    if 'PROJCS' in xml_proj:
        with_projcs = True
    else:
        with_projcs = False
    roi_dict = transform_geo_to_ctype(data_set,
                                      regions_dict,
                                      ctype='grid',
                                      with_projcs=with_projcs)

    res = []
    for region_name in roi_dict.keys():
        plg_list = roi_dict[region_name]
        i = 0
        for plg in plg_list:
            i += 1
            print('\rProcessing \"%s\" %04d ...' % (region_name, i), end='')
            plg_points = np.array(plg[:-1], dtype='int32')
            rect = limit_boundary(get_extent(plg_points),
                                  (0, img_rows, 0, img_cols))
            res.append(rect)

            box_img = img_data[:, rect[0]:rect[1], rect[2]:rect[3]].copy()

            directory = os.path.join(save_dir, region_name)
            folder = os.path.exists(directory)
            if not folder:
                os.makedirs(directory)
            save_name = os.path.join(directory, '%04d.tif' % i)

            geo_x, geo_y = transform.imagexy2geo(data_set, rect[0], rect[2])
            masked_tran = list(img_tran)
            masked_tran[0] = geo_x
            masked_tran[3] = geo_y
            save_tiff(save_name, box_img, rect[1] - rect[0], rect[3] - rect[2],
                      raster_num, masked_tran, img_proj)

    del data_set
    print('\nMission completed!')
    return res