About this Blog

This Blog has English posts and Japanese posts. About Mac, iOS, Objective-C, and so on.

2013年4月12日金曜日

Rubyで画像の二値化

自習時のメモです。

参考
画像処理について
:: ロボティクス入門(共立出版株式会社)
BMP画像の形式について
:: http://www.kk.iij4u.or.jp/~kondo/bmp/
gnuplotについて
:: http://www.wakayama-u.ac.jp/~tokoi/lecture/shori1/2009/09.html

使い方
$ruby binarize.rb ファイル名
としてください。 入力は、グレースケールのWindowsビットマップ画像
二値化されたpbmファイルと、クラス間分散とクラス内分散の分散比の数値データを出力します。
数値データは、gnuplotでプロットしてください。

出力サンプル
元画像、二値化した画像、閾値を変化させたときの分散比、という順番です。

りんごの画像




机の上に置かれた、プラスチックのケース





コード
binarize.rb
if ARGV.size==0
  puts "ERROR!: input file name is missing."
  exit
end

$original_file_name = ARGV[0]

def output_pbm(data)
  height = data.size
  width = data[0].size
  File.open($original_file_name+".pbm", "w"){|io|
    io.puts "P1"
    io.puts "# CREATOR: Ruby PNM Filter Version 1.1"
    io.puts width.to_s + " " + height.to_s
    data.reverse.each{|e1|
      io.puts e1.join(" ")
    }
  }
  puts "Created #{$original_file_name+".pbm"}."
end
def get_bmp_data
  io = open($original_file_name, "rb")
  io.seek(2, IO::SEEK_CUR)
  print "file size (byte)="; puts filesize = io.read(4).unpack("i")[0]
  io.seek(4, IO::SEEK_CUR)
  print "offset="; puts offset = io.read(4).unpack("i")[0]
  io.seek(4, IO::SEEK_CUR)
  print "width="; p width = io.read(4).unpack("i")[0]
  print "height="; p height = io.read(4).unpack("i")[0]
  io.seek(2, IO::SEEK_CUR)
  print "Bits per pixel="; p bpp = io.read(2).unpack("s")[0]
  print "Compression type="; p ctype = io.read(4).unpack("i")[0]
  puts "(0:No compression 1:RunLength 8 bits/pixel 2:RunLength 4 bits/pixel 3:Bitfields)"
  io.seek(offset, IO::SEEK_SET)
  data = Array.new(height)
  height.times{|j|
    data[j] = Array.new(width)
    width.times{|i|
      value = io.read(1).unpack("C")[0]
      data[j][i] = value
    }
    io.seek(width%4==0 ? 0 : 4-width%4, IO::SEEK_CUR)
  }
  io.close
  return data
end
def binarize(data, threshold=128)
  return data.map{|e1| e1.map{|e2| e2 max_variance_ratio
      max_variance_ratio = v
      slashold  = s
    end
  }
}
puts "Created #{$original_file_name+".plt"} for gnuplot."
print "max_variance_ratio:"; puts max_variance_ratio
output_pbm(binarize(data, slashold))
print "time(sec): "; puts Time.now - start_time

0 件のコメント:

コメントを投稿