Как создать цветную полосу (тестовый шаблон ТВ) - PullRequest
1 голос
/ 04 августа 2011

Мне нужно создать цветную полосу, такую ​​как ЭТО Я использую масштабированный массив с плавающей точкой от 0 до 1.

Теперь я хочу вычислить цвет RGB из этого числа. Как это сделать? Хочу написать это на C / c ++, поэтому я думаю, что мне нужно 2 функции.

Первая функция для построения цветовой панели с одним параметром, например STEPSIZE, и вторая функция должны иметь значение и должны просто возвращать индекс массива цветовой панели.

Я не смог найти его в Google, поэтому, пожалуйста, помогите мне.

Ответы [ 4 ]

6 голосов
/ 16 июля 2013

То, на что вы ссылаетесь, - это цветные полоски EBU 100% (названные в честь органа по стандартизации Европейского вещательного союза).Это не то же самое, что полные цветные полосы SMPTE RP 219-2002, которые имеют другие функции, включая градиенты и PLUGE (оборудование для создания линейных рисунков), описанные в статье Википедии о Цветные полосы .

Цветные полосы 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: черный

Таким образом, синий канал чередует каждый столбец, красный канал после двух столбцов и зеленыйпосле четырех столбцов.Это расположение имеет полезное свойство, заключающееся в том, что яркость (Y в цветовом пространстве YCb'Cr ') приводит к пошаговому графику.

Для визуализации с использованием 8-битного RGB (чаще всего встречается в настольных системах), просто умножьтевышеупомянутые значения на 255. Бары EBU бывают в 75% и 100% вариантах, в зависимости от интенсивности белого столбца.Цветные полосы SMPTE обычно используют уровни 75% в качестве эталона.

Вот простой код C для генерации цветных полос EBU 100% и сохранения результата в виде файла 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 (в этом случае алгоритм будет совсем другим).Здесь есть много возможностей для оптимизации;код написан для ясности, а не для скорости.

Обратите внимание, что, хотя в компьютере можно создать идеальное цифровое представление цветовых полос, это не будет безопасно для трансляции.Переходы между «идеальными» цветными полосами потребуют бесконечно высокой полосы пропускания для точного представления.Поэтому, если тестовое изображение должно передаваться через аналоговое вещательное оборудование, оно должно быть ограничено по полосе пропускания фильтром нижних частот (например, ~ 4,3 МГц для PAL).Вот почему вы замечаете «нечеткие» границы между каждым столбцом;они содержат промежуточные значения между чистыми цветами.

Также обратите внимание, что не позволяет точно представлять цветные полосы SMPTE в цветовом пространстве RGB.Это связано с тем, что определенные критические значения указаны в цветовом пространстве YCb'Cr '(особенно в области PLUGE), которые находятся за пределами гаммы RGB (SD или HD).Вы можете создать что-то, что приближает значения (например, очень темно-синий), но они не правильны.Поэтому, если вы не представляете тестовый фрейм в YCb'Cr ', придерживайтесь только столбцов EBU (верхние 2/3).

0 голосов
/ 04 августа 2011

Самое простое решение:

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))];
}

Затем вы можете использовать его для создания баров любой ширины.

0 голосов
/ 04 августа 2011

Мой гугл-фу обнаружил, что вы хотите верхнюю треть рисунка цветовой полосы SMPTE.Википедия говорит:

По порядку слева направо, цвета серый, желтый, голубой, зеленый, пурпурный, красный и синий.просто жестко закодировать соответствующие цветовые коды RGB, если они вам нужны.В статье также упоминается, как можно генерировать эти цвета, но это кажется намного сложнее и не стоит усилий для семи цветов.

0 голосов
/ 04 августа 2011

RGB использует байты, поэтому, предполагая, что ваш массив с плавающей запятой что-то вроде

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

, вы можете сделать:

unsigned char r = (unsigned char)(255 * scaledColor[0]);
unsigned char g = (unsigned char)(255 * scaledColor[1]);
unsigned char b = (unsigned char)(255 * scaledColor[2]);

Это, конечно, будет работать, только если значения вПоплавки действительно находятся в диапазоне от 0.0 до 1.0.

...