C++ 如何创建颜色栏(电视测试图案)

C++ 如何创建颜色栏(电视测试图案),c++,c,rgb,C++,C,Rgb,我需要创建一个像这样的颜色条 我使用0到1之间的浮动的缩放数组 现在我想从这个浮点数计算RGB颜色。怎么做?想用C/C++编写它,所以我想我需要两个函数 第一个函数使用一个参数(如步长)构建colorbar,第二个函数需要该值,并且必须只返回colorbar的数组索引 我在google上找不到它,所以请帮助我。RGB使用字节,所以假设您的浮点数组类似 float scaledColor[3]; // 0 = R, etc., all 0.0 < scaledColor[x] < 1.

我需要创建一个像这样的颜色条 我使用0到1之间的浮动的缩放数组

现在我想从这个浮点数计算RGB颜色。怎么做?想用C/C++编写它,所以我想我需要两个函数

第一个函数使用一个参数(如步长)构建colorbar,第二个函数需要该值,并且必须只返回colorbar的数组索引


我在google上找不到它,所以请帮助我。

RGB使用字节,所以假设您的浮点数组类似

float scaledColor[3]; // 0 = R, etc., all 0.0 < scaledColor[x] < 1.0

当然,这只在浮点中的值确实在0.0到1.0之间时才起作用。

RGB使用字节,因此假设浮点数组类似于

float scaledColor[3]; // 0 = R, etc., all 0.0 < scaledColor[x] < 1.0
当然,这只有在浮动中的值确实在0.0到1.0之间时才起作用。

最简单的解决方案:

const unsigned char* getColour(float x) /* 0 <= x < 1 */
{
    static const unsigned char bar[][3] = {
        {255,255,255},
        {255,255,0},
        // ... fill in all the colours ...
        {0,0,0}
    };
    return bar[(int)(x*sizeof(bar))];
}
然后,您可以使用它生成任意宽度的条形图。

最简单的解决方案:

const unsigned char* getColour(float x) /* 0 <= x < 1 */
{
    static const unsigned char bar[][3] = {
        {255,255,255},
        {255,255,0},
        // ... fill in all the colours ...
        {0,0,0}
    };
    return bar[(int)(x*sizeof(bar))];
}

然后,您可以使用它生成任意宽度的条。

我的google fu显示,您需要SMPTE颜色条图案的上三分之一。 维基百科说:

从左到右依次为灰色、黄色、青色、绿色、, 品红色、红色和蓝色


因此,最简单的方法是只需硬编码相应的RGB颜色代码(如果您只需要它们)。这篇文章还提到了如何生成这些颜色,但这似乎要困难得多,不值得为七种颜色付出努力。

我的google fu发现,您需要SMPTE颜色条图案的上三分之一。 维基百科说:

从左到右依次为灰色、黄色、青色、绿色、, 品红色、红色和蓝色


因此,最简单的方法是只需硬编码相应的RGB颜色代码(如果您只需要它们)。这篇文章还提到了如何生成这些颜色,但这似乎要困难得多,不值得为七种颜色付出努力。

这里您指的是以标准机构欧洲广播联盟命名的100%EBU颜色条。这与完整的SMPTE RP 219-2002颜色条不同,后者具有其他功能,包括渐变和Plug图片线生成设备,如维基百科上的文章所述

EBU颜色条由8个宽度相等的垂直条组成。对于SD和HD格式,它们的定义方式相同。在RGB颜色空间中,它们以不同的速率交替每个红色、绿色和蓝色通道,就像从0到100%强度的二进制计数一样。以从左到右的标准化RGB形式从白色开始倒计时:

1,1,1:白色 1,1,0:黄色 0,1,1:青色 0,1,0:绿色 1,0,1:洋红色 1,0,0:红色 0,0,1:蓝色 0,0,0:黑色 所以蓝色通道在每一列中交替出现,红色通道在两列之后,绿色通道在四列之后。这种排列具有有用的特性,即YCb'Cr'颜色空间中的亮度Y导致向下步进的绘图

要使用桌面系统中最常见的8位RGB进行渲染,只需将上述值乘以255即可。根据白色列的强度,EBU条分为75%和100%两种。SMPTE颜色条通常使用75%的级别作为参考

下面是一些简单的C代码,用于生成100%EBU颜色条并将结果保存为PGM文件:

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>

