2

2D NArray (通常の配列よりも効率的であるはずの Ruby クラス) のデータから RMagick イメージを作成する効率的な方法はありますか、それとも 2 つのライブラリのデータ型に互換性がないだけですか?

次のコードは機能しますが、難しい方法で実行します: ネストされた do ループを使用してデータ型をピクセルごとに変換します。私が知る限り、これにより余分な作業が多くなり、NArray の利点はまったくありません。1月の糖蜜よりも遅くなります。

  def LineaProcessor.createImage(dataArray, width, height, filename)

    image = Magick::Image.new width, height

    # scale pixel values from 0..256*255 (the RMagick pixel uses 16 bits)
    scaling = 65280/dataArray.max

    # set each pixel...I couldn't find any easy way to convert array types
    width.times do |x|
        height.times do |y|
            g = dataArray[x+y*width]*scaling
            pixel = Magick::Pixel.new(g, g, g,0)
            image.pixel_color x, y, pixel 
      end
    end

    image
  end  
4

2 に答える 2

0

これは、グレースケールのみでこれを行うために使用したいくつかのコードであり、比較的速いようです:

module Convert
  PX_SCALE = ( 2 ** Magick::QuantumDepth  ).to_f

  # Converts 2D NArray of floats 0.0->1.0 to Magick::Image greyscale (16-bit depth)
  def self.narray_to_image na
    raise( ArgumentError, "Input should be NArray, but it is a #{na.class}") unless na.is_a?(NArray)
    raise( ArgumentError, "Input should have 2 dimensions, but it has #{na.dim}" ) unless na.dim == 2
    width, height = na.shape
    img = Magick::Image.new( width, height ) { self.depth = 16; self.colorspace = Magick::GRAYColorspace }
    img.import_pixels(0, 0, width, height, 'I', na.flatten, Magick::DoublePixel )
    img
  end

  # Converts Magick::Image greyscale to 2D NArray of floats 0.0 -> 1.0
  def self.image_to_narray img
    width = img.columns
    height = img.rows
    pixels = NArray.cast( img.export_pixels( 0, 0, width, height, 'I' ).map { |x| x/PX_SCALE } )
    pixels.reshape( width, height )
  end
end

読むべき主要な方法はMagick::Image#import_pixels、 、Magick::Image#export_pixelsおよびNArray.cast

カラー画像を処理するために、チャネルごとに同様のことを行うことができるはずです。フロートを使用しなければならない根本的な理由はありません。私は自分の目的 (ニューラル ネットワークへの入力) のための形式が欲しかっただけです。

于 2013-08-01T19:34:31.717 に答える
0

このように、グレースケールの 8 ビット NArray を RMagick 画像に変換できます。

require 'narray'
require 'RMagick'
class NArray
  def to_magick
    retval = Magick::Image.new(*shape) { self.depth = 8 }
    retval.import_pixels 0, 0, *shape, 'I', to_s, Magick::CharPixel
    retval
  end
end
sample = NArray.byte(8, 32).indgen.to_magick
于 2016-02-11T11:02:42.450 に答える