使用 OpenMP 和 Magick++ 进行逐像素图像处理
Using OpenMP and Magick++ for pixel-by-pixel image processing
我正在编写用于逐像素工作的图像处理 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");
}
有办法解决吗?
Is there a way to solve this?
对于此示例,您需要使用 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
我正在编写用于逐像素工作的图像处理 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");
}
有办法解决吗?
Is there a way to solve this?
对于此示例,您需要使用 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