在R中如何将图像坐标系的树木检测边界框转换为NAD83(CSRS)坐标系?
图像坐标系边界框转UTM地理坐标实现栅格叠加方案
核心逻辑
模型输出的边界框是图像像素坐标系(左上角为(0,0),x向右递增,y向下递增),而你的栅格采用UTM 18N(EPSG:2959)地理坐标系。转换的关键是利用栅格的地理变换参数,将像素坐标映射到地理坐标。
具体实现步骤(基于R的terra/sf/deepforestr)
1. 读取栅格并获取地理变换参数
先读取目标栅格,提取其左上角地理坐标、分辨率等核心参数:
library(deepforestr) library(terra) library(sf) library(dplyr) # 加载模型并预测(复用你的代码框架) model = df_model() model$use_release() raster_path = "你的本地栅格路径.tif" # 替换为实际栅格路径 bounding_boxes = model$predict_tile(raster_path, return_plot=FALSE) # 仅返回数据框,关闭绘图 # 读取栅格,提取地理参数 r = rast(raster_path) # 栅格左上角的地理坐标(x=东向,y=北向) raster_origin_x = xmin(r) raster_origin_y = ymax(r) # 栅格分辨率(x/y方向的像素宽度/高度) res_x = xres(r) res_y = yres(r)
2. 将像素边界框转换为地理坐标
遍历每个边界框,把xmin/xmax(像素列)和ymin/ymax(像素行)转成UTM坐标:
# 像素坐标转地理坐标的工具函数 pixel_to_geo <- function(pixel_col, pixel_row, origin_x, origin_y, res_x, res_y) { geo_x = origin_x + pixel_col * res_x # 图像y向下递增,地理y向上递增,因此用原点y减去像素行*分辨率 geo_y = origin_y - pixel_row * res_y return(c(geo_x, geo_y)) } # 批量处理所有边界框并转为sf对象 bbox_geo = bounding_boxes %>% mutate( # 计算四个角点的地理坐标 tl_geo = pmap(list(xmin, ymin), ~pixel_to_geo(..1, ..2, raster_origin_x, raster_origin_y, res_x, res_y)), tr_geo = pmap(list(xmax, ymin), ~pixel_to_geo(..1, ..2, raster_origin_x, raster_origin_y, res_x, res_y)), br_geo = pmap(list(xmax, ymax), ~pixel_to_geo(..1, ..2, raster_origin_x, raster_origin_y, res_x, res_y)), bl_geo = pmap(list(xmin, ymax), ~pixel_to_geo(..1, ..2, raster_origin_x, raster_origin_y, res_x, res_y)) ) %>% rowwise() %>% mutate(geometry = st_polygon(list(rbind(tl_geo, tr_geo, br_geo, bl_geo, tl_geo)))) %>% st_as_sf(crs = st_crs(r)) # 继承栅格的EPSG:2959坐标系
3. 验证叠加效果
用terra绘图工具确认边界框与栅格的匹配度:
# 绘制栅格底图 plot(r) # 叠加红色边界框 plot(st_geometry(bbox_geo), add=TRUE, col="red", lwd=2)
关键注意事项
- 提前确认栅格CRS为EPSG:2959,可通过
st_crs(r)查看 - 模型输出的
ymin对应图像上方像素行,转换后UTM北向坐标更大;ymax对应图像下方行,北向坐标更小,符合地理坐标系逻辑 - 若模型输出的像素坐标是1索引(而非你描述的0索引),需先对
xmin/xmax/ymin/ymax减1再计算
内容的提问来源于stack exchange,提问作者Priya Patel
相关产品推荐
相关产品推荐

