#はじめに
Pythonの画像処理の定番はOpenCVかPILでしょう。
今回、PNG画像をOpenCVで処理をしていた時にどうもうまく動かないことがあったので、備忘録として書いておきます。
ちなみにαチャンネルとは透明の部分です。
#要約
αチャンネルを含んだpngをcv2.imread(img)
で読み込むとαチャンネルが削除されたndarrayになるよ
αチャンネルも読み込みたかったらcv2.imread(frame, -1)
みたいに引数に-1を渡すよ
opencvの全角文字非対応対策としてnumpyで読み込んでから変換したものはαチャンネルを含んでいるよ
opencvを使って動画を書き込む際はαチャンネルを含んでいちゃいけないよ
#本文
現在画像を使って動画を作成しています。
私の環境ではフォルダに全角文字を使用しているので、普通のcv2.imread(img)
ではパスに半角文字しか使えないため、画像を読み込めないです。
対策としてこのようにnumpyで読み込んでからRGBの順番を変更するという方法があります。
というのもcv2.imread(img)
はnumpyのndarrayとして画像を扱うからです。
import cv2
import numpy as np
buf = np.fromfile(img_path, np.uint8)
img = cv2.imdecode(buf, cv2.IMREAD_UNCHANGED)
しかし問題があり、cv2.imread(img)
ではpngのαチャンネルを削除して読み込むのに対し、上のコードだとαチャンネルまで読み込んでしまいます。
具体的には、高さ720、幅528の画像を読み込んだ際、
cv2.imread(img)
では(720,528,3)のサイズの配列となり、(3はRGB)
上のコードで読み込むと(720,528,4)のサイズの配列となります。(4はαRGB)
さらに問題なのはopencvで動画を作成するときの画像はRGBでなければいけないということです。
そのためnumpyで読み込み、その後αチャンネルを削除する必要があります。
さらに問題なのは、pngはαチャンネルを含むものと含まないものがあることです。
これらを加味して、全角パスのpngを読み込んでRGBに変換するコードがこちらです。
buf = np.fromfile(frame, np.uint8)
img = cv2.imdecode(buf, cv2.IMREAD_UNCHANGED)
if img.shape[2] == 4:
img = np.delete(img, 3, axis=2)
#まとめ
opencvは便利な反面、全角文字に対応していないのが一番の弱点ですよね