求将像素颜色转换为含油饱和度(0-1或0-100%)的算法
像素颜色转含油饱和度的算法方案
你提供的含油饱和度构造图如下:

之前用亮度公式(0.299R+0.587G+0.144B)得不到合理结果,是因为这类专业地质可视化图的颜色编码是自定义色标映射,和通用亮度逻辑无关,正确的解法需要基于图中的色条(Color Bar)来建立映射关系,具体步骤如下:
1. 提取色标映射基准点
- 找到图中的色条(通常在图像边缘,带有数值刻度),选取至少3个有明确数值对应的颜色点,比如色条的最小值端、最大值端,以及中间1-2个刻度点。
- 用图像工具(如Photoshop、GIMP、在线取色器)提取每个点的精确RGB值,同时记录对应的含油饱和度数值(0-100%或0-1)。
2. 建立颜色-饱和度映射模型
根据色条的渐变类型选择合适的映射方式:
- 线性渐变色条:直接用线性插值。假设已知两个基准点
(R1,G1,B1) → S1和(R2,G2,B2) → S2,对于任意像素的RGB值,先计算其在RGB色彩空间中与两个基准点的距离,找到所属区间后,通过线性比例计算对应的饱和度值。 - 非线性渐变色条:选取更多基准点,用多项式拟合或分段插值的方式构建映射函数,确保拟合结果和色条的渐变趋势一致。
- 更高效的方式是将RGB转换到HSV色彩空间,这类图通常用色相(H)通道区分数值,直接对H通道做线性/非线性映射即可。
3. 批量转换实现示例(Python)
import cv2 import numpy as np # 示例:从色条提取的映射点(需替换成你图中的实际值) color_sat_pairs = [ (255, 255, 255, 0), # 白色 → 0% 饱和度 (180, 180, 255, 25), # 浅蓝 → 25% (0, 0, 255, 50), # 蓝色 → 50% (255, 0, 0, 100) # 红色 → 100% ] def get_saturation(r, g, b): # 计算当前像素与所有基准点的色彩距离 dists = [] for cr, cg, cb, sat in color_sat_pairs: # 欧氏距离衡量色彩相似度 dist = np.sqrt((r-cr)**2 + (g-cg)**2 + (b-cb)**2) dists.append((dist, sat)) # 取最近的两个基准点做线性插值 dists.sort() d1, s1 = dists[0] d2, s2 = dists[1] if d1 + d2 == 0: return s1 # 插值计算最终饱和度 return s1 + (s2 - s1) * (d1 / (d1 + d2)) # 读取并处理图像 img = cv2.imread("your_map_image.png") img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) height, width = img.shape[:2] # 生成饱和度映射图 saturation_map = np.zeros((height, width), dtype=np.float32) for y in range(height): for x in range(width): r, g, b = img_rgb[y, x] saturation_map[y, x] = get_saturation(r, g, b) # 输出结果(可保存为灰度图或数值文件) cv2.imwrite("saturation_gray.png", saturation_map)
关键注意事项
- 绝对不能依赖通用亮度公式,这类专业图的颜色编码是业务自定义的,和亮度无直接关联。
- 基准点的选取要覆盖色条的全范围,数值对应必须准确,否则映射结果会出现偏差。
- 如果色条有模糊或像素偏差,可对色条区域取平均RGB值来提高精度。
内容的提问来源于stack exchange,提问作者Aramu5ha
相关产品推荐
相关产品推荐

