简体   繁体   中英

QImage and openmp when updating image display

In Qt 5.5 for mac, I am trying to speed up the computation the image buffer and its display with QImage. I was using openMP directives but I realised this was messing with the QImage display.

Here is the code:

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

In the code above, nPixels is the total number of pixels in the image and red16 , green16 , and blue16 are the 3 color channel of my images. They have a size equal to nPixels . The values naxis1 and naxis2 are the width and height (in pixels).

Note the pragma directive to parallelise the for loop. When I use it, I get scrambled lines in my image, and any update to the image is changing the results. When I do not use the pragma directive, so that only one thread is used, my image is fine, as expected. I change and update the buffer with such parallelisation, and that mess with the display.

Is there a better way? Like making sure that my threads finished the job and then update the display in my Qt object's paintEvent? Or something related to how the QImage is shared across the threads?...

Thanks

Thanks to the suggestion in the comment, I fixed it. The pragma clause private was needed to define private variables to work with.

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

And yes, it is considerably faster! This is used with some QSlider signal/slots, which perform contrast stretching. I simplified the code here. In fact, range is changing and not fixed and eg red16[ii] is (red16[ii] - minValue) where minValue changes with some QSliders.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM