今回の内容1(前回の修正)

今回は前回の「2009-7-1:二値化するときの閾値を占有率ごとに求めてみよう
のときに作成したエディターを修正します。

今回の内容2(次回の処理のための前準備)

今回行うもう一つの処理は、ある占有率に対して決定した
閾値で二値化を行ったときのバイナリーデータの入れ物の
名前を自動的に作成します。

作業(1)

前回作成したalos2lac.rbのコピーを同じディレクトリ内に作成します。
名前は何でもかまいませんが、ここでは作業した日が7月2日だったため、
名前を以下のようにしました。

alos2lac_07_02.rb

今回はこのコピーを修正していきますので、雛形のalos2lac.rbは何も
変更せずにとっておいてください。

それでは修正をしますので、alos2lac_07_02.rbを立ち上げてください。

作業(2)


前回作成したalos2lac.rbをもとにalos2lac_07_02.rbを
以下のように修正します。

##############################################################
file="4.ppm"

##----------------------------
#ファイル名と配列の数の取得用モジュール
class Thresh #クラス名は最初大文字で。
  #初期化とファイル名と配列数の読み込み
  def initialize(file)
    @file_name = file[0..-5]    #ファイルの名前を後ろから数えて5文字目
(.も1文字とカウントします)までを頭から取ってくる
    
    f=open(file,"rb")
    v = f.gets.split                    #headerを取る
    m = v[1].to_i;  n = v[2].to_i       #headerに書いてある縦ピクセル数m,横ピクセル数nの数字を文字から整数にする
    @array = f.read(m*n).unpack("C*") #@が付くとインスタンス変数となる(他の場所で使えるようになる). 'と"で使い分けをしなければならないときがあるので注意
   
     #上の@arrayについては、1列に読んでいく方法もある。
   
    #ヒストグラム作成
    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  #二値化ファイルの作成
  end #閾値計算のdefのend
 
  #二値化ファイルの作成
  def binary
    out_file = @file_name + "_#{@k_ratio}.ppm" #binaryファイルの名前をそれぞれの占有率にあわせて作成
    puts out_file
  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

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

作業内容

前回・今回扱う画像「4.ppm」のファイルをエディターで見てみると
一行目に以下のように書いてあります。 
P5 200 200 255
これがheaderです。
前回までのテキストはこのheaderも読み込んでしまっていました。
今回はこのheaderを読み飛ばします。

また、前回は一つのループの中で一気にやってしまっていた作業を
それ単体で分けて小さいループに分割しました。

また、この次の作業で二値化したデータを入れる入れ物の名前を自動で
作成してもらえるようにします。

結果確認

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

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

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





前回の作業(修正前)では表示さていなかった
 4_○○(占有率).ppm 
が表示されていると思います。

これがその占有率になるように分けたときの二値化データ
の名前(になる予定の)です。

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

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

タグ:

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