5

Rubyでimagemagick、できればmini_magicで「エントロピー」を見つける方法は? これは、より大きなプロジェクトの一部として必要であり、画像の「面白さ」を見つけてトリミングします。

Python/Djangoで良い例を見つけました。これにより、次の擬似コードが得られます。

image = Image.open('example.png')
histogram = image.histogram() # Fetch a list of pixel counts, one for each pixel value in the source image

#Normalize, or average the result.
for each histogram as pixel
  histogram_recalc << pixel / histogram.size
endfor

#Place the pixels on a logarithmic scale, to enhance the result.
for each histogram_recalc as pixel
  if pixel != 0
    entropy_list << log2(pixel)
  endif
endfor

#Calculate the total of the enhanced pixel-values and invert(?) that.
entropy = entroy_list.sum * -1

これは式に変換されentropy = -sum(p.*log2(p))ます。

私の質問: Django/Python コードを正しく解釈しましたか? Rubyのmini_magickでヒストグラムを取得するにはどうすればよいですか?

最も重要な質問: そもそも、このアルゴリズムは適切でしょうか? 画像(の一部)で「エントロピー」または「変化するピクセルの量」または「グラデーションの深さ」を見つけるためのより良いものを提案しますか?

編集:以下の回答で提供されるリソースを使用して、動作するコードを思いつきました:

# Compute the entropy of an image slice.
def entropy_slice(image_data, x, y, width, height)
  slice = image_data.crop(x, y, width, height)
  entropy = entropy(slice)
end

# Compute the entropy of an image, defined as -sum(p.*log2(p)).
# Note: instead of log2, only available in ruby > 1.9, we use
# log(p)/log(2). which has the same effect.
def entropy(image_slice)
  hist = image_slice.color_histogram
  hist_size = hist.values.inject{|sum,x| sum ? sum + x : x }.to_f

  entropy = 0
  hist.values.each do |h|
    p = h.to_f / hist_size
    entropy += (p * (Math.log(p)/Math.log(2))) if p != 0
  end
  return entropy * -1
end

image_data はRMagick::Image.

これはsmartcropper gemで使用され、ペーパークリップなどで画像のスマートなスライスとトリミングを可能にします。

4

2 に答える 2

1

エントロピーはここで説明されています (MATLAB ソースを使用していますが、定性的な説明が役立つことを願っています):

エントロピーの紹介 (MATLAB でのデータ マイニング)

より正式な説明については、以下を参照してください。

「情報理論の要素」(第 2 章)、Cover と Thomas共著

于 2011-02-16T08:36:47.807 に答える
0

ファセットArray#entropyの:

require 'facets'
puts File.read('path/to/image.png').chars.entropy
于 2016-10-29T00:05:36.000 に答える