ImageMagick将图像加载到RAM中

时间:2015-09-27 22:06:33

标签: imagemagick jpeg image-manipulation

我有一张JPG图片,我想在其上执行一些操作以便使用模式识别。图片正在旋转,还应用了一些过滤器,如颜色反转,灰度等 程序就像这样

for(i=0;i<360;i++){
   rotate(pic,i);
   foreach(filter as f){
     f(pic);
     recognize(pic);
   }
}

为了提高速度,我希望将源图像加载到RAM中,然后从那里读取。可能吗?

2 个答案:

答案 0 :(得分:1)

由于您还没有指定语言或操作系统,我将向您展示如何在Linux / OSX环境中使用C ++中的Magick ++进行操作:

#include <Magick++.h> 
#include <iostream> 
using namespace std; 
using namespace Magick; 
int main(int argc,char **argv) 
{ 
   InitializeMagick(*argv);

   // Create an image object
   Image image;

   // Read a file into image object 
   image.read( "input.gif" );

   // Crop the image to specified size (width, height, xOffset, yOffset)
   image.crop( Geometry(100,100, 0, 0) );

   // Repage the image to forget it was part of something bigger
   image.repage();

   // Write the image to a file 
   image.write( "result.gif" ); 

   return 0; 
}

编译:

g++ -o program program.cpp `Magick++-config --cppflags --cxxflags --ldflags --libs`

您需要一个名为input.gif的图片才能阅读并且大于100x100,因此请创建一个:

convert -size 256x256 xc:gray +noise random input.gif

答案 1 :(得分:1)

您可以将图像写入mpr:,或将图像实例克隆到新结构。无论原始源位于内存中,您仍需要在第一个for循环中复制数据。这是C中的一个示例,它包含一个wand实例并克隆每次迭代。

#include <stdio.h>
#include <MagickWand/MagickWand.h>

void rotate(MagickWand * wand, double degree) {
    PixelWand * pwand = NewPixelWand();
    PixelSetColor(pwand, "white");
    MagickRotateImage(wand, pwand, degree);
    DestroyPixelWand(pwand);
}

void _f(MagickWand * wand, FilterTypes filter) {
    double x,y;
    x = y = 0.0;
    MagickResampleImage(wand, x, y, filter);
}

void recognize(MagickWand * wand) {
    // ???
}

int main(int argc, const char * argv[]) {
    MagickWandGenesis();
    MagickWand * wand, * copy_wand;
    wand = NewMagickWand();
    MagickReadImage(wand, "rose:");
    for ( int i = 0; i < 360 ; i++ ) {
        copy_wand = CloneMagickWand(wand);
        for ( FilterTypes f = UndefinedFilter; f < SentinelFilter; f++ ) {
            _f(copy_wand, f);
            recognize(copy_wand);
        }
    }
    MagickWandTerminus();
    return 0;
}

MPR写入内存中的特定页面,可以通过用户定义的标签进行识别。

MagickReadImage(wand, "rose:");
MagickWriteImage(wand, "mpr:original"); // Save image to "original" label
for ( int i = 0; i < 360 ; i++ ) {
    copy_wand = NewMagickWand();
    MagickReadImage(copy_wand, "mpr:original"); // Read image from "original" label
    for ( FilterTypes f = UndefinedFilter; f < SentinelFilter; f++ ) {
        _f(copy_wand, f);
        recognize(copy_wand);
    }
    copy_wand = DestroyMagickWand(copy_wand);
}

我能想到的最后一个选项是将图像像素数据复制到内存中,并在每次迭代时重新引用它。这允许一些性能改进,我正在考虑OpenMP,但是你会失去很多辅助方法。

MagickReadImage(wand, "rose:");
size_t w = MagickGetImageWidth(wand);
size_t h = MagickGetImageHeight(wand);
size_t data_length = w * h * 4;
char * data = malloc(data_length);
MagickExportImagePixels(wand, 0, 0, w, h, "RGBA", CharPixel, (void *)data);
for ( int i = 0; i < 360; i++ ) {
    long * copy_data = malloc(data_length);
    memcpy(copy_data, data, data_length);