QGradient椭圆混合

时间:2012-12-22 09:35:54

标签: qt qpainter

我目前正致力于使用QPainter和QImage生成“热图”。我的方法包括绘制多个圆圈,黑色到透明的QRadialGradients作为QBrush(参见“强度图”)。然后我将渐变映射应用于强度贴图以获得所需的“热图”效果(请参阅“渐变映射后”)。

我在“After Gradient Map”图像中更明显的问题是圆圈没有正确混合。圆圈重叠的地方似乎部分混合,但是朝向边缘,您可以清楚地看到圆圈的终点(几乎是外部发光)。我想要一个效果,它在圆圈和正确混合之间没有可见的边框。

强度地图

Intensity Map

渐变映射(不同强度图)

After Gradient Map

代码

// 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。我还尝试使圆圈比径向渐变大得多,因此无法切除渐变或将边框应用于圆的外部。

有什么想法吗?谢谢!

2 个答案:

答案 0 :(得分:5)

我认为这是一种机械条带形式,这是一种视错觉,其中视觉系统增强了亮度的变化,导致图像中实际不存在的明亮或暗带的出现。通常这些是在两个不同区域之间的边界上看到的,但在这种情况下,我认为这是观察到的梯度的明显不连续性。

以下是一些展示此问题的图片:

第一张图像是用软件计算的,由三个圆圈组成,每个圆圈用径向线性渐变绘制。在圆圈之间的重叠边缘应该可以看到马赫效应,因为这些是渐变急剧变化的点。

Grayscale, banded

第二个图像完全相同的计算,但不是沿半径线性,而是将梯度映射到曲线(我使用了第一个hermite基函数)。乐队几乎完全消失了:

Grayscale, smooth

至于为什么这会更多地影响着色图像,我不确定是这样。我认为在上面的情况中,也许有一些额外的条带由色彩有效地作为调色板查找引起,导致额外的条带。

我在本地执行了大致相同的颜色,也简单地映射了调色板,效果类似:

enter image description here enter image description here

使用QT的线性渐变来修复这个问题可能并不重要(您可以尝试在渐变中添加更多控制点,但是您必须添加相当多的...),但是在软件中计算这样的图像并不难。您还可以考虑其他一些后期处理效果,例如添加模糊和/或添加噪点。任何打破梯度不连续性的事情都可能有所帮助。

答案 1 :(得分:0)

我同意JasonD。

此外,请记住,Qt正在sRGB色彩空间中进行线性混合,这不是线性的(它应用了伽玛2.2)。

要做到这一点,你需要在线性光下进行混合或插值,然后转换为sRGB(应用伽玛)进行显示。