Personal tools
You are here: Home メンバー 菊地時夫 授業 画像処理論 画像の幾何補正・他(演習4)
Document Actions

画像の幾何補正・他(演習4)

by 菊地時夫 last modified 2007-06-13 11:43

~/image/e4 で演習

内挿法

  • Python Imaging Library には内挿法として

    NEAREST ... 最近隣内挿法

    BILINEAR ... 共一次内挿法

    BICUBIC ... 3次畳み込み内挿法

    が用意されている。

  • これに加えて、主に画像を縮小するときに使用する ANTIALIAS もある

画像の拡大

  • この小さい画像 を 5倍に拡大してみよう
  • 最初は NEAREST を使う
  • # e401.py ... expand image
    import Image
     
    img = Image.open('s401.ppm')
    width, height = img.size
    width = width * 5
    height = height * 5
    imgx = img.resize((width,height), Image.NEAREST)
    imgx.save('s401-1.ppm')
    

他の内挿法も試してみる

  • 同じ画像を使って、

    BILINEAR -> e401-2.ppm

    BICUBIC -> e401-3.ppm

    ANTIALIAS -> e401-4.ppm

    にそれぞれ画像を保存して比較してみよう

  • 注意:img.show() で表示させた場合、いったん JPEG 形式で保存される。このため若干画質が落ちて 比較できないことがある。

画像の縮小と内挿法

  • ついでに画像を縮小する場合も比較してみよう
  • 大きい画像 をダウンロードして保存し、縦横それぞれ 1/4 に縮小するプログラム(e402.py)を作成しなさい。NEAREST/BILINEAR/BICUBIC/ANTIALIAS それぞれ s402-1.ppm/s402-2.ppm/s402-3.ppm/s402-4.ppm に保存して比較する。

Affine 変換の係数を求める

  • 以下の図のような affine 変換を行う

  • u = ax + by + c
    v = dx + ey + f
    
  • (u, v) -> (x, y) へ変換(逆変換)

三角形の頂点を与える

  • (x, y) = ( 10, 50), (380, 100), (130, 280)
    (u, v) = (  0,  0), (400, 100), (100, 300)
    
  • |u1 v1|   |x1 y1 1| |a d|
    |u2 v2| = |x2 y2 1| |b e|
    |u3 v3|   |x3 y3 1| |c f|
    
  • 上記行列による方程式を(a, b, ... f) について解く

Python で解く

  • # e403.py ... affine coefficients
    from Numeric import *
    from Matrix import *
    from LinearAlgebra import * 
    U = Matrix([[  0,   0],
                [400, 100],
                [100, 300]])
    X = Matrix([[10,  50, 1],
                [380, 100, 1],
                [130, 280, 1]])
    XINV = inverse(X)
    C = array(XINV * U)
    print 'a =', C[0][0]
    print 'b =', C[1][0]
    print 'c =', C[2][0]
    print 'd =', C[0][1]
    print 'e =', C[1][1]
    print 'f =', C[2][1]
    

Affine 変換を実行

  • PIL の image オブジェクトには transform というメソッドが用意されている。
  • 詳しくは マニュアル
  • この画像 を変換
  • 係数(a, b,...f) は先に求めたものを使う(このままでは動かない)
  • # e404.py ... test affine transform
    import Image
     
    img = Image.open('s404.ppm')
    imgx = img.transform((400,300), Image.AFFINE, 
                         (a, b, c, d, e, f),
                         Image.NEAREST)
    imgx.save('s404-1.ppm')

最小二乗法(おまけ)

  • 解説
  • プログラム例
  • 二乗誤差を最小にするという原理と
  • 偏微分をゼロにすると一次連立方程式に帰結することが理解できれば、
  • 変数が増えても同じ。

最小二乗法(グラフ)

  • プログラム例を簡単化し、gnuplot で点と回帰線を表示する
  • gnuplot を使っているため、X11 のターミナルから実行すること
  • # e405.py
    from math import sqrt
    import Gnuplot
     
    def linreg(X, Y):
        assert len(X) == len(Y)
        N = len(X)
        Sx = Sy = Sxx = Syy = Sxy = 0.0
        for x, y in zip(X, Y):
            Sx = Sx + x
            Sy = Sy + y
            Sxx = Sxx + x*x
            Syy = Syy + y*y
            Sxy = Sxy + x*y
        det = Sxx * N - Sx * Sx
        a = (Sxy * N - Sy * Sx)/det
        b = (Sxx * Sy - Sx * Sxy)/det
        return a, b
     
    def plot(X, Y, a, b):
        g = Gnuplot.Gnuplot()
        P = Gnuplot.Data(zip(X, Y))
        L = Gnuplot.Func('(%f)*x + (%f)' % (a, b), with='line')
        g.plot(P, L)
        raw_input('Hit return to terminate.')
     
    if __name__=='__main__':
        #testing
        X=[1,2,3,4,5]
        Y=[357.14,53.57,48.78,10.48,-168.8]
        a, b = linreg(X, Y)
        plot(X, Y, a, b)
    

発展課題

  • 1.ppm 2.ppm 4.ppm の中からひとつを選んでアフィン変換を試して見なさい。その際、画像は適当に斜めに歪ませるが、同時に 上下反転 するように係数を選びなさい。(e406.py)

出席確認

  • - 本日作成した 最後のプログラム をメールの本文に記入して、菊地・画像処理論用 に送信。本文の最初に感想等入れるも可。

Powered by Plone CMS, the Open Source Content Management System

This site conforms to the following standards: