彩虹编码映射实现:C++与C#

彩虹编码的核心是将灰度值(0-255)映射到彩虹色谱(红→橙→黄→绿→蓝→靛→紫)的RGB值。下面提供两种语言的完整实现代码,并附上详细说明。

🌈 彩虹编码原理

  1. 彩虹色谱:将7种颜色(红、橙、黄、绿、蓝、靛、紫)作为关键点
  2. 映射方式:将灰度值0-255线性映射到彩虹的6个区间
  3. 插值:在相邻颜色点之间进行线性插值

C# 实现代码(WPF/WinForms可用)

cs 复制代码
using System;
using System.Windows.Media;

public static class RainbowColorMapper
{
    // 彩虹色谱的关键颜色点(归一化RGB值,0-1范围)
    private static readonly (float R, float G, float B)[] RainbowColors = new[]
    {
        (1.0f, 0.0f, 0.0f),  // 红
        (1.0f, 0.5f, 0.0f),  // 橙
        (1.0f, 1.0f, 0.0f),  // 黄
        (0.0f, 1.0f, 0.0f),  // 绿
        (0.0f, 0.0f, 1.0f),  // 蓝
        (0.3f, 0.0f, 0.5f),  // 靛
        (0.6f, 0.0f, 0.8f)   // 紫
    };

    /// <summary>
    /// 将灰度值(0-255)转换为彩虹色
    /// </summary>
    public static Color GetRainbowColor(int grayValue)
    {
        // 确保灰度值在0-255范围内
        grayValue = Math.Max(0, Math.Min(255, grayValue));
        
        // 归一化到0-1范围
        float normalized = grayValue / 255.0f;
        
        // 映射到彩虹的6个区间 (0-6)
        float position = normalized * 6.0f;
        
        // 找到两个相邻的颜色点
        int index = (int)Math.Floor(position);
        float fraction = position - index;
        
        // 确保索引在有效范围内
        index = Math.Max(0, Math.Min(5, index));
        
        // 获取两个颜色点
        var color1 = RainbowColors[index];
        var color2 = RainbowColors[index + 1];
        
        // 线性插值
        float r = color1.R + fraction * (color2.R - color1.R);
        float g = color1.G + fraction * (color2.G - color1.G);
        float b = color1.B + fraction * (color2.B - color1.B);
        
        // 转换为0-255的整数值
        return Color.FromRgb(
            (byte)Math.Round(r * 255),
            (byte)Math.Round(g * 255),
            (byte)Math.Round(b * 255)
        );
    }
    
    // 用法示例
    public static void ExampleUsage()
    {
        // 将灰度值128转换为彩虹色
        Color color = GetRainbowColor(128);
        
        // 在WPF中使用
        // var brush = new SolidColorBrush(color);
    }
}

C++ 实现代码(使用SDL2或类似库)

cpp 复制代码
#include <vector>
#include <cstdint>
#include <algorithm>

// 预计算彩虹颜色表(256个值)
std::vector<std::vector<uint8_t>> PrecomputeRainbowTable() {
    // 彩虹色谱的关键颜色点(归一化RGB值,0-1范围)
    const float rainbowColors[7][3] = {
        {1.0f, 0.0f, 0.0f},  // 红
        {1.0f, 0.5f, 0.0f},  // 橙
        {1.0f, 1.0f, 0.0f},  // 黄
        {0.0f, 1.0f, 0.0f},  // 绿
        {0.0f, 0.0f, 1.0f},  // 蓝
        {0.3f, 0.0f, 0.5f},  // 靛
        {0.6f, 0.0f, 0.8f}   // 紫
    };

    std::vector<std::vector<uint8_t>> table(256, std::vector<uint8_t>(3));
    
    for (int i = 0; i < 256; ++i) {
        float normalized = i / 255.0f;
        float position = normalized * 6.0f;
        int index = static_cast<int>(std::floor(position));
        float fraction = position - index;
        
        index = std::max(0, std::min(5, index));
        
        float r1 = rainbowColors[index][0];
        float g1 = rainbowColors[index][1];
        float b1 = rainbowColors[index][2];
        float r2 = rainbowColors[index + 1][0];
        float g2 = rainbowColors[index + 1][1];
        float b2 = rainbowColors[index + 1][2];
        
        float r = r1 + fraction * (r2 - r1);
        float g = g1 + fraction * (g2 - g1);
        float b = b1 + fraction * (b2 - b1);
        
        table[i][0] = static_cast<uint8_t>(std::round(r * 255));
        table[i][1] = static_cast<uint8_t>(std::round(g * 255));
        table[i][2] = static_cast<uint8_t>(std::round(b * 255));
    }
    
    return table;
}

