Skip to content

Instantly share code, notes, and snippets.

@angelfan
Forked from rasefon/si.rb
Created March 21, 2016 02:03
Show Gist options
  • Select an option

  • Save angelfan/ced2baa571db278ff881 to your computer and use it in GitHub Desktop.

Select an option

Save angelfan/ced2baa571db278ff881 to your computer and use it in GitHub Desktop.

Revisions

  1. @rasefon rasefon revised this gist Oct 30, 2013. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion si.rb
    Original file line number Diff line number Diff line change
    @@ -58,7 +58,7 @@ def calculate_threshold(img_fn)
    end

    #puts threshold
    img = img.threshold(threshold)
    img = img.threshold(threshold * 256)
    img.write(File.join(dir_name, "threshold_#{img_fn}"))

    result = Hash.new
  2. @rasefon rasefon created this gist Oct 30, 2013.
    105 changes: 105 additions & 0 deletions si.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,105 @@
    require 'RMagick'

    $scale_size = 256.0
    $img_fn1 = ARGV[0]
    $img_fn2 = ARGV[1]
    $scale_size = ARGV[2].to_f if ARGV[2]

    def calculate_threshold(img_fn)
    dir_name = File.dirname(img_fn)

    img = Magick::Image.read(img_fn).first
    img.scale!($scale_size, $scale_size)
    img = img.quantize(256, Magick::GRAYColorspace)
    img = img.negate(true)

    # record negative image
    img.write(File.join(dir_name, "ng_#{img_fn}"))

    rows = img.rows
    cols = img.columns

    pixels = img.export_pixels(0, 0, cols, rows, "I").map { |p| p / 256 }
    total_pixels = pixels.size

    # Calculate histogram
    histogram = Array.new(256, 0)
    pixels.each do |p|
    histogram[p] += 1
    end
    #p histogram
    sum = 0.0
    256.times { |i| sum += i * histogram[i] }

    sum_b = 0.0
    w_b, w_f = 0, 0
    max_cache = 0.0
    threshold = 0

    256.times do |t|
    w_b += histogram[t]
    next if 0 == w_b

    w_f = total_pixels - w_b
    break if 0 == w_f

    sum_b += t * histogram[t]
    m_b = sum_b / w_b
    m_f = (sum - sum_b) / w_f

    #puts "mb:#{m_b} mf:#{m_f} wb:#{w_b} wf:#{w_f}"

    between = w_b * w_f * (m_b - m_f) ** 2

    if between > max_cache
    max_cache = between
    threshold = t
    end
    end

    #puts threshold
    img = img.threshold(threshold)
    img.write(File.join(dir_name, "threshold_#{img_fn}"))

    result = Hash.new
    result["threshold"] = threshold
    result["bw_img"] = img

    result
    end

    def hamming_dist(img_fn1, img_fn2)
    img_result1 = calculate_threshold(img_fn1)
    img_result2 = calculate_threshold(img_fn2)

    img1 = img_result1["bw_img"]
    pixels1 = img1.export_pixels(0, 0, img1.columns, img1.rows, "I").map { |p| p / 65535 }

    img2 = img_result2["bw_img"]
    pixels2 = img2.export_pixels(0, 0, img2.columns, img2.rows, "I").map { |p| p / 65535 }

    hd = 0

    difference_pixels = []
    pixels1.each_index do |i|
    pixel = pixels1[i] ^ pixels2[i]
    hd += pixel
    difference_pixels[i] = pixel * 65535
    end

    [hd, difference_pixels]
    end

    result = hamming_dist($img_fn1, $img_fn2)
    hd = result[0]
    difference_rate = hd / $scale_size ** 2 * 100
    puts "Hamming distance: #{hd}"
    puts "Difference rate: #{difference_rate}%"

    if 0 != hd
    d_img = Magick::Image.new($scale_size, $scale_size)
    d_img.import_pixels(0, 0, $scale_size, $scale_size, "I", result[1])
    fn1 = File.basename($img_fn1, File.extname($img_fn1))
    fn2 = File.basename($img_fn2, File.extname($img_fn2))
    d_img.write(File.join("#{fn1}_#{fn2}_diff_img.png"))
    end