【问题标题】:Converting NArray to Magick::Image in Ruby在 Ruby 中将数组转换为 Magick::Image
【发布时间】:2013-08-01 18:54:37
【问题描述】:

是否有一种有效的方法可以从 2D NArray(一个应该比常规数组更高效的 Ruby 类)中的数据创建 RMagick 图像,或者这两个库的数据类型不兼容?

下面的代码可以工作,但很难做到:使用嵌套的 do-loop 逐像素转换数据类型。据我所知,这给了我很多额外的工作,但没有 NArray 的优势。它在一月份的运行速度比糖蜜慢:

  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  

【问题讨论】:

    标签: ruby rmagick narray


    【解决方案1】:

    这里是一些我用来做灰度的代码,看起来比较快:

    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_pixelsMagick::Image#export_pixelsNArray.cast

    应该可以逐个通道做类似的事情来处理彩色图像。你必须使用浮点数没有根本原因,我只是想要我的目的格式(输入到神经网络)

    【讨论】:

    • 这对初学者很有帮助,但我无法确定如何在 narray_to_image 中确定像素值范围。您会注意到我的代码将所有像素值缩放到 0-256*255 范围(例如,如果数组中仅出现 1、2、3、4 的值,那么它将乘以 16k)。我尝试了您的代码,它生成了似乎是二进制图像的内容。每个点要么是纯黑的,要么是纯白的。
    • @user2055867:我的代码将 0.0..1.0 范围内的 FloatsNArray 转换为灰度图像。根据您的描述,您似乎传入了一个范围更广的数组,因此值 1.0 都是最大亮度。您可以在 0.0 和 1.0 之间扩展您的 NArray,或者考虑使用与 import_pixels 不同的存储类型参数 - 请参阅 imagemagick.org/RMagick/doc/constants.html#StorageType
    【解决方案2】:

    您可以像这样将灰度 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
    

    【讨论】:

      猜你喜欢
      • 2012-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-16
      • 2014-01-30
      • 1970-01-01
      相关资源
      最近更新 更多