彩虹编码映射实现: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原色组合。"

相关推荐
WW_千谷山4_sch12 分钟前
MYOJ_10599:CSP初赛题单10:计算机网络
c++·计算机网络·算法
梵尔纳多1 小时前
绘制一个矩形
c++·图形渲染·opengl
橘颂TA1 小时前
【剑斩OFFER】算法的暴力美学——leetCode 946 题:验证栈序列
c++·算法·leetcode·职场和发展·结构与算法
闻缺陷则喜何志丹1 小时前
【状态机动态规划】3686. 稳定子序列的数量|1969
c++·算法·动态规划·力扣·状态机动态规划
liulilittle1 小时前
OPENPPP2 网络驱动模式
开发语言·网络·c++·网络协议·信息与通信·通信
mjhcsp1 小时前
C++ AC 自动机:原理、实现与应用全解析
java·开发语言·c++·ac 自动机
爱吃生蚝的于勒1 小时前
【Linux】进程间通信之匿名管道
linux·运维·服务器·c语言·数据结构·c++·vim
为自己_带盐1 小时前
在 Blazor Server 中集成 docx-preview.js 实现高保真 Word 预览
javascript·c#·word
wanderist.2 小时前
C++输入输出的一些问题
开发语言·c++·图论