今回の内容

2009-7-2:二値化するときの閾値を占有率ごとに求めて名前をつけよう
で作成したファイルalos2lac_07_02.rb を編集します。

alos2lac_07_02.rb をコピーして、同じ作業フォルダに
貼り付けます。
ファイル名を以下のように変更します。
alos2lac_07_06.rb

alos2lac_07_06.rb を以下のように編集します。

#################################################################
file="4.ppm"
##----------------------------
#ファイル名と配列の数の取得用モジュール
class Thresh #クラス名は最初大文字で。
  #初期化とファイル名と配列数の読み込み
  def initialize(file)
    @file_name = file[0..-5]         
    f=open(file,"rb")
    v = f.gets.split
    @m = v[1].to_i;  @n = v[2].to_i       #headerに書いてあるmを文字から整数にしてとってくる
    @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    

    #ヒストグラム作成
    histogram    
  end 

  #ヒストグラム作成
  def histogram 
    #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
    dn=@dn #インスタンス変数のdnをローカルのこっちで使えるようにする
    sum=0; sum1=0; t_value=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
        break #dn.keys.sort-のブレイク
      end #ifのend
    end#dn.keys.sort-のend
    
    dif = sum - ratio;  dif1 = ratio - sum1
    t_value -= 1 if dif > dif1
    puts "#{@k_ratio},#{t_value},#{sum1},#{sum},#{dif1},#{dif}"  #上のprintfはこのように表しても良い
    
    binary(t_value)  #二値化ファイルの作成
  end #閾値計算のdefのend
  
  #二値化ファイルの作成
  def binary(t_value)
    dir = "PBM"
    Dir.mkdir(dir)  unless File.exist?(dir)
    out_file = dir + "/" + @file_name + "_#{@k_ratio}.pbm"
    puts out_file
  
    b_array = @array.collect do |x|
      bin = 1
      bin = 0 if x > t_value
      bin
    end  
  #p b_array
    out = open(out_file,"w")
    out.puts "P1 #{@m} #{@n}"                   #二値化したデータのヘッダー
    out.puts b_array.join(" ")
    out.close
  end
  
  #占有率10~90%の閾値を求める
  def thresh_ten
    puts "占有率P(%),閾値となるDN,和-1,和,差-1,差"  #和-1:占有率Pを越す一つ手前までのDNの総ピクセル数
                                               #和:占有率Pを越した時のDNまでの総ピクセル数
                                               #差-1:(画像の総面積×P)-(和-1)
                                               #差:和-(画像の総面積×P)
    9.times do |k|
      @k_ratio = (k+1)*10
      threshold
    end
  end
end #クラスのend

##-------------------------
thresh = Thresh.new(file) #新しく作ったモジュールをきれいにします.で、 それをthreshという変数にします
thresh.thresh_ten 

##################################################################

作業内容

今回の作業では
2009-7-1:二値化するときの閾値を占有率ごとに求めてみよう」、
「2009-7-2:二値化するときの閾値を占有率ごとに求めて名前をつけよう」
で作成してきたファイルを完成させます。

内容は、画像ファイル(今回は4.ppm)を占有率が10、20、30、…90%
となるように閾値を決めてその閾値での二値化画像を作ります。
作った衛星画像は同じ作業フォルダのPBMディレクトリに収納されます。
ちなみにPBMディレクトリは自動で作成されるようにプログラムします。

(注意)
二値化した時の閾値をkとすると
   DN       二値化の値
  0~k        1
 k+1~255      0


結果確認

作業領域でコマンドプロンプトを立ち上げてください。
立ち上げたコマンドプロンプトに以下のように打ちます。

ruby alos2lac_07_06.rb    (エンターキー)

すると以下のように表示されると思います。




作業ディレクトリーにPBMという新しいフォルダができてると思います。
その中に9つの画像が作成されているのを確認してください。

4_占有率.pbm
4_10.pbm
4_20.pbm
 ・
 ・
4_80.pbm
4_90.pbm


今回は以上です。
お疲れ様でした。

(お詫びと注意)
コメント文が実際の作業とずれている可能性があります。
もし間違いに気がつかれた方がございましたらそのつど修正を
お願いいたします。

タグ:

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