Last active
January 3, 2016 08:19
-
-
Save pnlybubbles/8435425 to your computer and use it in GitHub Desktop.
適当に書いた画像変換プログラム。なにが起きてるかよくわからない。むちゃくちゃ遅い。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# encoding: utf-8 | |
# require "pp" | |
# require "pry" | |
require "RMagick" | |
include Magick | |
module ImageAnalize | |
class MagickItem | |
attr_reader :img | |
def initialize(img_magick) | |
@img = img_magick | |
end | |
def to_dict_array | |
img_da = [] | |
@img.each_pixel do |p, x, y| | |
img_da[y] ||= [] | |
img_da[y][x] = p | |
end | |
return DictArrayItem.new(img_da) | |
end | |
end | |
class DictArrayItem | |
def initialize(img_da) | |
@img = img_da | |
end | |
def to_hsla | |
return DictArrayItem.new(@img.map { |y_p| y_p.map { |p| p.to_hsla } }) | |
end | |
def to_diff | |
img_delta = [] | |
th = [] | |
@img.each_with_index do |y_p, y| | |
th[y] = Thread.new do | |
y_p.each_with_index do |p, x| | |
p_here = p | |
p_prev = around_pixel(x, y, -1, 0) | |
p_next = around_pixel(x, y, 1, 0) | |
p_above = around_pixel(x, y, 0, -1) | |
p_below = around_pixel(x, y, 0, 1) | |
p_above_prev = around_pixel(x, y, -1, -1) | |
p_below_next = around_pixel(x, y, 1, 1) | |
p_above_next = around_pixel(x, y, 1, -1) | |
p_below_prev = around_pixel(x, y, -1, 1) | |
p_delta_horizontal = diff(p_prev, p_next, 1) | |
p_delta_vertical = diff(p_above, p_below, 1) | |
p_delta_topleft_bottomright = diff(p_above_prev, p_below_next, Math.sqrt(2)) | |
p_delta_topright_bottomleft = diff(p_above_next, p_below_prev, Math.sqrt(2)) | |
p_delta = balance(p_delta_horizontal, p_delta_vertical, p_delta_topleft_bottomright, p_delta_topright_bottomleft) | |
img_delta[y] ||= [] | |
img_delta[y][x] = p_delta | |
end | |
end | |
end | |
th.each { |thj| thj.join } | |
return DictArrayItem.new(img_delta) | |
end | |
def calibrate(*max_calibrate) | |
max_value = @img.map { |x_a| x_a.transpose.map { |a| a.max } }.transpose.map { |a| a.max } | |
calibrate_img = @img.map do |y_p| | |
y_p.map do |p| | |
(0...max_calibrate.length).to_a.map do |i| | |
max_calibrate[i] * (1 - p[i] / max_value[i]) | |
end | |
end | |
end | |
return DictArrayItem.new(calibrate_img) | |
end | |
def set_all(*p_all) | |
return DictArrayItem.new(@img.map { |y_p| y_p.map { |p| p.zip(p_all).map { |v| v[1] || v[0] } } }) | |
end | |
def to_magick | |
img_new = Magick::Image.new(@img[0].length, @img.length) | |
@img.each_with_index do |y_p, y| | |
y_p.each_with_index do |p, x| | |
pixel = Magick::Pixel.from_hsla(*p) | |
img_new.pixel_color(x, y, pixel) | |
end | |
end | |
return MagickItem.new(img_new) | |
end | |
private | |
def diff(p1, p2, d) | |
return p1.zip(p2).map { |a| (a[0] - a[1]).abs / d } | |
end | |
def balance(*p) | |
return p[0].zip(*p[1..-1]).map { |a| a.inject(0) { |r, v| r += v } / p.length } | |
end | |
def around_pixel(x, y, rx, ry) | |
if (x + rx > 0 && x + rx < @img[0].length - 1) && (y + ry > 0 && y + ry < @img.length - 1) | |
return @img[y + ry][x + rx] | |
else | |
return @img[y][x] | |
end | |
end | |
end | |
end | |
# -- ui -- | |
img_file = ARGV[0] | |
start_time = Time.now.instance_eval { '%s.%03d' % [strftime('%Y%m%d%H%M%S'), (usec / 1000.0).round] }.to_f | |
puts "start : #{start_time}" | |
puts "load file : #{File.expand_path(img_file)}" | |
img_src = Magick::ImageList.new(img_file) | |
puts "size : #{img_src.columns} x #{img_src.rows}" | |
img_analize = ImageAnalize::MagickItem.new(img_src) | |
img_result = img_analize.to_dict_array.to_hsla.to_diff.calibrate(*[255.0, 255.0, 255.0, 1.0]).set_all(*[0, 0, nil, 1.0]).to_magick.img | |
img_new_name = img_file.gsub(/\.png/, "_delta_#{Time.now.strftime('%y-%m-%d_%H.%M.%S')}.png") | |
img_result.write(img_new_name) | |
puts "generate file : #{File.expand_path(img_new_name)}" | |
finish_time = Time.now.instance_eval { '%s.%03d' % [strftime('%Y%m%d%H%M%S'), (usec / 1000.0).round] }.to_f | |
puts "finish : #{finish_time}" | |
puts "elapsed time : #{finish_time - start_time}" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment