Julia中热力图坐标转像素出现明显误差,求助排查
解决热力图地理坐标到像素坐标的线性转换误差问题
你的代码目前采用轴对齐的线性缩放逻辑,假设经度仅与x像素线性相关、纬度仅与y像素线性相关,但实际上你的四个角坐标构成的是平行四边形(无畸变、对边相等):x方向的经度变化率在上下两行不一致,y方向的纬度变化率在左右两列也不一致,简单的min/max分割必然导致坐标映射误差。
解决方案:使用仿射变换实现精准映射
因为地图无畸变且对边相等,完全符合仿射变换的应用场景——仿射变换可以完美处理平行四边形的坐标映射关系,通过求解变换矩阵,就能实现地理坐标到像素坐标的准确转换。
具体实现步骤
- 定义四个角的地理坐标与对应像素坐标的映射关系:
- 左上角地理坐标 → 像素坐标
(0, 0) - 左下角地理坐标 → 像素坐标
(0, n_rows-1) - 右下角地理坐标 → 像素坐标
(n_cols-1, n_rows-1) - 右上角地理坐标 → 像素坐标
(n_cols-1, 0)
- 左上角地理坐标 → 像素坐标
- 基于仿射变换公式构建方程组,求解变换参数:
x_pixel = a*lon + b*lat + c y_pixel = d*lon + e*lat + f - 用求解出的参数实现坐标转换函数,并验证四个角的映射准确性。
修正后的代码(Julia)
# 四个角的地理坐标(lon, lat) geo_points = [ [-118.9883423, 34.8782616], # top-left [-119.4855042, 34.2534752], # bottom-left [-118.7960052, 33.7048225], # bottom-right [-118.2988434, 34.3296089] # top-right ] n_rows, n_cols = size(normalized_band) # 对应像素坐标 pixel_points = [ [0, 0], [0, n_rows-1], [n_cols-1, n_rows-1], [n_cols-1, 0] ] # 求解x方向变换参数:x = a*lon + b*lat + c A_x = [ geo_points[1][1] geo_points[1][2] 1; geo_points[2][1] geo_points[2][2] 1; geo_points[3][1] geo_points[3][2] 1 ] b_x = [pixel_points[1][1], pixel_points[2][1], pixel_points[3][1]] a, b, c = A_x \ b_x # 求解y方向变换参数:y = d*lon + e*lat + f A_y = [ geo_points[1][1] geo_points[1][2] 1; geo_points[2][1] geo_points[2][2] 1; geo_points[3][1] geo_points[3][2] 1 ] b_y = [pixel_points[1][2], pixel_points[2][2], pixel_points[3][2]] d, e, f = A_y \ b_y # 坐标转换函数 function coord_to_pixel(lon, lat) x_pixel = a*lon + b*lat + c y_pixel = d*lon + e*lat + f return round(Int, x_pixel), round(Int, y_pixel) end # 验证四个角的转换结果(应输出对应像素坐标) println(coord_to_pixel(geo_points[1][1], geo_points[1][2])) println(coord_to_pixel(geo_points[2][1], geo_points[2][2])) println(coord_to_pixel(geo_points[3][1], geo_points[3][2])) println(coord_to_pixel(geo_points[4][1], geo_points[4][2]))
补充说明
- 代码中用前三个点求解变换参数,第四个点用于验证(平行四边形特性下,仿射变换会完美匹配第四个点)
- 如果你的图像像素坐标系原点是左下角(部分图像库的设定),只需调整
pixel_points的y值即可,比如左上角对应(0, n_rows-1)、左下角对应(0, 0)
内容的提问来源于stack exchange,提问作者Anwesh saha
相关产品推荐
相关产品推荐

