ImageMagick 将图像加载到 RAM 中

ImageMagick load image into RAM

我有一张 JPG 图片,我想对其执行一些操作以使用模式识别。图片正在旋转,还应用了一些滤镜,如颜色反转、灰度等。 程序是这样的

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

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

由于您尚未指定语言或操作系统,我将向您展示如何在 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

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

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