0

I'm working on a C++ code for image manipulation that works pixel-by-pixel (using Magick++), and I want to use it with OpenMP, but I have the next issue:

Magick: Semaphore operation failed (unable to destroy semaphore) [Dispositivo o recurso ocupado].
img_test: magick/pixel_cache.c:2765: ModifyCache: La declaración `image->cache != (Cache) ((void *)0)' no se cumple.

And, also, it keeps stuck in an infinite loop.

Here is the code snippet:

int main(int argc,char **argv)
{
    InitializeMagick(*argv);

    Image img1, img2;
    img1.read(argv[1]);
    img2.read(argv[2]);

    int sx = img1.columns();
    int sy = img1.rows();
    Image out;
    out.size(Geometry(sx,sy));

    cout << "Processing pictures..." << endl;

    int iy;
    #pragma omp for private(iy)
    for (iy=0;iy<sy;iy++)
    {
        #pragma omp parallel for
        for (int ix=0;ix<sx;ix++)
        {
            double _r = 0.0, _g = 0.0, _b = 0.0;

            ColorRGB ppix1(img1.pixelColor(ix,iy));
            ColorRGB ppix2(img2.pixelColor(ix,iy));

            // do some image processing...

            ColorRGB opix(_r*MaxRGB,_g*MaxRGB,_b*MaxRGB);
            out.pixelColor(ix,iy,opix);
        }
    }
    out.write("Output.png");
}

Is there a way to solve this?

2
  • 1
    You don't want two parallel regions. Simply parallelizing over iy will give you your desired parallelization. Which line is your error occurring at? What is line 2765? Commented Mar 21, 2016 at 18:18
  • I don't believe the pixel cache will be able to load in parallel. Commented Mar 22, 2016 at 2:04

1 Answer 1

1

Is there a way to solve this?

For this example, you would want to use schedule ordered.

cout << "Processing pictures..." << endl;

int iy;
#pragma omp for schedule(static) ordered
for (iy=0;iy<sy;iy++)
{
#pragma omp ordered
    for (int ix=0;ix<sx;ix++)
    {
        double _r = 0.0, _g = 0.0, _b = 0.0;

        ColorRGB ppix1(img1.pixelColor(ix,iy));
        ColorRGB ppix2(img2.pixelColor(ix,iy));

        // do some image processing...

        ColorRGB opix(_r*MaxRGB,_g*MaxRGB,_b*MaxRGB);
        out.pixelColor(ix,iy,opix);
    }
}
out.write("Output.png");

Edit

If you do want to work with low-level pixel information across parallel, @NoseKnowsAll is correct for a single region of iy. However you'll run into issues calling out.pixelColor as the internal cache may fall out of sync. I would suggest export the pixels data, perform work in parallel, and import the final results.

// Allocate three buffers the total size of x * y * RGB
double * buffer1 = new double[sx * sy * 3];
double * buffer2 = new double[sx * sy * 3];
double * buffer3 = new double[sx * sy * 3];

// Write pixel data to first two buffers
img1.write(0,0, sx, sy, "RGB", DoublePixel, buffer1);
img2.write(0,0, sx, sy, "RGB", DoublePixel, buffer2);

cout << "Processing pictures..." << endl;

int iy;
#pragma omp parallel for
for (iy=0;iy<sy;iy++)
{
    for (int ix=0;ix<sx;ix++)
    {
        // Find where in buffer the current pixel is located at
        size_t idx = (iy * sx + ix) * 3;
        // For fun, let's alternate which source to assing to the
        // third buffer.
        if ((iy % 2 && ix % 2) || (!(iy % 2) && !(ix % 2))) {
            buffer3[idx+0] = buffer1[idx+0]; // R
            buffer3[idx+1] = buffer1[idx+1]; // G
            buffer3[idx+2] = buffer1[idx+2]; // B
        } else {
            buffer3[idx+0] = buffer2[idx+0]; // R
            buffer3[idx+1] = buffer2[idx+1]; // G
            buffer3[idx+2] = buffer2[idx+2]; // B
        }
    }
}
// Import the third buffer into out Image
out.read(sx, sy, "RGB", DoublePixel, buffer3);
out.write("Output.png");

YMMV

pixel-by-pixel image processing

Sign up to request clarification or add additional context in comments.

1 Comment

The double * buffers worked great with OpenMP, even with the #pragmas I used in my question's code. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.