LoginSignup
3
3

More than 1 year has passed since last update.

OpenCVでαチャンネルを含んだpng画像を読み込む時の注意

Last updated at Posted at 2021-11-27

はじめに

Pythonの画像処理の定番はOpenCVかPILでしょう。

今回、PNG画像をOpenCVで処理をしていた時にどうもうまく動かないことがあったので、備忘録として書いておきます。

ちなみにαチャンネルとは透明の部分です。

image.png

要約

αチャンネルを含んだ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)

image.png

上のコードで読み込むと(720,528,4)のサイズの配列となります。(4はαRGB)

image.png

さらに問題なのは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は便利な反面、全角文字に対応していないのが一番の弱点ですよね

3
3
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
3
3