// 使用预计算表进行快速转换
void ConvertToRainbow(const uint8_t* grayData, uint8_t* rainbowData, 
                     int width, int height, 
                     const std::vector<std::vector<uint8_t>>& rainbowTable) {
    
    int totalPixels = width * height;
    for (int i = 0; i < totalPixels; ++i) {
        uint8_t grayValue = grayData[i];
        rainbowData[i * 3 + 0] = rainbowTable[grayValue][0];
        rainbowData[i * 3 + 1] = rainbowTable[grayValue][1];
        rainbowData[i * 3 + 2] = rainbowTable[grayValue][2];
    }
}

代码工作原理详解

  1. 彩虹色谱定义

    • 7种颜色作为关键点(红→紫)
    • 每种颜色用归一化RGB值表示(0.0-1.0)
  2. 映射过程

    • 将灰度值(0-255)归一化为0.0-1.0
    • 乘以6.0,得到0-6的区间值
    • 例如:128 → 0.5 → 0.5*6=3.0
  3. 区间划分

    区间 颜色 说明
    0.0-1.0 红→橙 0.0=红, 1.0=橙
    1.0-2.0 橙→黄 1.0=橙, 2.0=黄
    2.0-3.0 黄→绿 2.0=黄, 3.0=绿
    3.0-4.0 绿→蓝 3.0=绿, 4.0=蓝
    4.0-5.0 蓝→靛 4.0=蓝, 5.0=靛
    5.0-6.0 靛→紫 5.0=靛, 6.0=紫
  4. 插值计算

    • 例如:灰度值128 → 0.5 → 3.0 → 区间3.0(绿→蓝的边界)
    • 但实际计算:0.5*6=3.0 → index=3, fraction=0.0
    • 所以是绿色(0.0, 1.0, 0.0)

📊 彩虹编码测试示例

灰度值 位置 区间 颜色 实际RGB
0 0.0 0.0 (255, 0, 0)
64 0.25 1.5 橙→黄 (255, 128, 0)
128 0.5 3.0 绿 (0, 255, 0)
192 0.75 4.5 蓝→靛 (38, 0, 130)
255 1.0 6.0 (153, 0, 204)

💡 实际应用建议

  1. 医学影像中:通常使用从蓝到红的彩虹编码(冷色→暖色),可以调整颜色点顺序
  2. 性能优化:在实时系统中,可以预先计算好256个颜色值,存储在数组中
  3. 自定义 :根据需要修改rainbowColors数组,实现不同风格的彩虹编码

重要提示 :在医学影像中,彩虹编码的目的是增强人眼辨识度,而不是"覆盖"图像。选择哪种编码方式应基于临床需求,如知识库[5]所述:"在实际应用中,主要根据人眼辨色能力和能否突出显示研究目标来选择合适的3原色组合。"

相关推荐
PfCoder10 小时前
C#中定时器之System.Timers.Timer
c#·.net·visual studio·winform
CSDN_RTKLIB11 小时前
简化版unique_ptr说明其本质
c++
naruto_lnq11 小时前
泛型编程与STL设计思想
开发语言·c++·算法
m0_7487080511 小时前
C++中的观察者模式实战
开发语言·c++·算法
时光找茬12 小时前
【瑞萨AI挑战赛-FPB-RA6E2】+ 从零开始:FPB-RA6E2 开箱测评与 e2 studio 环境配置
c++·单片机·边缘计算
qq_5375626712 小时前
跨语言调用C++接口
开发语言·c++·算法
猷咪12 小时前
C++基础
开发语言·c++
CSDN_RTKLIB12 小时前
WideCharToMultiByte与T2A
c++
星火开发设计13 小时前
类型别名 typedef:让复杂类型更简洁
开发语言·c++·学习·算法·函数·知识
蒹葭玉树13 小时前
【C++上岸】C++常见面试题目--操作系统篇(第二十八期)
linux·c++·面试