Смешение эллипса QGradient

В настоящее время я работаю над созданием «тепловых карт» с помощью QPainter и QImage. Мой метод состоит в рисовании нескольких кругов черными и прозрачными QRadialGradients в качестве QBrush (см. «Карта интенсивности»). Затем я применяю карту градиента к карте интенсивности, чтобы получить желаемый эффект «тепловой карты» (см. «После карты градиента»).

Проблема, с которой я сталкиваюсь, которая более очевидна на изображении «После карты градиента», заключается в том, что круги не смешиваются правильно. Там, где круги перекрываются, кажется, что они частично сливаются, но ближе к краям вы можете ясно видеть, где круги заканчиваются (почти внешнее свечение). Я хотел бы, чтобы эффект не имел видимых границ между кругами и правильно смешивался.

Карта интенсивности

Карта интенсивности

После карты градиента (карта другой интенсивности)

После карты градиента

Код

// Setup QImage and QPainter
QImage *map = new QImage(500, 500, QImage::Format_ARGB32);
map->fill(QColor(255, 255, 255, 255));
QPainter paint(map);
paint.setRenderHint(QPainter::HighQualityAntialiasing);

// Create Intensity map
std::vector<int> record = disp_data[idx]; // Data
for(int j = 1, c = record.size(); j < c; ++j) {
    int dm = 150 + record[j] * 100 / 255; // Vary the diameter

    QPen g_pen(QColor(0, 0, 0, 0));
    g_pen.setWidth(0);
    QRadialGradient grad(sensors[j-1].x, sensors[j-1].y, dm/2); // Create Gradient
    grad.setColorAt(0, QColor(0, 0, 0, record[j])); // Black, varying alpha
    grad.setColorAt(1, QColor(0, 0, 0, 0)); // Black, completely transparent
    QBrush g_brush(grad); // Gradient QBrush
    paint.setPen(g_pen);
    paint.setBrush(g_brush);
    paint.drawEllipse(sensors[j-1].x-dm/2, sensors[j-1].y-dm/2, dm, dm); // Draw circle
}

// Convert to heat map
for(int i = 0; i < 500; ++i) {
    for(int j = 0; j < 500; ++j) {
        int b = qGray(map->pixel(i, j));
        map->setPixel(i, j, grad_map->pixel(b, 0)); //grad_map is a QImage gradient map
    }
}

Как видите, для кругов нет QPen. Я пробовал различные режимы наложения, но безуспешно. Я также изменил подсказку рендеринга на HighQualityAntialiasing. Я также попытался сделать круги намного больше, чем радиальный градиент, поэтому градиент не может быть обрезан или граница применяется к внешней стороне круга.

Любые идеи? Спасибо!


person ranger_rick    schedule 22.12.2012    source источник
comment
Вы уверены, что видите то, что думаете? Мне кажется, это махбандинг.   -  person JasonD    schedule 22.12.2012
comment
@JasonD: Я почти уверен, что да... Я уходил от этого руководство, у которого может быть похожая проблема? Вот пример, который я сделал в фотошопе, у которого нет проблемы.   -  person ranger_rick    schedule 22.12.2012
comment
Являются ли ваши градиенты фотошопа линейными?   -  person JasonD    schedule 22.12.2012
comment
@JasonD: Да, градиенты линейные. Тем не менее, я могу видеть, откуда вы пришли с полосами Маха, но проблема кажется гораздо более очевидной, когда я применяю карту градиента.   -  person ranger_rick    schedule 22.12.2012


Ответы (2)


Я думаю, что это форма полос Маха, представляющая собой оптическую иллюзию, когда зрительная система усиливает изменения яркости, вызывая появление ярких или темных полос, которых на самом деле нет на изображении. Обычно они видны на границе между двумя отдельными областями, но в данном случае я полагаю, что это резкий разрыв в наблюдаемых градиентах.

Вот несколько изображений, демонстрирующих проблему:

Это первое изображение рассчитывается в программе и состоит из трех кругов, каждый из которых нарисован с радиальным линейным градиентом. Эффекты полосы Маха должны быть видны на краях перекрытия между кругами, так как это точки, где градиент резко меняется.

Оттенки серого, полосы

Это второе изображение представляет собой точно такой же расчет, но вместо того, чтобы быть линейным по радиусу, градиент отображается в виде кривой (я использовал первую базисную функцию Эрмита). Полосы должны были почти полностью исчезнуть:

Оттенки серого, плавный

Что касается того, почему это больше влияет на цветное изображение, я не уверен, что это так. Я думаю, что в приведенном выше случае, возможно, есть дополнительные полосы, вызванные раскрашиванием, фактически являющимся поиском палитры, что приводит к дополнительным полосам.

Я выполнил примерно такое же раскрашивание локально, также просто сопоставив палитру, и эффект аналогичен:

введите здесь описание изображениявведите здесь описание изображения

Исправление этого с помощью линейных градиентов QT, вероятно, нетривиально (вы можете попробовать добавить гораздо больше контрольных точек в градиент, но вам придется добавить довольно много...), но вычислить такое изображение в программном обеспечении несложно. . Вы также можете рассмотреть некоторые другие эффекты постобработки, такие как добавление размытия и/или добавления шума. Все, что нарушает разрыв в градиенте, скорее всего, поможет.

person JasonD    schedule 22.12.2012
comment
Спасибо за идеи, буду дальше разбираться. - person ranger_rick; 23.12.2012
comment
В итоге я выбрал что-то похожее на распределение Гаусса для контрольных точек, что дало результаты, аналогичные тому, что вы опубликовали. Еще раз спасибо! - person ranger_rick; 23.12.2012

Я согласен с JasonD.

Кроме того, имейте в виду, что Qt выполняет линейное смешивание в цветовом пространстве sRGB, которое не является линейным (применяется гамма 2.2).

Чтобы сделать это правильно, вам нужно выполнить смешивание или интерполяцию в линейном свете, а затем преобразовать в sRGB (применить гамму) для отображения.

person Dithermaster    schedule 22.12.2012