LoginSignup
17
16

More than 3 years have passed since last update.

OpenCVでトリミングする ~覗き動画を作る~

Posted at

はじめに

釣りタイトルっぽいな。

OpenCVでトリミング

OpenCVのタイプはnumpy.ndarray。だからスライスでその一部を取り出すことができる。
行列だから行・列の順。行列だから「どの行(列)からどの行(列)まで」を指定する。「左上座標と切り取るサイズ」ではない。
要はimg[r1: r2, c1: c2]だが、理屈を理解すれば img[r: r+h, c: c+w] という書き方を暗記するのは容易だ。

ところで、左上座標を x, y = …と定義したとき、サイズの書き方は h, w = … と w, h = … のどちらが適切なのだろうか。小学校算数のかけ算の順序問題が話題になっている昨今、必修化されるプログラミング教育の授業で本件は新たな火種となってしまう可能性がある。

なお、トリミングは当然PIL(Pillow)でもできるが、PILの仕様を書くと混乱してしまうのでここではいっさい触れない。

基本的なプログラム

trim.py
import cv2

filename = "nurse.jpg"
img = cv2.imread(filename)

x, y = 380, 30
h, w = 160, 120
img_trim = img[y:y+h, x:x+w]

cv2.imshow("origin", img)
cv2.imshow("trim", img_trim)
cv2.imwrite("trimmed_image.jpg", img_trim)

cv2.waitKey(0)
cv2.destroyAllWindows()

元画像(スキマナース)から、
bakudan.jpg
(x,y)=(380,30)から始まる高さ160×幅120のエリアを取り出すことができた。
trim.jpg
もちろん、顔認識を入れれば位置やサイズを手打ちする必要はなくなる。

OpenCVで画像を保存 cv2.imwrite()

cv2.imwrite(filename, mat) という使い方をする。
filenameはファイル名。画像フォーマットはファイル名の拡張子で自動的に決まる。
matは画像データ。

応用例

これだけでは面白くないので、ループを回しながらトリミング位置を変えるというプログラムを書いてみた。

peep.py
import cv2
from PIL import Image

filename = "nurse.jpg"
img = cv2.imread(filename)
imgH, imgW = img.shape[:2]

# ご自由にどうぞ
x, y = 50, 100
dx,dy = 2, 3
h, w = 160, 160

imgs=[]
while True:
    if 0 <= x+dx <= imgW-w : #こんな書き方ができるんだねえ。
        x = x+dx
    else:
        dx = -dx

    if 0 <= y+dy <= imgH-h :
        y = y+dy
    else:
        dy = -dy

    window = img[y:y+h, x:x+w]
    cv2.imshow("", window)

# この一文を有効にするとどうなるか君の目で確かめてくれ!
#    cv2.moveWindow("", x+100, y+100)

    imgPIL=Image.fromarray(window[:,:,::-1])
    imgs.append(imgPIL)

    if cv2.waitKey(1) & 0xFF == ord("q"):
        break

cv2.destroyAllWindows()
imgs[0].save("peep.gif", save_all=True,
             append_images=imgs[1:], optimize=False,
             duration=20, loop=0)

このプログラムにより、こんなアニメーションGIFが作られる。
peep.gif

この手のゲームをピープホール(覗き穴)と呼ぶと昔ベーマガで読んだのだが、この言葉が使われているのを見たことがないぞ。

終わりに

Excelにはじめて触れたとき、R1C1形式を見て「RとC、どっちが行でどっちが列なんだ!」「Rが行でCが列なのはわかったけど、xy座標はx,yと書くのに行列がRCだと並びが逆じゃないか!」と憤ったことを思い出す。
その違和感とまた付き合うことになるとは思わなかった。

17
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
16