Python・Pygameで画像処理まとめ
文章:syun
日付:2005/8/11
目次
1.はじめに
2.グレースケール変換
3.セピア変換
4.2値変換
5.RGB抽出
6.RGB成分入れ替え
7.ネガ変換
8.輪郭抽出
9.グレースケールの改良版
10.モザイク化
11.ぼかし
12.モーションブラー
13.鮮鋭化
1.はじめに
今回はPython・Pygameを使った画像処理のソースコードをのせます。
(解説はなしです…)
2.グレースケール変換
超基本のグレースケールから、、。
import pygame
_gSrc = None
pygame.init()
pygame.display.set_mode((150, 150), 0, 32)
pygame.display.set_caption("グレースケール")
_gScr = pygame.display.get_surface()
tBuf = pygame.image.load("kenmo.jpg").convert()
# グレースケール変換
w, h = tBuf.get_size()
for j in range(h):
for i in range(w):
colorA = tBuf.get_at((i, j))
gray = (colorA[0] + colorA[1] + colorA[2]) / 3
tBuf.set_at((i, j), (gray, gray, gray, 255))
while True:
_gScr.blit(tBuf, (0, 0), tBuf.get_rect())
pygame.display.update()
pygame.time.wait(10)
3.セピア変換
次にセピア変換を。
import pygame
_gSrc = None
pygame.init()
pygame.display.set_mode((150, 150), 0, 32)
pygame.display.set_caption("セピア変換")
_gScr = pygame.display.get_surface()
tBuf = pygame.image.load("kenmo.jpg").convert()
# セピア変換
w, h = tBuf.get_size()
for j in range(h):
for i in range(w):
colorA = tBuf.get_at((i, j))
gray = (colorA[0] + colorA[1] + colorA[2]) / 3
tBuf.set_at((i, j), (gray * 1, gray * 0.8, gray * 0.6, 255))
while True:
_gScr.blit(tBuf, (0, 0), tBuf.get_rect())
pygame.display.update()
pygame.time.wait(10)
4.2値変換
続いて、2値変換を。
import pygame
_gSrc = None
pygame.init()
pygame.display.set_mode((150, 150), 0, 32)
pygame.display.set_caption("2値変換")
_gScr = pygame.display.get_surface()
tBuf = pygame.image.load("kenmo.jpg").convert()
threshold = 127 # 閾値
# 2値変換
w, h = tBuf.get_size()
for j in range(h):
for i in range(w):
colorA = tBuf.get_at((i, j))
gray = (colorA[0] + colorA[1] + colorA[2]) / 3
if(threshold > gray):
colorA = (255, 255, 255, 255)
else:
colorA = (0, 0, 0, 255)
tBuf.set_at((i, j), colorA)
while True:
_gScr.blit(tBuf, (0, 0), tBuf.get_rect())
pygame.display.update()
pygame.time.wait(10)
5.RGB抽出
RGB抽出を。
import pygame
_gSrc = None
pygame.init()
pygame.display.set_mode((150, 150), 0, 32)
pygame.display.set_caption("RGB抽出")
_gScr = pygame.display.get_surface()
tBuf = pygame.image.load("kenmo.jpg").convert()
# RGB抽出
w, h = tBuf.get_size()
for j in range(h):
for i in range(w):
colorA = tBuf.get_at((i, j))
# R成分抽出
tBuf.set_at((i, j), (colorA[0], 0, 0, 255))
while True:
_gScr.blit(tBuf, (0, 0), tBuf.get_rect())
pygame.display.update()
pygame.time.wait(10)
6.RGB成分入れ替え
RGB成分入れ替えです。
import pygame
_gSrc = None
pygame.init()
pygame.display.set_mode((150, 150), 0, 32)
pygame.display.set_caption("RGB成分入れ替え")
_gScr = pygame.display.get_surface()
tBuf = pygame.image.load("kenmo.jpg").convert()
# RGB成分入れ替え
w, h = tBuf.get_size()
for j in range(h):
for i in range(w):
colorA = tBuf.get_at((i, j))
# RGBをGRBに
tBuf.set_at((i, j), (colorA[1], colorA[0], colorA[2], 255))
while True:
_gScr.blit(tBuf, (0, 0), tBuf.get_rect())
pygame.display.update()
pygame.time.wait(10)
7.ネガ変換
ネガ変換です。
import pygame
_gSrc = None
pygame.init()
pygame.display.set_mode((150, 150), 0, 32)
pygame.display.set_caption("ネガ変換")
_gScr = pygame.display.get_surface()
tBuf = pygame.image.load("kenmo.jpg").convert()
# ネガ変換
w, h = tBuf.get_size()
for j in range(h):
for i in range(w):
colorA = tBuf.get_at((i, j))
r = 255 - colorA[0]
g = 255 - colorA[1]
b = 255 - colorA[2]
# 色の反転
tBuf.set_at((i, j), (r, g, b, 255))
while True:
_gScr.blit(tBuf, (0, 0), tBuf.get_rect())
pygame.display.update()
pygame.time.wait(10)
8.輪郭抽出
輪郭抽出です。
大きめの画像でやると、そこそこキレイに抽出できますね。
import pygame
import math
_gSrc = None
pygame.init()
pygame.display.set_mode((150, 150), 0, 32)
pygame.display.set_caption("輪郭抽出")
_gScr = pygame.display.get_surface()
tBuf = pygame.image.load("kenmo.jpg").convert()
tblGray = []
# グレースケールテーブル作成
for j in range(tBuf.get_height()):
w = []
for i in range(tBuf.get_width()):
colorA = tBuf.get_at((i, j))
gray = (colorA[0] + colorA[1] + colorA[2]) / 3
w.append(gray)
tblGray.append(w)
# 輪郭抽出(グラディエント法)
for j in range(tBuf.get_height() - 1):
for i in range(tBuf.get_width() - 1):
# 微分、というか差分
dx = tblGray[j][i+1] - tblGray[j][i]
dy = tblGray[j+1][i] - tblGray[j][i]
#tblGray[j][i] = math.sqrt(dx ** 2 + dy ** 2)
tblGray[j][i] = abs(dx) + abs(dy) # 高速化
# 2値化
AMP = 5 # 出力レベル
BLACK = (0, 0, 0, 255)
WHITE = (255, 255, 255, 255)
for j in range(tBuf.get_height() - 1):
for i in range(tBuf.get_width() - 1):
if(tblGray[j][i] > AMP):
tBuf.set_at((i, j), WHITE)
else:
tBuf.set_at((i, j), BLACK)
while True:
_gScr.blit(tBuf, (0, 0), tBuf.get_rect())
pygame.display.update()
pygame.time.wait(10)
ノイズが多い場合は出力レベルを上げるとキレイになりますよー。
9.グレースケールの改良版
グレースケールの改良版です。
人の目は緑に最も良く反応し、続いて赤、青という反応をします。
よって、このように重みをかけると、自然なグレースケールになるわけです。
import pygame
import math
_gSrc = None
def main():
pygame.init()
pygame.display.set_mode((250, 250), 0, 32)
pygame.display.set_caption("グレースケール2")
_gScr = pygame.display.get_surface()
tBuf = pygame.image.load("nyan.bmp").convert()
for j in range(tBuf.get_height()):
for i in range(tBuf.get_width()):
rgba = tBuf.get_at((i, j))
gray = (
rgba[0] * 0.299 # r
+ rgba[1] * 0.587 # g
+ rgba[2] * 0.114 # b
) / 3
tBuf.set_at((i, j), (gray, gray, gray, 255))
while True:
_gScr.blit(tBuf, (0, 0), tBuf.get_rect())
pygame.display.update()
for e in pygame.event.get():
if e.type == pygame.QUIT: return
pygame.time.wait(10)
if __name__ == '__main__':
main()
10.モザイク化
モザイク化です。
画面遷移時に使えますね。(ただ、重いから使えないかな…)
import pygame
import math
# Mosaic
# @param tBuf サーフェス
# @param RECT モザイクをかける範囲
# @param SIZE モザイクの大きさ
def transMosaic(tBuf, RECT, SIZE):
if(SIZE < 1): return None
retBuf = pygame.transform.scale(tBuf, tBuf.get_size())
for j in range(RECT.top, RECT.bottom, SIZE):
for i in range(RECT.left, RECT.right, SIZE):
colorSum = 0, 0, 0
for b in range(SIZE):
for a in range(SIZE):
rgba = tBuf.get_at((i+a, j+b))
colorSum = (
colorSum[0] + rgba[0],
colorSum[1] + rgba[1],
colorSum[2] + rgba[2])
colorSum = (
colorSum[0] / ((SIZE)**2),
colorSum[1] / ((SIZE)**2),
colorSum[2] / ((SIZE)**2),
255)
for b in range(SIZE):
for a in range(SIZE):
retBuf.set_at((i+a, j+b), colorSum)
return retBuf
# Main
def main():
pygame.init()
pygame.display.set_mode((250, 250), 0, 32)
pygame.display.set_caption("モザイク")
_gScr = pygame.display.get_surface()
tBuf = pygame.image.load("nyan.bmp").convert()
i = 1
while True:
dstBuf = transMosaic(tBuf, pygame.Rect(50, 50, 100, 100), i)
i += 1
if(i > 50): i = 1
_gScr.blit(dstBuf, (0, 0), dstBuf.get_rect())
pygame.display.update()
for e in pygame.event.get():
if e.type == pygame.QUIT: return
pygame.time.wait(10)
if __name__ == '__main__':
main()
11.ぼかし
ぼかしです。
import pygame
import math
# ぼかし
# @param tBuf サーフェス
# @return 変換後のサーフェス
def transBlur(tBuf):
retBuf = pygame.transform.scale(tBuf, tBuf.get_size())
for j in range(1, retBuf.get_height()-1):
for i in range(1, retBuf.get_width()-1):
color1 = tBuf.get_at((i, j-1))
color2 = tBuf.get_at((i-1, j))
color3 = tBuf.get_at((i, j+1))
color4 = tBuf.get_at((i+1, j))
color5 = tBuf.get_at((i, j))
color = (
(color1[0]+color2[0]+color3[0]+color4[0]+color5[0])/5,
(color1[1]+color2[1]+color3[1]+color4[1]+color5[1])/5,
(color1[2]+color2[2]+color3[2]+color4[2]+color5[2])/5,
255)
retBuf.set_at((i, j), color)
return retBuf
# Main
def main():
pygame.init()
pygame.display.set_mode((250, 250), 0, 32)
pygame.display.set_caption("ぼかし")
_gScr = pygame.display.get_surface()
tBuf = pygame.image.load("nyan.bmp").convert()
i = 32
while True:
tBuf = transBlur(tBuf)
_gScr.blit(tBuf, (0, 0), tBuf.get_rect())
pygame.display.update()
for e in pygame.event.get():
if e.type == pygame.QUIT: return
pygame.time.wait(10)
if __name__ == '__main__':
main()
12.モーションブラー
左上方向のモーションブラーです。
import pygame
import math
# モーションブラー(左上)
# @param tBuf サーフェス
# @return 変換後のサーフェス
def transBlur(tBuf):
retBuf = pygame.transform.scale(tBuf, tBuf.get_size())
for j in range(retBuf.get_height()-5):
for i in range(retBuf.get_width()-5):
color1 = tBuf.get_at((i, j))
color2 = tBuf.get_at((i+1, j+1))
color3 = tBuf.get_at((i+2, j+2))
color4 = tBuf.get_at((i+3, j+3))
color5 = tBuf.get_at((i+4, j+4))
color = (
(color1[0]+color2[0]+color3[0]+color4[0]+color5[0])/5,
(color1[1]+color2[1]+color3[1]+color4[1]+color5[1])/5,
(color1[2]+color2[2]+color3[2]+color4[2]+color5[2])/5,
255)
retBuf.set_at((i, j), color)
return retBuf
# Main
def main():
pygame.init()
pygame.display.set_mode((250, 250), 0, 32)
pygame.display.set_caption("ぼかし")
_gScr = pygame.display.get_surface()
tBuf = pygame.image.load("nyan.bmp").convert()
i = 32
while True:
tBuf = transBlur(tBuf)
_gScr.blit(tBuf, (0, 0), tBuf.get_rect())
pygame.display.update()
for e in pygame.event.get():
if e.type == pygame.QUIT: return
pygame.time.wait(10)
if __name__ == '__main__':
main()
13.鮮鋭化
鮮鋭化です。
import pygame
import math
def saturate(param):
if(param < 0): ret = 0
elif(param > 255): ret = 255
else: ret = param
return ret
# 鮮鋭化
# @param tBuf サーフェス
# @return 変換後のサーフェス
def transSharp(tBuf):
retBuf = pygame.transform.scale(tBuf, tBuf.get_size())
for j in range(1, retBuf.get_height()-1):
for i in range(1, retBuf.get_width()-1):
color1 = tBuf.get_at((i, j))
color2 = tBuf.get_at((i-1, j))
color3 = tBuf.get_at((i+1, j))
color4 = tBuf.get_at((i, j-1))
color5 = tBuf.get_at((i, j+1))
color = (
saturate(color1[0]-((color2[0]+color3[0]+color4[0]+color5[0])-(color1[0]*4))),
saturate(color1[1]-((color2[1]+color3[1]+color4[1]+color5[1])-(color1[1]*4))),
saturate(color1[2]-((color2[2]+color3[2]+color4[2]+color5[2])-(color1[2]*4))),
255)
retBuf.set_at((i, j), color)
return retBuf
# Main
def main():
pygame.init()
pygame.display.set_mode((250, 250), 0, 32)
pygame.display.set_caption("鮮鋭化")
_gScr = pygame.display.get_surface()
tBuf = pygame.image.load("nyan.bmp").convert()
tBuf = transSharp(tBuf)
while True:
_gScr.blit(tBuf, (0, 0), tBuf.get_rect())
pygame.display.update()
for e in pygame.event.get():
if e.type == pygame.QUIT: return
pygame.time.wait(10)
if __name__ == '__main__':
main()