2011-02-08 98 views
5

¿Cómo encontrar la "entropía" con imagemagick, preferiblemente mini_magic, en Ruby? Necesito esto como parte de un proyecto más grande, encontrando "interés" en una imagen para recortarlo.Obtener, o calcular la entropía de una imagen con Ruby y imagemagick

I encontró una buena example in Python/Django, que da el siguiente pseudo-código:

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 

esto se traduciría en la fórmula entropy = -sum(p.*log2(p)).

Mis preguntas: ¿Interpreté correctamente el código de Django/Python? ¿Cómo puedo buscar un histograma en mini_magick de ruby, si es que lo hago?

Pregunta más importante: ¿este algoritmo es bueno en primer lugar? ¿Sugeriría uno mejor para encontrar la "entropía" o "cantidad de píxeles cambiantes" o "profundidad del degradado" en (partes de) las imágenes?

Editar: Usando a.o. los recursos proporcionados por la respuesta a continuación, se me ocurrió con el código de trabajo:

# 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 

Dónde image_data es un RMagick::Image.

Esto se utiliza en el smartcropper gem, que permite el corte y recorte inteligente de imágenes con p. Ej. clip de papel.

Respuesta

Cuestiones relacionadas