画像の色彩(演習3)

画像の色彩

  • 前回の演習に引き続き、PIL を用いて pixel ごとに処理します
  • 本日の演習は ~/image/e3 で行ってください
    $ cd image
    $ mkdir e3
    $ cd e3
    
  • 本日のサンプル画像 ダウンロードして、 ~/image/e3 に入れておく

RGB 分解

# e301.py ... decompose color image to R,G,B channels
import Image
 
img = Image.open('sample.ppm')
width, height = img.size
imgR = Image.new('L', (width, height))
imgG = Image.new('L', (width, height))
imgB = Image.new('L', (width, height))
for j in range(height):
    for i in range(width):
        r, g, b = img.getpixel((i, j))
        imgR.putpixel((i, j), r)
        imgG.putpixel((i, j), g)
        imgB.putpixel((i, j), b)
imgR.save('r.pgm')
imgG.save('g.pgm')
imgB.save('b.pgm')

YUV 分解

# e302.py ... split into YUV components
import Image
 
img = Image.open('sample.ppm')
width, height = img.size
imgY = Image.new('L', (width, height))
imgU = Image.new('L', (width, height))
imgV = Image.new('L', (width, height))
for j in range(height):
    for i in range(width):
        r, g, b = img.getpixel((i, j))
        y =  0.299   * r + 0.587   * g + 0.114   * b
        u = (-0.14713 * r - 0.28886 * g + 0.436   * b)+128
        v = ( 0.615   * r - 0.51499 * g - 0.10001 * b)+128
        imgY.putpixel((i, j), y)
        imgU.putpixel((i, j), u)
        imgV.putpixel((i, j), v)
imgY.save('y.pgm')
imgU.save('u.pgm')
imgV.save('v.pgm')

YUV から再構成

# e303.py ... compose RGB color image from YUV
import Image
 
imgY = Image.open('y.pgm')
imgU = Image.open('u.pgm')
imgV = Image.open('v.pgm')
width, height = imgY.size
img = Image.new('RGB', (width, height))
for j in range(height):
    for i in range(width):
        y = imgY.getpixel((i, j))
        u = imgU.getpixel((i, j)) - 128
        v = imgV.getpixel((i, j)) - 128
        r = y               + 1.13983 * v
        g = y - 0.39465 * u - 0.58060 * v
        b = y + 2.03211 * u
        img.putpixel((i, j), (r, g, b))
img.show()

課題:UV の情報量を減らす

  • YUV のうち UV は色に関する情報で輝度に関する情報 Y に比較して精度を落とすことができると言われている。
  • 次のコードを e303.py の適当な箇所に挿入して、画像がどのように変化するか確かめなさい。
  • プログラムのファイル名は e304.py とすること。
    # shrink and expand to reduce information
    imgU = imgU.resize((width/2, height/2), Image.ANTIALIAS
                       ).resize((width, height))
    imgV = imgV.resize((width/2, height/2), Image.ANTIALIAS
                       ).resize((width, height))
    
  • 2 を 4 に変えて試してみてもよい

発展課題:色あい、あざやかさの調整

  • u, v は画像の色だけを取り出したものである。
  • ゆえに u, v の値を調整すると、色だけを変化させることができる。
  • u, v は 参考 の図にあるように、2次元で表されるので、(u, v) ベクトルの「向き」と「大きさ」を変化させてみよう。

(u, v) の向きを調整

# e305.py
import Image
from math import cos, sin, pi
 
def hue(t, u, v):
    x = cos(t) * u - sin(t) * v
    y = sin(t) * u + cos(t) * v
    return x, y
 
imgY = Image.open('y.pgm')
imgU = Image.open('u.pgm')
imgV = Image.open('v.pgm')
width, height = imgY.size
img = Image.new('RGB', (width, height))
for j in range(height):
    for i in range(width):
        y = imgY.getpixel((i, j))
        u = imgU.getpixel((i, j)) - 128
        v = imgV.getpixel((i, j)) - 128
        u, v = hue(pi/6, u, v)
        r = y               + 1.13983 * v
        g = y - 0.39465 * u - 0.58060 * v
        b = y + 2.03211 * u
        img.putpixel((i, j), (r, g, b))
img.show()

Hue について

  • e305.py で関数名を hue としたが、色相(Hue)は別の定義があるので、(u, v) の向きを変える関数とは異なっている。
  • ここでは似たような機能であることから、便宜的に hue() と名付けてある。

(u, v) の大きさを調整

  • e305.py に、(u, v) の大きさを調整する関数を付け加えなさい。
  • 関数は saturation(s, u, v) の形で呼び出し、hue と同様 (u, v) のタプルを返すものとする。
  • hue, saturation のパラメータ (t, s) を適当に変化させて、どのような画像になるか確かめなさい。

Saturation について

  • 彩度という呼び名があるが、ここで使っているものは定義とは異なる。
  • 初期のカラーテレビには 輝度・コントラスト に加えて、色相(Hue)・彩度(Saturation)(など) と書いた調節つまみがあった。
  • 今でも、業務用モニターなどでは調整できるようになっているらしい。

さらに発展課題

  • 以下の画像からひとつを選んで、色あい・あざやかさの調整を行う
  • 1.ppm 2.ppm 3.ppm 4.ppm

出席確認

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