Up

OpenCVで用意した画像のPyGameによる表示

 

画像の回転をOpenCVを利用して行い、回転した画像をPyGameで連続的に提示すると、画像が回転しているように見える。例えば、図1の画像を横方向に回転することを考える。

 

図1

 

リストのスクリプトを実行すると、図2に示すように横方向に回転しているように見える動画が表示される。ファイルは、圧縮ファイルusingopencvfiles.zipにまとめた。

 

 − 

図2

 

リスト1のスクリプトで用いているOpenCVのライブラリは、コマンド

 

pip install opencv-python

 

でインストールできる。インストールしたライブラリは、次のコードでimportできる。

 

import cv2

 

リスト1のスクリプトを実行すると、次のスクリプトで画像ファイルsample.pngが読み込まれて表示される。

 

img1 = cv2.imread('sample.png')

img2 = cv2.cvtColor(img1, cv2.COLOR_BGR2RGB)  #   RGBに変換

plt.imshow(img2)

plt.show()

 

表示する前に、画像の色をRGBに並べ替えていることに注意。

表示画像(図1)のWindowを閉じると(右上角のX印をクリック)、画像の回転(横方向)に合わせた横方向収縮画像の作成とPyGamesurfaceのリストへの格納が、次のスクリプトで行われる。

 

surfaces = []

for i in range(38):

    ck_time = time.perf_counter()

    t_angl = i * 2 * np.pi/38        #   回転角

    s_ps = np.array([[img_w//2, 0], [img_w//2, img_h], [0, 0]], dtype=np.float32)

    d_ps = np.array([[img_w//2, 0], [img_w//2, img_h],

                     [int((img_w//2)*(1 - np.cos(t_angl))), 0]],

                     dtype=np.float32)

    t_mat = cv2.getAffineTransform(s_ps, d_ps)        #   変換行列

    t_img = cv2.warpAffine(img1, t_mat, (img_w, img_h))   #   画像の変換

 

    cv2.imwrite('temp.png', t_img)                    #   変換画像をファイルに保存

    surfaces.append(pg.image.load('temp.png'))    #   保存画像ファイルをPyGame用画像として

                                                      #   スクリーンのリストに格納

 

画像の縦方向の中心、[img_w//2, 0][img_w//2, img_h]結ぶ線、を固定して、左上の点[0, 0]を回転角t_anglの回転に対応する点[int((img_w//2)*(1 - np.cos(t_angl))), 0]に変換する行列t_matを求めて、変換画像t_imgを算出している。

 

回転画像のsurfaceのリストの作成後、次のスクリプトで1枚ずつ順番に提示している。

 

ck = True                       #   while文のコントロール用

img_id = 0                      #   表示画像のid

size_L = len(surfaces)  

ck_time = time.perf_counter()   #   画面の更新間隔のコントロール用

while ck:

    screen.blit(surfaces[img_id], (100, 100))

    img_id += 1

    if img_id >= size_L:

        img_id = 0

 

提示の時間間隔は次のコードで行っている。

 

    while time.perf_counter() < ck_time + 0.1:  #  画面の更新間隔を0.1秒とする

        pass

    pg.display.flip()      

    ck_time = time.perf_counter()

 

スクリプトの実行終了は、次のコードでWindowのクローズボタンがクリックされたかどうかのチェックにより行っている。

 

    for e in pg.event.get():

        if e.type == pg.QUIT:  #  Close Windowボタンがクリックされたか

            ck = False         #  while文の終了

 

クリックされていたらckFalseに設定してwhile文を終了している。

 

他の画像で試みる場合は、次のコードにおけるファイル名'sample.png'を該当の画像ファイル名に置き換えればよい。

 

img1 = cv2.imread('sample.png')

 

 

 

 

リスト1

 

import pygame as pg

import cv2          # pip install opencv-python

import numpy as np

import matplotlib.pyplot as plt

import time

 

pg.init()      #   PyGameの初期化

 

img1 = cv2.imread('sample.png')

img2 = cv2.cvtColor(img1, cv2.COLOR_BGR2RGB)  #   RGBに変換

plt.imshow(img2)

plt.show()

(img_h, img_w, _) = img1.shape                 #   画像配列のサイズ

print(img_h, img_w)

surfaces = []

for i in range(38):

    ck_time = time.perf_counter()

    t_angl = i * 2 * np.pi/38        #   回転角

    s_ps = np.array([[img_w//2, 0], [img_w//2, img_h], [0, 0]], dtype=np.float32)

    d_ps = np.array([[img_w//2, 0], [img_w//2, img_h],

                     [int((img_w//2)*(1 - np.cos(t_angl))), 0]],

                     dtype=np.float32)

    t_mat = cv2.getAffineTransform(s_ps, d_ps)        #   変換行列

    t_img = cv2.warpAffine(img1, t_mat, (img_w, img_h))   #   画像の変換

 

    cv2.imwrite('temp.png', t_img)                    #   変換画像をファイルに保存

    surfaces.append(pg.image.load('temp.png'))    #   保存画像ファイルをPyGame用画像として

                                                      #   スクリーンのリストに格納

    print(f'{i+1}/38')

 

print(len(surfaces))

 

screen  = pg.display.set_mode((img_w+200, img_h+200))    #  表示画面のサイズ

pg.display.set_caption('Using OpenCV')

screen.fill((0, 0, 0))

 

ck = True                       #   while文のコントロール用

img_id = 0                      #   表示画像のid

size_L = len(surfaces)  

ck_time = time.perf_counter()   #   画面の更新間隔のコントロール用

while ck:

    screen.blit(surfaces[img_id], (100, 100))

    img_id += 1

    if img_id >= size_L:

        img_id = 0

 

    while time.perf_counter() < ck_time + 0.1:  #  画面の更新間隔を0.1秒とする

        pass

    pg.display.flip()      

    ck_time = time.perf_counter()

 

   

    for e in pg.event.get():

        if e.type == pg.QUIT:  #  Close Windowボタンがクリックされたか

            ck = False         #  while文の終了

 

pg.quit()     #   PyGameの終了

 

 

 

 

Home