使用Ruby和imagemagick获取或计算图像的熵

ber*_*kes 5 ruby image-manipulation imagemagick entropy

如何在Ruby中找到带有imagemagick的"entropy",最好是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
Run Code Online (Sandbox Code Playgroud)

这将转化为公式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
Run Code Online (Sandbox Code Playgroud)

image_data是一个RMagick::Image.

这用于smartcropper gem,它允许使用例如回形针进行智能切片和裁剪图像.

Pre*_*tor 1

这里解释了熵(使用 MATLAB 源代码,但希望定性解释有所帮助):

熵简介(MATLAB 中的数据挖掘)

更正式的解释请参见:

《信息论要素》(第二章),作者:Cover 和 Thomas