// PAL dimensions
static const unsigned kWidth = 720;
static const unsigned kHeight = 576;

typedef struct
{
    uint8_t     r;
    uint8_t     g;
    uint8_t     b;
} RGB;

int main(int argc, char* argv[])
{
    const RGB BAR_COLOUR[8] =
    {
        { 255, 255, 255 },  // 100% White
        { 255, 255,   0 },  // Yellow
        {   0, 255, 255 },  // Cyan
        {   0, 255,   0 },  // Green
        { 255,   0, 255 },  // Magenta
        { 255,   0,   0 },  // Red
        {   0,   0, 255 },  // Blue
        {   0,   0,   0 },  // Black
    };

    // Allocate frame buffer
    size_t      frameBytes = kWidth*kHeight*sizeof(RGB);
    RGB*        frame = malloc(frameBytes);
    unsigned    columnWidth = kWidth / 8;

    // Generate complete frame
    for (unsigned y = 0; y < kHeight; y++)
    {
        for (unsigned x = 0; x < kWidth; x++)
        {
            unsigned col_idx = x / columnWidth;
            frame[y*kWidth+x] = BAR_COLOUR[col_idx];
        }
    }

    // Save as PPM
    FILE* fout = fopen("ebu_bars.ppm", "wb");
    fprintf(fout, "P6\n%u %u\n255\n", kWidth, kHeight);
    fwrite(frame, frameBytes, 1, fout);
    fclose(fout);

    free(frame);

    return 0;
}
这应该很容易适应任何其他语言。可能不需要使用float,除非您在GPU上实现它,在这种情况下,算法会非常不同。这里有很大的优化空间;编写代码是为了清晰,而不是为了速度

请注意,虽然可以在计算机中生成颜色条的完美数字表示,但这对于广播来说并不安全。完美颜色条之间的过渡需要无限高的带宽才能准确表示。因此,如果测试图像是通过模拟广播设备传输的,它的带宽必须受到低通滤波器的限制,例如PAL为~4.3MHz。这就是为什么你会注意到每列之间的模糊边界;这些包含纯颜色之间的中间值


还请注意,不可能在RGB颜色空间中准确表示SMPTE颜色条。这是因为在YCb'Cr'颜色空间中指定了某些临界值,特别是在RGB色域SD或HD之外的PLUGE区域。您可以创建一些近似值的东西,例如深蓝色,但它们不正确。因此,除非您用YCb'Cr'表示测试帧,否则请仅使用上面2/3的EBU色条。

这里您指的是以标准机构欧洲广播联盟命名的100%EBU色条。这与完整的SMPTE RP 219-2002颜色条不同,后者具有其他功能,包括渐变和Plug图片线生成设备,如维基百科上的文章所述

T EBU颜色条由8条宽度相等的垂直条组成。对于SD和HD格式,它们的定义方式相同。在RGB颜色空间中,它们以不同的速率交替每个红色、绿色和蓝色通道,就像从0到100%强度的二进制计数一样。以从左到右的标准化RGB形式从白色开始倒计时:

1,1,1:白色 1,1,0:黄色 0,1,1:青色 0,1,0:绿色 1,0,1:洋红色 1,0,0:红色 0,0,1:蓝色 0,0,0:黑色 所以蓝色通道在每一列中交替出现,红色通道在两列之后,绿色通道在四列之后。这种排列具有有用的特性,即YCb'Cr'颜色空间中的亮度Y导致向下步进的绘图

要使用桌面系统中最常见的8位RGB进行渲染,只需将上述值乘以255即可。根据白色列的强度,EBU条分为75%和100%两种。SMPTE颜色条通常使用75%的级别作为参考

下面是一些简单的C代码,用于生成100%EBU颜色条并将结果保存为PGM文件:

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>

// PAL dimensions
static const unsigned kWidth = 720;
static const unsigned kHeight = 576;

typedef struct
{
    uint8_t     r;
    uint8_t     g;
    uint8_t     b;
} RGB;

