如何在Matplotlib Pyplot图像指定坐标点获取颜色值?
用Matplotlib/Pyplot或Scikit-image实现精准地理坐标到赛道点的判断
一、Matplotlib/Pyplot方案(优先选,适配你的绘图流程)
既然你是用Pyplot绘制的赛道图,直接复用它的坐标变换系统就能解决手动转换不准的问题,不用绕到外部库。
1. 精准转换地理坐标到图片像素
绘图时一定要保留fig和ax对象,这样可以调用Matplotlib内置的坐标变换工具,自动处理画布缩放、坐标轴偏移等细节:
import matplotlib.pyplot as plt # 示例:你的绘图代码(保留ax对象) fig, ax = plt.subplots() # 设置地理坐标范围(和你赛道的真实范围对应) ax.set_xlim(54.620, 54.690) # 东经范围 ax.set_ylim(24.464, 24.478) # 北纬范围 # 绘制灰色背景、黄色赛道、红绿起点终点... # 定义坐标转换函数 def geo_to_pixel(geo_point, ax): lon, lat = geo_point # 先转成轴的归一化坐标(0-1),再转成像素坐标 norm_coord = ax.transLimits.transform((lon, lat)) pixel_coord = ax.transAxes.inverted().transform(norm_coord) # 转成整数像素索引,注意图像y轴是反向的 canvas_w, canvas_h = ax.figure.canvas.get_width_height() px = int(pixel_coord[0] * canvas_w) py = canvas_h - int(pixel_coord[1] * canvas_h) return (px, py)
2. 判断点是否在赛道上
分两种场景处理:
场景1:赛道是图像格式(用imshow加载的)
如果你的赛道是一张图像(比如用imshow绘制),直接提取对应像素的颜色值:
import numpy as np # 假设你是这样加载赛道图的(extent必须和地理范围匹配) track_img = plt.imread("your_track.jpg") im_obj = ax.imshow(track_img, extent=[54.620, 54.690, 24.464, 24.478]) img_array = im_obj.get_array() # 转换目标地理点 target_point = (54.66023, 24.46823) px, py = geo_to_pixel(target_point, ax) # 获取颜色(注意数组索引是[y, x]) pixel_color = img_array[py, px] # 根据你的颜色规则判断 if np.array_equal(pixel_color, [255, 255, 0]): # 黄色赛道 print("该点在赛道上") elif np.array_equal(pixel_color, [255, 0, 0]): # 红色起点 print("该点是起点") elif np.array_equal(pixel_color, [0, 255, 0]): # 绿色终点 print("该点是终点") else: print("该点不在赛道上")
场景2:赛道是矢量路径(用plot绘制的线条)
如果赛道是用矢量线条画的,直接判断点是否在路径范围内比看颜色更准确(避免图像压缩、抗锯齿的误差):
from matplotlib.path import Path # 假设track_points是你绘制赛道时用的地理坐标列表 track_points = [(lon1, lat1), (lon2, lat2), ...] track_path = Path(track_points) # 判断目标点是否在赛道路径内(radius设置赛道宽度,单位和地理坐标一致) target_point = (54.66023, 24.46823) is_on_track = track_path.contains_point(target_point, radius=0.0005) # 半径根据实际赛道宽度调整 if is_on_track: print("该点在赛道上") else: print("该点不在赛道上")
二、Scikit-image方案
如果习惯用skimage处理图像,可以通过建立线性变换来实现精准坐标转换:
1. 构建地理坐标到像素的变换
from skimage.transform import AffineTransform import numpy as np from skimage.io import imread img = imread("your_track.jpg") img_h, img_w = img.shape[:2] # 地理范围参数 lon_min, lon_max = 54.620, 54.690 lat_min, lat_max = 24.464, 24.478 # 创建线性变换矩阵 transform = AffineTransform( scale=(img_w/(lon_max - lon_min), img_h/(lat_max - lat_min)), translation=(-lon_min * img_w/(lon_max - lon_min), -lat_min * img_h/(lat_max - lat_min)) ) # 转换目标点 target_point = np.array([[54.66023, 24.46823]]) px, py = transform(target_point)[0].astype(int) # 翻转y轴(图像坐标系和地理坐标系y方向相反) py = img_h - py
2. 获取像素颜色并判断
pixel_color = img[py, px] # 颜色判断逻辑和之前一致
核心提示
- 不管用哪种方法,地理范围和图像/坐标轴的范围必须严格匹配,这是坐标转换精准的关键。
- 矢量赛道优先用
Path.contains_point判断,比颜色识别更可靠,尤其是赛道有宽度的情况。
内容的提问来源于stack exchange,提问作者Tuur Vanlerberghe
相关产品推荐
相关产品推荐

