0
0

OpemCVでimshowしたときとimwriteしたときで色が違うときの原因と対策

Posted at

事件

アルファ付きpng画像を重ねて表示したいときに事件は起きた。imreadで背景画像を読み込んだ時には大丈夫なのに、真っ白なキャンバスを生成するためにnp.zerosを使ったときに問題発生。cv2.cvshowで表示したときに色がおかしくなる。cv2.imwriteで書き出すと思っていた通りの色が出る

この記事を参考に(ほぼコピペ)、背景画像を読み込むところを、真っ白い画像を生成することによって代替した。
真っ白い画像を生成する(4,5行目)のは適当にググった ←伏線

問題のソースコード(間違ったソースコード)
import cv2
import numpy as np

frame = np.zeros((720, 1280, 3)) #真っ黒画像(ゼロ埋め)
frame += 255 #真っ白画像を生成

#frame = cv2.imread("bg.jpg") #特定の画像を読み込むわけではない
png_image = cv2.imread("alpha.png", cv2.IMREAD_UNCHANGED)  # アルファチャンネル込みで読み込む

# 貼り付け先座標の設定。とりあえず左上に
x1, y1, x2, y2 = 0, 0, png_image.shape[1], png_image.shape[0]

# 合成!
frame[y1:y2, x1:x2] = frame[y1:y2, x1:x2] * (1 - png_image[:, :, 3:] / 255) + \
                      png_image[:, :, :3] * (png_image[:, :, 3:] / 255)

cv2.imwrite("out.png",frame)
cv2.imshow("window",frame)
cv2.waitKey(0)

↓alpha.png
alpha.png

結果

↓cv2.imshowで出したウィンドウ
image.png
↓out.png
out.png

imshowで出したウィンドウは、明らかにおかしい。なんというか、アルファチャンネルが読み込めていないようにも見える(アルファ値255のみが見えているように感じる)。しかし、よく見るとカラフルな線が黒い枠線に重なったところが白抜きされてるなど様子が変だ。(黒い枠線はどう考えてもアルファ値255である)

対策

4行目frame=np.zeros()としてnp配列を作成して画像としている。どうやらnp.zerosのdtype引数はデフォルトでfloatとなっているらしい。しかしopenCVで使用するのはnp.uint8らしく、どうやらこれが原因だったらしい。
と、後になって調べてみると、np.zerosで生成するときにほとんどの記事でdtype=np.uint8を指定しているではないか。適当にググったのが仇となってしまった。 ←伏線回収
ちなみにunit(ユニット)と見間違えやすいがこれはunsigned intのことである。

対策したソースコード
import cv2
import numpy as np

frame = np.zeros((720, 1280, 3),dtype=np.uint8) #真っ黒画像(ゼロ埋め)
frame += 255 #真っ白画像を生成

#frame = cv2.imread("bg.jpg") #特定の画像を読み込むわけではない
png_image = cv2.imread("alpha.png", -1)  # アルファチャンネル込みで読み込む

# 貼り付け先座標の設定。とりあえず左上に
x1, y1, x2, y2 = 0, 0, png_image.shape[1], png_image.shape[0]

# 合成!
frame[y1:y2, x1:x2] = frame[y1:y2, x1:x2] * (1 - png_image[:, :, 3:] / 255) + \
                      png_image[:, :, :3] * (png_image[:, :, 3:] / 255)

cv2.imwrite("out.png",frame)
cv2.imshow("window",frame)
cv2.waitKey(0)

余談だがimreadでアルファチャンネルを読み込むならfilenameの次に-1で良い。こっそり直してみた

修正後

↓想像通りの画像をimshowすることができた
image.png

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