Ejemplo n.º 1
0
def output_result_based_max(raw_image_path, samples_dir, save_path,
                            labels_dict):
    """ 输出分类结果

    根据分类标签取概率值最大者对应类别,以tiff文件的格式输出分类结果

    Args:
        raw_image_path: 原始影像路径
                        str
        samples_dir: 与标签对应的样本目录
                     str
        save_path: 结果保存路径
                   str
        labels_dict: 与样本对应的分类标签
                     dict{'sample_name': [(index, value), ...]}
    """

    gdal.AllRegister()
    data_set = gdal.Open(raw_image_path)
    trans = data_set.GetGeoTransform()
    proj = data_set.GetProjection()
    img_rows, img_cols = data_set.RasterYSize, data_set.RasterXSize

    res_array = np.full((img_rows, img_cols), 255, dtype=np.uint8)
    value_array = np.full((img_rows, img_cols), -1, dtype=np.float32)

    g = os.walk(samples_dir)
    for path, dir_list, file_list in g:
        for file in file_list:
            area_id, ext = os.path.splitext(file)
            if ext != '.tif':
                continue
            if area_id not in labels_dict.keys():
                continue

            sys.stdout.write('\rProcessing %s ...' % area_id)
            sys.stdout.flush()

            cur_label, cur_value = labels_dict[area_id][0]
            file_path = os.path.join(path, file)
            cur_data_set = gdal.Open(file_path)
            cur_rows, cur_cols = cur_data_set.RasterYSize, cur_data_set.RasterXSize
            geo_x_org, geo_y_org = transform.imagexy2geo(cur_data_set, 0, 0)
            geo_x_end, geo_y_end = transform.imagexy2geo(
                cur_data_set, cur_rows - 1, cur_cols - 1)
            res_row_org, res_col_org = transform.geo2imagexy(
                data_set, geo_x_org, geo_y_org)
            res_row_end, res_col_end = transform.geo2imagexy(
                data_set, geo_x_end, geo_y_end)

            rect_arr = res_array[res_row_org:res_row_end,
                                 res_col_org:res_col_end]
            rect_value_arr = value_array[res_row_org:res_row_end,
                                         res_col_org:res_col_end]
            cond = rect_value_arr < cur_value
            rect_arr[cond] = cur_label
            rect_value_arr[cond] = cur_value

    save_tiff(save_path, res_array[np.newaxis, :], img_rows, img_cols, 1,
              trans, proj)
Ejemplo n.º 2
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!')
Ejemplo n.º 3
0
def grid_to_coord(dataset, location_array):
    """ 栅格坐标转地理坐标

    Args:
        dataset: gdal读取的影像数据集
        location_array: 待转换的栅格坐标列表
                        array[[raw, col],
                              ...
                              []]
    Return:
        res_arr: shape与location_array对应的地理坐标列表
                 array[[lng, lat],
                       ...
                       []]
    """

    poi_num = location_array.shape[0]
    res_arr = np.zeros((poi_num, 2), dtype='float32')
    for i in range(0, poi_num):
        row = location_array[i, 0]
        col = location_array[i, 1]
        geo_x, geo_y = transform.imagexy2geo(dataset, row, col)
        res_arr[i] = transform.geo2lonlat(dataset, geo_x, geo_y)
    return res_arr
Ejemplo n.º 4
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)
Ejemplo n.º 5
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!')
Ejemplo n.º 6
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!')
Ejemplo n.º 7
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