差動結合による錯視
PyGameサンプルプログラム
図1に示される灰色の帯は、左側の領域と右側の領域の一様な部分に分かれ、左の方が明るく見える。物理的には、左の1/4の領域と右の1/4の領域は同じ明るさであり、それぞれ中央に向かって緩やかな明るさの傾斜で変化して、中央の境界線で明るさが明瞭に異なっている。緩やかな変化は、その変化が分からない程度であるので一様に見えている(人によって、あるいはその時の見方によっては、緩やかな変化が分かるが、この緩やかな変化の度合いは、サンプルプログラム(リスト1)では調整できる)。これは、差動結合によると説明されている。
図1
リスト1のプログラムファイルは、圧縮ファイルdiffcplngfile.zipとして用意したので、ダウンロード展開すれば自由に利用できる。
リスト1のプログラムはライブラリPyGameを利用しているが、PyGameは、このウェブサイトで説明されているように簡単にインストールできる。
図1の灰色の帯は、ピクセル単位で色の設定を行った。使用したコードは、以下のようである。
pa[:200] =
(100,100,100)
# 左1/4を灰色で塗り潰す
for ix in
range(200,400):
# 中央左側を変化率vd/200で塗り潰す
v =
100 + int(vd * (ix - 200) / 200)
pa[ix] = (v,v,v)
for ix in
range(400,600):
# 中央右側を変化率-vd/200で塗り潰す
v =
100 - vd + int(vd * (ix - 400) / 200)
pa[ix] = (v,v,v)
pa[600:800] =
(100,100,100)
# 右1/4を灰色で塗り潰す
刺激パターンの表示後、以下のコードでキーボードの入力待ちを行っている。
ck0 = True
while ck0:
for
e in pg.event.get():
if e.type == pg.KEYDOWN:
if e.key == pg.K_q:
# 「キーQ」が押されたか?
ck0 = False
# このwhile文を抜け出す
ck = False
# 外側のwhile文を抜け出す
elif e.key == pg.K_u: # 「キーU」が押されたか?
ck0 = False
if vd < 70:
vd += 1
# vdの更新
elif e.key == pg.K_d: # 「キーD」が押されたか?
ck0 = False
if vd > -70:
vd -= 1
# vdの更新
pg.time.wait(10)
# 10msの待機
キーQを押すと、プログラムの実行終了である。
キーUを押すと、中央境界線における明るさの違いvd(中央値からの差)が1増える。
キーDを押すと、vdの値は1減る。
キーUを繰り返して押して、vd=50の場合のパターンが図3である。中央の境界線近くの明るさの変化が分かり、帯の左右の1/4の領域の明るさが同じに見える。
図2
キーDを繰り返し押して、vd=3に設定したときのパターンは図3のようになる。中央線の左右の明るさのなだらかな変化は分かり難く、作用の領域は明るさの異なる一様な灰色の領域に見える。
図3
キーQを押すと、プログラムは終了する。
import pygame as pg
pg.init()
my_font = pg.font.SysFont(None,34)
screen =
pg.display.set_mode(size=(1000,500)) # 表示画面
sf = pg.Surface((800,200))
# 刺激表示サーフェス
pa = pg.PixelArray(sf)
# サーフェスに対応するピクセル配列
vd = 10
# 境界領域の輝度差
ck = True
while ck:
#
# 画面全体を白で塗りつぶす
#
screen.fill((255,255,255))
pg.display.flip()
#
#
輝度差vdの表示
#
img_str =
my_font.render(f'vd = {vd}', True, (0,0,0), (255,255,255))
rect_str =
img_str.get_rect()
screen.blit(img_str, (500 -
rect_str.width//2, 500 - rect_str.height*2))
#
#
提示刺激パターンの描画
#
pa[:200] =
(100,100,100)
# 左1/4を灰色で塗り潰す
for ix in
range(200,400):
# 中央左側を変化率vd/200で塗り潰す
v =
100 + int(vd * (ix - 200) / 200)
pa[ix] = (v,v,v)
for ix in
range(400,600):
# 中央右側を変化率-vd/200で塗り潰す
v =
100 - vd + int(vd * (ix - 400) / 200)
pa[ix] = (v,v,v)
pa[600:800] =
(100,100,100)
# 右1/4を灰色で塗り潰す
sf =
pg.PixelArray.make_surface(pa) # ピクセル配列をサーフェスに変換
screen.blit(sf,
(100,100))
# サーフェスをスクリーンに移す
pg.display.flip()
# ディスプレイ画面の更新
ck0 = True
while ck0:
for
e in pg.event.get():
if e.type == pg.KEYDOWN:
if e.key == pg.K_q:
# 「キーQ」が押されたか?
ck0 = False
# このwhile文を抜け出す
ck = False
# 外側のwhile文を抜け出す
elif e.key == pg.K_u: # 「キーU」が押されたか?
ck0 = False
if vd < 70:
vd += 1
# vdの更新
elif e.key == pg.K_d: # 「キーD」が押されたか?
ck0 = False
if vd > -70:
vd -= 1 # vdの更新
pg.time.wait(10)
# 10msの待機
pg.quit()
# PyGameの終了