Python中基于数组值从colormap获取对应RGB索引的方法
Python等价实现方案
你可以直接基于numpy和matplotlib完成和Matlab完全一致的jet色图映射,核心要注意Python数组索引从0开始,Matlab从1开始,不需要像Matlab代码那样给归一化后的索引+1。
核心色值映射代码
以下代码和你给出的Matlab逻辑1:1对齐,输出的RGB值和Matlab运行结果无差异:
import numpy as np from matplotlib import cm # 输入:cvar为存储三角面压力系数的数组,支持list、numpy数组格式 cvar = np.asarray(cvar) # 生成40阶jet色图,转换为0-255范围的8位RGB值,和Matlab jet(40)*255完全对应 cmap = (cm.jet(np.linspace(0, 1, 40)) * 255).astype(np.uint8) cvar_min = cvar.min() cvar_max = cvar.max() if cvar_max == cvar_min: # 所有数值相等时直接取中间色阶,避免除零错误 face_colors = np.tile(cmap[20], (len(cvar), 1)) else: # 归一化到0~39的索引范围(对应40个色阶,适配Python 0起始索引) cvars_map = (cvar - cvar_min) / (cvar_max - cvar_min) * 39 cvars_map = np.round(cvars_map).astype(int) # 截断浮点数计算误差导致的越界索引 cvars_map = np.clip(cvars_map, 0, 39) # 提取每个面对应的RGB值,跳过colormap自带的alpha通道,输出形状为(三角面数, 3) face_colors = cmap[cvars_map, :3]
带面颜色的PLY文件导出
ASCII格式的PLY不需要额外依赖库,直接按格式写入即可,以下是可直接调用的写入函数,适配三角网格:
def write_tri_mesh_ply(save_path, vertices, triangles, face_rgb): """ 写入带三角面颜色的ASCII格式PLY文件 :param save_path: PLY文件保存路径 :param vertices: 顶点数组,形状为(N,3),每一行是x/y/z坐标 :param triangles: 三角面索引数组,形状为(M,3),每一行是三个顶点的序号 :param face_rgb: 三角面颜色数组,形状为(M,3),每一行是0-255范围的R/G/B值 """ with open(save_path, 'w') as f: # 写入PLY文件头 f.write("ply\nformat ascii 1.0\n") f.write(f"element vertex {len(vertices)}\n") f.write("property float x\nproperty float y\nproperty float z\n") f.write(f"element face {len(triangles)}\n") f.write("property list uchar int vertex_indices\n") f.write("property uchar red\nproperty uchar green\nproperty uchar blue\n") f.write("end_header\n") # 写入顶点坐标 for x, y, z in vertices: f.write(f"{x:.6f} {y:.6f} {z:.6f}\n") # 写入三角面索引和对应颜色 for (v1, v2, v3), (r, g, b) in zip(triangles, face_rgb): f.write(f"3 {v1} {v2} {v3} {r} {g} {b}\n")
调用时直接传入顶点、三角面索引、前面生成的face_colors即可导出符合要求的PLY文件,支持MeshLab、Blender等常见三维软件直接打开识别面颜色。
注意事项
- matplotlib自带的jet色卡实现和Matlab原生jet色值完全对齐,不会出现色差
- 加索引截断是为了避免浮点数精度问题导致的索引越界(比如最大值计算后得到39.0000000002,四舍五入后变为40超出数组范围)
- 如果需要连续色映射而非40阶离散色,去掉离散色卡生成、索引取整的步骤,直接用归一化后的数值调用
cm.jet即可:cvar_norm = (cvar - cvar_min)/(cvar_max - cvar_min) face_colors = (cm.jet(cvar_norm)[:, :3]*255).astype(np.uint8)
内容的提问来源于stack exchange,提问作者DrProtocol
相关产品推荐
相关产品推荐

