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

相关推荐
apocelipes1 天前
常用编程语言和库的正则表达式性能对比
c语言·c++·python·性能优化·golang·开发工具和环境
郝学胜_神的一滴3 天前
CMake 034:生成器表达式:解耦构建时序、精简分支逻辑的终极利器
c++·cmake
hez20103 天前
在 .NET 上构建超大托管数组
c#·.net·.net core·gc·clr
见过夏天3 天前
C++ 基础入门完全指南
c++
用户805533698034 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
BadBadBad__AK5 天前
线段树维护区间 k 次方和
c++·数学·算法·stl
卷无止境5 天前
Eigen 库如何借助 OpenMP 加速计算
c++·后端
卷无止境6 天前
OpenMPI、MPICH 与 OpenMP:关系、核心概念与架构全解
c++·后端
郝学胜_神的一滴6 天前
CMake 30:循环语法全解|foreach_while双循环精讲、迭代技巧与实战避坑指南
c++·cmake
雨落倾城夏未凉8 天前
第四章c#方法-参数数组和可选参数(16)
后端·c#