影像分块拼接错误:上下区域位置颠倒问题求助
影像拼接上下颠倒问题排查与解决
问题背景
现有多边形坐标点:
geometry = [ [ [38.752152,37.208675], [39.224913,37.208675], [39.224913,36.686262], [38.752152,36.686262], [38.752152,37.208675] ] ]
通过该坐标获取了5000x5000尺寸的影像,需拆分为4张2500x2500的子影像后拼接。拆分与拼接的核心代码如下:
区域拆分代码
step_x = round(size[0]/2500+1) step_y = round(size[1]/2500+1) points_x = numpy.linspace(x_min,x_max,step_x) points_y = numpy.linspace(y_min,y_max,step_y) combinedImage = numpy.zeros((step_x*2500,step_y*2500,3)) # 用于拼接影像
子影像获取与拼接代码
size_x = len(points_x) size_y = len(points_y) for y in range(size_y-1): for x in range(size_x-2,-1,-1): tmpGeometry = [[[points_x[x],points_y[y]],[points_x[x+1],points_y[y]],[points_x[x],points_y[y+1]],[points_x[x+1],points_y[y+1]]]] x_min, y_min = numpy.min(tmpGeometry, axis = 1)[0]# 左上角坐标 x_max, y_max = numpy.max(tmpGeometry, axis = 1)[0]# 右下角坐标 sentinelhub.setBBox(x_min,y_min,x_max,y_max) image = sentinelhub.sendRequest()# 获取子影像 combinedImage[2500*y:2500*(y+1),2500*x:2500*(x+1)] = image# 拼接影像 print((x,y),(x,y+1),(x+1,y),(x+1,y+1))
错误现象
拼接完成后影像出现上下颠倒错乱,原本位于顶部的区域被拼到底部,底部区域出现在顶部,红色线条处可见明显错位。
问题原因与修复方案
核心原因
- 坐标系Y轴方向不匹配:地理坐标系中纬度值越大越靠北(对应影像顶部),但图像数组的Y轴索引是从上到下递增(索引0对应图像顶部,索引越大越靠下)。
points_y生成顺序错误:原代码用numpy.linspace(y_min,y_max,step_y)生成的是从低纬度到高纬度的序列,直接用y索引对应图像Y轴位置时,会把高纬度(顶部)的子影像放到图像底部。- 拼接数组维度定义错误:原代码中
combinedImage的维度写反,应该是(step_y*2500, step_x*2500, 3)(高度对应Y方向步数,宽度对应X方向步数)。
修复步骤
1. 修正points_y的生成顺序
将points_y改为从高纬度到低纬度生成,确保地理坐标的顶部对应图像数组的顶部索引:
# 直接反转linspace的起止值,生成从高纬度到低纬度的序列 points_y = numpy.linspace(y_max, y_min, step_y)
2. 修正拼接数组的维度
combinedImage = numpy.zeros((step_y*2500, step_x*2500, 3))
3. 调整X方向遍历顺序(可选)
原代码中X方向反向遍历会导致左右颠倒,若无需左右反转,改为正序遍历:
for x in range(size_x-1):
4. 验证子影像本身的Y轴方向(可选)
部分遥感API返回的子影像可能本身Y轴倒置,若上述修复后仍有问题,可在获取子影像后反转其Y轴:
image = sentinelhub.sendRequest()[::-1, :, :]
完整修复后代码示例
step_x = round(size[0]/2500+1) step_y = round(size[1]/2500+1) points_x = numpy.linspace(x_min,x_max,step_x) # 修正points_y生成顺序 points_y = numpy.linspace(y_max, y_min, step_y) # 修正拼接数组维度 combinedImage = numpy.zeros((step_y*2500, step_x*2500, 3)) size_x = len(points_x) size_y = len(points_y) for y in range(size_y-1): # 正序遍历X方向 for x in range(size_x-1): tmpGeometry = [[[points_x[x],points_y[y]],[points_x[x+1],points_y[y]],[points_x[x],points_y[y+1]],[points_x[x+1],points_y[y+1]]]] x_min, y_min = numpy.min(tmpGeometry, axis = 1)[0] x_max, y_max = numpy.max(tmpGeometry, axis = 1)[0] sentinelhub.setBBox(x_min,y_min,x_max,y_max) image = sentinelhub.sendRequest() combinedImage[2500*y:2500*(y+1),2500*x:2500*(x+1)] = image
内容的提问来源于stack exchange,提问作者Wtow
相关产品推荐
相关产品推荐

