Advertisement
acavalin

color/greyscale image test

Jul 11th, 2016
896
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ruby 5.14 KB | None | 0 0
  1. #!/usr/bin/env ruby
  2.  
  3. # How to check image color or back and white -- http://www.imagemagick.org/discourse-server/viewtopic.php?t=19580
  4. #
  5. #   convert file.jpg -colorspace HSL -verbose info:|grep -A 6 Green # values: absolute (percent)
  6. #       Green:
  7. #         min:  0       (0)
  8. #         max:  255     (1)
  9. #         mean: 70.2043 (0.275311)
  10. #         standard deviation: 99.2055 (0.389041)
  11. #         kurtosis: -0.981812
  12. #         skewness:  0.897517
  13. #
  14. # You convert the image to HSL and then output verbose information ("identify"
  15. # statistics).
  16. # In HSL space Saturation define how colorful pixels are, and this is returned
  17. # in the 'Green' channel statistics.
  18. #
  19. # If max is 0 so no color was present at all: it is a perfect grayscale or black/white image.
  20. # If max is 1 so at least one pure color pixel exists: it is not a pure grayscale image.
  21. #
  22. # The mean indicates how much colorful in general the image is.
  23. # A mean of 40% means the image is not even mostly grayscale (white background).
  24. #
  25. # Other statistics show how the color ratios was distributed about that mean.
  26. #
  27. # NOTE:
  28. #   Due to HSL being a double hexcone model, this colorspace does not work properly
  29. #   for measuring saturation for L>50% as it approaches the top peak. There white
  30. #   is going to be indetermined saturation and turns out is interpreted as high
  31. #   saturation. In its place, use HCL, HCLp, HSI or HSB above. These are all single
  32. #   hexcone type models and should work fine in the above equation.
  33. #
  34. #   convert file.jpg -colorspace HSI -channel g +channel -format "%[fx:mean.g]" info:
  35. #
  36. # ------------------------------------------------------------------------------
  37. #
  38. # How to retrive the single values from the statistics:
  39. #   Retrieving individual Image Channel Statistics -- http://www.imagemagick.org/discourse-server/viewtopic.php?t=21008
  40. #   FX Expressions as Format and Annotate Escapes  -- http://www.imagemagick.org/Usage/transform/#fx_escapes
  41. #   Format and Print Image Properties              -- http://www.imagemagick.org/script/escape.php
  42. #   The Fx Special Effects Image Operator          -- http://www.imagemagick.org/script/fx.php
  43. #
  44. # ------------------------------------------------------------------------------
  45. #
  46. # Robust command to get H/S/I statistics in the R/G/B sections:
  47. #   convert file.jpg -colorspace HSI -verbose info: | grep -A 20 Red
  48. #
  49. # Get the single value of a statistic (saturation mean):
  50. #   convert file.jpg -colorspace HSI -channel g +channel -format "%[fx:mean.g]" info:
  51. #
  52. # Get image colors histogram for a restricted number of colors (64):
  53. #   convert file.jpg -dither FloydSteinberg -colors 64 -colorspace HSB -format %c histogram:info:-
  54.  
  55. def die(msg); STDERR.puts "ERROR: #{msg}!"; exit 1; end
  56.  
  57. fname = ARGV[0].to_s
  58. die 'file not found' if fname.size == 0 || !File.exists?(fname)
  59.  
  60. # computing histogram
  61. histlines = `convert '#{fname}' -dither FloydSteinberg -colors 64 -colorspace HSB -format %c histogram:info:-`.split("\n")
  62. puts histlines if ARGV.include?('-h')
  63.  
  64. print fname.ljust(25)
  65.  
  66. # extract values from histogram (num.pixels, hue, saturation, intensity)
  67. hist = histlines.grep(/hs[ib]/i).map{|line|
  68.   # http://www.imagemagick.org/Usage/files/#histogram
  69.   # pixel count:    R   G   B  #HEX    hsi(hue, saturation, intensity)
  70.   #        9274: (  1, 89,135) #015987 hsi(0.582895%,35.0103%,53.0617%)
  71.   next unless m = line.match(Regexp.new ' +([0-9]+):.+hs[ib]\(([^%]+)%,([^%]+)%,([^%]+)%')
  72.   {
  73.     npix: m.captures[0].to_i,
  74.     hue:  m.captures[1].to_f,
  75.     sat:  m.captures[2].to_f,
  76.     int:  m.captures[3].to_f,
  77.   }
  78. }.compact
  79.  
  80. die "histogram size (#{hist.size}) < 2" if hist.size < 2
  81.  
  82. # compute saturation mean and unique hue std.deviation
  83. stats = hist.each_with_index.inject({
  84.   tot_pixels: 0,
  85.   hue_outlayered_pixels: 0,
  86.   sat_sum:    0,
  87.   hue_num:    0,
  88.   hue_mean:   0,
  89.   hue_m2:     0,
  90. }){|stats, pair|
  91.   row, i = pair
  92.  
  93.   stats[:tot_pixels] += row[:npix]
  94.  
  95.   stats[:sat_sum] += row[:npix] * row[:sat]
  96.  
  97.   # incremental/online formula for std.deviation
  98.   # https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Online_algorithm
  99.   if i != 0 && i != (hist.size - 1) # remove extreme values/outlayers for a better st.dev
  100.     delta             = row[:hue] - stats[:hue_mean]
  101.     stats[:hue_num ] += 1
  102.     stats[:hue_mean] += delta / stats[:hue_num]
  103.     stats[:hue_m2  ] += delta * (row[:hue] - stats[:hue_mean])
  104.   else
  105.     stats[:hue_outlayered_pixels] += row[:npix]
  106.   end
  107.  
  108.   stats
  109. }
  110.  
  111. sat_mean = stats[:sat_sum] / stats[:tot_pixels]
  112. hue_sd   = (stats[:hue_m2] / (hist.size - 3)) ** 0.5
  113. hue_outl = stats[:hue_outlayered_pixels].to_f / stats[:tot_pixels] * 100
  114. print [
  115.   'S:%5.2f' % sat_mean ,
  116.   'H:%5.2f' % hue_sd   ,
  117.   'N:%3d'   % hist.size,
  118.   'O:%3d%%' % hue_outl ,
  119.   '=>  '
  120. ].join('  ')
  121.  
  122. def is_colored?(sat_mean, hue_sd, hist_size)
  123.   return false if hist_size < 4
  124.  
  125.   if    sat_mean < 10; return false         # low saturation
  126.   elsif sat_mean < 30; return hue_sd > 25   # middle sat., hue must be big for a colored image
  127.   else               ; return true          # high saturation
  128.   end
  129. end # is_colored?
  130.  
  131. puts is_colored?(sat_mean, hue_sd, hist.size) ? 'color' : 'grey'
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement