画像の濃淡情報(演習2)

画像の濃淡情報

  • この演習では
  • Python Imaging Library を用いて画像を読み込み
  • Pixel ごとの処理を行うプログラムを作成する
    • PIL には、pixel ごとでなく、まとめてごそっと処理できる機能もあるが、とりあえずは使用しない
  • 演習は ~/image/e2/ で行う
    $ cd image
    $ mkdir e2
    $ cd e2

ヒストグラムを求める

  • サンプル画像 ... ダウンロードして作業ディレクトリに移動して (mv ~/Desktop/sample.pgm .) 利用する。
    # e201.py ... make histogram
    import Image
    img = Image.open('sample.pgm')
    width, height = img.size
    hist = [0,]*256
    for j in range(height):
        for i in range(width):
            pixval = img.getpixel((i, j))
            hist[pixval] += 1
    for t in range(len(hist)):
        print '%3d %4d' % (t, hist[t])
    
  • 実行
    $ python e201.py

ヒストグラムをグラフ表示する

  • Pylab (matplotlib) を使用する。e201.py を次のように書き変える。
    # e201.py ... make histogram
    import Image
    import pylab
    img = Image.open('sample.pgm')
    width, height = img.size
    hist = [0,]*256
    for j in range(height):
        for i in range(width):
            pixval = img.getpixel((i, j))
            hist[pixval] += 1
    pylab.plot(hist)
    pylab.xlim((0, 255))
    pylab.show()
    

スクリプトの汎用化

  • 以下のような python スクリプトを作成し、chmod +x しておく
    #!/usr/bin/env python
    # pgmhist.py ... make histogram
    import sys
    import Image
    import pylab
    if len(sys.argv) == 1:
        print 'Usage: %s pgmfile.pgm' % sys.argv[0]
        sys.exit(1)
    else:
        fname = sys.argv[1]
    img = Image.open(fname)
    width, height = img.size
    hist = [0,]*256
    for j in range(height):
        for i in range(width):
            pixval = img.getpixel((i, j))
            hist[pixval] += 1
    pylab.plot(hist)
    pylab.xlim((0, 255))
    pylab.show()
    

使用法

  • ターミナルで
    ./pgmhist.py sample.pgm
  • 以下、画像をいろいろ濃度変換するが、このスクリプトでファイルを指定してヒストグラムを確認することができる

濃度変換

  • pixel 値を反転するには、入力を x 出力を y として
  • y = 255 - x
  • とすればよい
    # e202.py ... invert image
    import Image
    im0 = Image.open('sample.pgm')
    width, height = im0.size
    im1 = Image.new('L', (width, height))
    for j in range(height):
        for i in range(width):
            x = im0.getpixel((i,j))
            y = 255 - x
            im1.putpixel((i,j), y)
    im1.show()
    
  • im1.show() を im1.save("sample_inv.pgm") と書き変えて実行すると "sample_inv.pgm" に保存される

練習

  • sample_inv.pgm のヒストグラムを pgmhist.py で表示する

問題:濃度変換

  • 以下のようなコントラスト変換を行うプログラムを e203.py に作成しなさい。
  • 変換前の画像は次の中から選ぶこと
  • また、変換した画像を "e203.pgm" に保存しなさい。
    • (、そのヒストグラムを e203.hist に作成しなさい。)は不要
  • 必ず pgmhist.py でヒストグラムを確認すること。
    y = 0            ... ( x < 64)
        (x - 64) * 2 ... (64 <= x < 196)
        255          ... ( x >= 196)
    

注意

  • 上の式は、プログラム文ではない。
  • ノートなどに、式がどのようなグラフになるか描いて確認しなさい。
  • グラフとヒストグラムを見比べなさい。

課題(e204)

  • 以下のように、一部を白黒反転するような濃度変換も可能である。このような技法を「ソラリゼーション」と呼ぶ。ソラリゼーションは 銀塩写真でも処理途中で印画紙に光を当てることで可能であり、古くから行われている手法である。
    y = 2 * x               ... ( x < 128 )
        255 - 2 * (x - 128) ... ( x >= 128 )
    

発展課題(e205)

  • Image クラスのメソッドである point() を使うと、全pixel に適用する変換を一度に行うことができる。
  • ただし、PGM 画像は "L" mode であるため、変換表(lookup table) をあらかじめ作る必要がある。
    # e205.py ... bright
    import Image
     
    # make lookup table
    brighter = []
    for x in range(256):
        y = 0.5 * (x - 255) + 255
        brighter.append(int(y))
     
    im0 = Image.open('sample.pgm')
    im1 = im0.point(brighter)
    im1.show()
    

発展課題(e205)(続き)

  • 前記プログラムを実行してみなさい。
  • また、プログラムを修正して、自分が選んだ画像の明るさを変えて e205.pgm に保存しなさい。
  • e205.pgm のヒストグラムを確認しなさい。

発展課題(e206)

  • e205.py を書き変えて、ガンマ補正する配列(gamma)を作成し、自分が選んだ画像に適用しなさい。但し、γ=2 とする。(e206.py)
  • なお、y = x1/γ の式は x, y の最大値を 1.0 としていることに注意すること。
  • 適用した画像を e206.pgm に保存しなさい。

出席確認

  • 本日作成した 最後の 画像をメールに添付して、菊地・画像処理論用 に送信。本文に感想等入れるも可。