int main(int argc, char* argv[])
{
    const RGB BAR_COLOUR[8] =
    {
        { 255, 255, 255 },  // 100% White
        { 255, 255,   0 },  // Yellow
        {   0, 255, 255 },  // Cyan
        {   0, 255,   0 },  // Green
        { 255,   0, 255 },  // Magenta
        { 255,   0,   0 },  // Red
        {   0,   0, 255 },  // Blue
        {   0,   0,   0 },  // Black
    };

    // Allocate frame buffer
    size_t      frameBytes = kWidth*kHeight*sizeof(RGB);
    RGB*        frame = malloc(frameBytes);
    unsigned    columnWidth = kWidth / 8;

    // Generate complete frame
    for (unsigned y = 0; y < kHeight; y++)
    {
        for (unsigned x = 0; x < kWidth; x++)
        {
            unsigned col_idx = x / columnWidth;
            frame[y*kWidth+x] = BAR_COLOUR[col_idx];
        }
    }

    // Save as PPM
    FILE* fout = fopen("ebu_bars.ppm", "wb");
    fprintf(fout, "P6\n%u %u\n255\n", kWidth, kHeight);
    fwrite(frame, frameBytes, 1, fout);
    fclose(fout);

    free(frame);

    return 0;
}
这应该很容易适应任何其他语言。可能不需要使用float,除非您在GPU上实现它,在这种情况下,算法会非常不同。这里有很大的优化空间;编写代码是为了清晰,而不是为了速度

请注意,虽然可以在计算机中生成颜色条的完美数字表示,但这对于广播来说并不安全。完美颜色条之间的过渡需要无限高的带宽才能准确表示。因此,如果测试图像是通过模拟广播设备传输的,它的带宽必须受到低通滤波器的限制,例如PAL为~4.3MHz。这就是为什么你会注意到每列之间的模糊边界;这些包含纯颜色之间的中间值


还请注意,不可能在RGB颜色空间中准确表示SMPTE颜色条。这是因为在YCb'Cr'颜色空间中指定了某些临界值,特别是在RGB色域SD或HD之外的PLUGE区域。您可以创建一些近似值的东西,例如深蓝色,但它们不正确。因此,除非您用YCb'Cr'表示测试帧,否则请仅使用EBU条的上2/3。

到目前为止,您已经完成了哪些工作?考虑使用255 255 0,将我的浮点从0到255进行缩放,并将其用作RG,b每次为0。。但是这个suxxx你的阵列现在看起来怎么样?这些值究竟代表什么?你知道RGB颜色是如何工作的吗?你到底需要什么帮助?你需要知道如何画东西吗?或者仅仅是什么?浮点数和rgb通常是不相关的。你想用哪种算法从一个转换到另一个?@Raiv这是个问题,我只是有一个浮点数,必须把它转换成rgb。witch和how不重要,我只需要它:D我需要帮助将浮点转换为rgb颜色。到目前为止,您已经完成了哪些工作?考虑只使用255 255 0,将我的浮点从0到255进行缩放,并将其用作RG,b每次为0。。但是这个suxxx你的阵列现在看起来怎么样?这些值究竟代表什么?你知道RGB颜色是如何工作的吗?你到底需要什么帮助?你需要知道如何画东西吗?或者仅仅是什么?浮点数和rgb通常是不相关的。你想用哪种算法从一个转换到另一个?@Raiv这是个问题,我只是有一个浮点数,必须把它转换成rgb。witch和how不重要,我只需要它:D我需要帮助将浮点转换为rgb颜色作为一名20年的专业广播老手,这是一个关于什么是EBU颜色条,如何创建它们,以及为什么在rgb颜色空间中使用SMPTE颜色条不起作用的难以置信的完整而优秀的答案。非常好@这就是为什么谢谢你不久前我不得不自己解决这个问题,我发现网上有太多的资料不完整、不准确或误导。所以我希望能提供一个彻底的解释,让未来的开发者很容易找到。我甚至没有尝试覆盖不同的颜色空间。。。正如你所知道的,这东西很难做对!作为专业广播20年的老手,这是一个令人难以置信的完整和优秀的答案,关于什么是EBU颜色条,如何创建它们,以及为什么在RGB颜色空间中使用SMPTE颜色条不起作用。非常好@这就是为什么谢谢你不久前我不得不自己解决这个问题,我发现网上有太多的资料不完整、不准确或误导。所以我希望能提供一个彻底的解释,让未来的开发者很容易找到。我甚至没有尝试覆盖不同的颜色空间。。。正如你所知道的,这东西很难做对!