【问题标题】:QImage and openmp when updating image display更新图像显示时的QImage和openmp
【发布时间】:2015-10-15 15:21:59
【问题描述】:

在 Qt 5.5 for mac 中,我试图加快计算图像缓冲区及其使用 QImage 的显示。我使用的是 openMP 指令,但我意识到这会干扰 QImage 显示。

代码如下:

int = 65535    
newPaintImage = new QImage(naxis1, naxis2, QImage::Format_ARGB32 );
#pragma omp parallel for
for ( int ii = 0; ii < nPixels; ++ii )
{
    cred = (int) 255 * red16[ii] / range;
    cgreen = (int) 255 * green16[ii] / range;
    cblue = (int) 255 * blue16[ii] / range;     

    QRgb argb = qRgba( cred, cgreen, cblue, 255);
    QRgb* rowData = (QRgb*) newPaintImage->scanLine(ii/naxis1);
    rowData[ii%naxis1] = argb;
}
newPaintWidget = new PaintWidget(newPaintImage, naxis1, naxis2);

在上面的代码中,nPixels 是图像中的像素总数,red16green16blue16 是我的图像的 3 色通道。它们的大小等于nPixelsnaxis1naxis2 的值是宽度和高度(以像素为单位)。

注意用于并行化 for 循环的 pragma 指令。当我使用它时,我的图像中出现乱线,并且对图像的任何更新都会改变结果。 当我不使用 pragma 指令时,只使用一个线程,我的图像很好,正如预期的那样。 我用这种并行化来更改和更新缓冲区,这会弄乱显示。

有没有更好的方法?就像确保我的线程完成工作然后更新我的 Qt 对象的paintEvent 中的显示?或者与如何跨线程共享 QImage 相关的东西?...

谢谢

【问题讨论】:

  • 尝试将private(cred, cgreen, cblue) 添加到您的 OpenMP 编译指示中。不确定它是否足够,但绝对需要。
  • 读得越多,我就越有信心#pragma omp parallel for private(cred, cgreen, cblue)应该足以让您的代码并行工作。但不确定它会更快,因为您的代码主要受内存限制。
  • @gilles 好的,我刚刚用#pragma omp parallel for private(cred, cgreen, cblue) 尝试过,但出现编译错误:error: expected variable name #pragma omp parallel for private(cred, cgreen, cblue) 我完全不知道这些指令。有什么想法吗?
  • @gilles 成功了! cred、cgreen、cblue 是类私有的。所以指令需要这个:int cred2, cgreen2, cblue2; #pragma omp parallel for private(cred2, cgreen2, cblue2) 我正在发布更正的代码。谢谢你的帮助!真快!!

标签: c++ multithreading qt openmp qimage


【解决方案1】:

感谢评论中的建议,我修复了它。需要使用 pragma 子句 private 来定义要使用的私有变量。

int cred2, cgreen2, cblue2   
#pragma omp parallel for private(cred2, cgreen2, cblue2)
for ( int ii = 0; ii < nPixels; ++ii )
{
    cred2 = (int) 255 * red16[ii] / range;
    cgreen2 = (int) 255 * green16[ii] / range;
    cblue2 = (int) 255 * blue16[ii] / range;
    QRgb argb = qRgba( cred2, cgreen2, cblue2, 255);
    QRgb* rowData = (QRgb*) newPaintImage->scanLine(ii/naxis1);
    rowData[ii%naxis1] = argb;
}
newPaintWidget = new PaintWidget(newPaintImage, naxis1, naxis2);

是的,它的速度要快得多!这与一些执行对比度拉伸的 QSlider 信号/插槽一起使用。我在这里简化了代码。事实上,range 正在变化而不是固定,例如red16[ii](red16[ii] - minValue),其中 minValue 会随着一些 QSlider 的变化而变化。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-09
    • 1970-01-01
    • 1970-01-01
    • 2021-11-12
    • 1970-01-01
    相关资源
    最近更新 更多