二値化するときの閾値を占有率Pごとに求めてみよう

今回は衛星画像をどのグレースケールで二値化するかの閾値を、
二値化した後の画像の何割を黒いピクセル(グレースケール=0)が占めるか
で決めたいと思います。

それでは実際にやってみましょう!!

用いる衛星画像をとってくる

今回用いる衛星画像は "O:/研究室ワークショップ/090701_ALOS2Lacunarity(キタダ)/4.ppm" です。
まずはじめに、4.ppmを自分の好きな好きな作業領域にコピーしてください。

エディター作成

エディターを立ち上げてください。
ファイル名は alos2lac.rb にします.
立ち上げたエディターに以下のように打ち込みます。

##############################################################
file="4.ppm"
m=n=200
##----------------------------
#ファイル名と配列の数の取得用モジュール
class Thresh #クラス名は最初大文字で。
  #初期化とファイル名と配列数の読み込み
  def initialize(file,m,n)
    f=open(file,"rb")
    @array = f.read(m*n).unpack("C*") #@が付くとインスタンス変数となる(他の場所で使えるようにな る). 'と"で使い分けをしなければならないときがあるので注意
    #上の奴についてcだと-127から127のものになる。Cだと0-255となる
    #上の@arrayについては、1列に読んでいく方法もある。
    #str=f.read(m*n)
    #=str.unpack("c*")
#    p @array.size
   
    #ヒストグラム作成
    histgram   
  end
  #ヒストグラム作成
  def histgram 
    #hash(連想配列)を定義
    dn={} #DN(digital number)を入れる箱(ハッシュ)の初期化
    @array.each do |x|
      dn[x]=0 unless dn[x] #dn[]の箱に何も入っていない(nil)の状態なら0を入れておきますよ。
      #上のはこっちでもいいよ。 dn[x]=0 if dn[x]=nil #dn[]の箱に何も入っていない(nil)の状態なら0を入れておきますよ。
      dn[x] += 1 #xの数字のdnの箱に1をカウントする
    end #@array.each doのend
#1    #1キーと個数の関係
#1    dn.each{|dn_x,freq| p [dn_x,freq]} #key,value 何(dn_x)がどんだけ(freq)あるか
#2    #2ソート
#2    dn.keys.sort.each{|x| p [x,dn[x]]}
    @dn=dn #dnをインスタンス変数にする
  end #ヒストグラム作成のdef
  #閾値の計算
  def threshold(k_ratio)
    dn=@dn #インスタンス変数のdnをローカルのこっちで使えるようにする
    sum=0; na=@array.size
    ratio = k_ratio*na/100.0 #判断基準となる数値
    dn.keys.sort.each do |x|
      sum += dn[x]; sum1 = sum - dn[x]
      if sum >= k_ratio*na/100.0
        t_value=x
        dif = sum - ratio
        dif1 = ratio -sum1
        t_value -=1 if dif > dif1
#        p t_value
#        p [k_ratio,t_value,sum,dn[x],sum1] #k_ratio:パーセンテージ、t_value:大きい方の画素、 sum:画素の個数のトータル
#        printf "%d,%d,%d,%d,%d,%d\n", k_ratio,t_value,sum1,sum,dif1,dif
        puts "#{k_ratio},#{t_value},#{sum1},#{sum},#{dif1},#{dif}"  #上のprintfはこのように表しても良い
        break #dn.keys.sort-のブレイク
      end #ifのend
    end#dn.keys.sort-のend
  end #閾値計算のdefのend
end #クラスのend
##-------------------------
thresh = Thresh.new(file,m,n) #新しく作ったモジュールをきれいにします.で、それをthreshという変数にします
#thresh.histgram
puts "占有率(%),閾値,和-1,和,差-1,差"
9.times do |k|
  k_ratio = (k+1)*10
  thresh.threshold(k_ratio)
end
#######################################################################

閾値となるグレースケールをみる。

4.ppmと今作成したalos2lac.rbがあるディレクトリでコマンドプロンプトを立ち上げてください。
下のように打ち込んでエンターキーを押してください。

ruby alos2lac.rb

すると以下のように文字がはしると思います。




各フレーズの説明
占有率P(%)  :二値化したときに黒色が占める割合
閾値となるDN :このDNまでの総ピクセル数が、もっとも占有率Pに近いを二値化画像で出す
   和-1    :占有率Pを越す一つ手前までのDNの総ピクセル数
    和      :占有率Pを越した時のDNまでの総ピクセル数
   差-1    :(画像の総面積×P)-(和-1)
    差      :和-(画像の総面積×P)

今日はここまで終了です。
お疲れ様でした。

タグ:

+ タグ編集
  • タグ:
最終更新:2009年07月01日 22:50
添付ファイル