Search code examples
rubyimage-processingminimagickcontrast

How to find contrast ratio or any kind of measurement to find image with "content"?


I am trying to find out a way to "score" images that are likely to be a logo. I have thought on using the concept of contrast ratio. I will be comparing one image that is clearly to be a logo with other images that basically will be just a background color or a background color with a column in another color. For example:

Black background

vs

Jacks background

So, how can I measure the contrast ratio using any Ruby library? I am currently using Minimagick but I haven't found a way to get the contrast ratio. There are options to modify it, but not to get the ratio per say.


Solution

  • You can do this in roughly two steps.

    First get the histogram of the image using RMagick:

    http://www.simplesystems.org/RMagick/doc/image1.html#color_histogram

    The next step is applying some formula. The one I provide below is one I just came up with off the top of my head. However, there are a few others:

    http://en.wikipedia.org/wiki/Contrast_(vision)#Formula

    Next compute the average color by multiplying each pixel by it's weight and then dividing by the total number of pixels. Something like this:

    color_histogram.each do |pixel, count|
      total_red += pixel.red*count
      total_blue += pixel.blue*count
      total_green += pixel.green*count
    end
    

    average_red = total_red / pixel_count average_blue = total_blue / pixel_count average_green = total_green / pixel_count

    Once you have your "average color", determine the total distance between each pixel and the average:

    color_histogram.each do |pixel, count|
      distance_red += Math.abs(average_red - pixel.red)
      distance_blue += Math.abs(average_blue - pixel.blue)
      distance_green += Math.abs(average_green - pixel.green)
    end
    

    The sum distance_red + distance_blue + distance_green should roughly be equivalent to the "contrast" of the image.