使用OpenMP和Magick ++进行逐像素图像处理

时间:2016-03-21 00:23:37

标签: c++ openmp magick++

我正在研究用于图像处理的C ++代码,逐像素工作(使用Magick ++),我想将它与OpenMP一起使用,但我有下一个问题:

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.

而且,它仍然陷入无限循环。

以下是代码段:

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

有没有办法解决这个问题?

1 个答案:

答案 0 :(得分:1)

  

有没有办法解决这个问题?

对于此示例,您可能希望使用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");

修改

如果您确实希望跨平行处理低级像素信息,则@NoseKnowsAll对于iy的单个区域是正确的。但是,由于内部缓存可能不同步,因此您将遇到调用out.pixelColor的问题。我建议导出像素数据,并行执行工作,并导入最终结果。

// 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