質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
Jupyter

Jupyter (旧IPython notebook)は、Notebook形式でドキュメント作成し、プログラムの記述・実行、その実行結果を記録するツールです。メモの作成や保存、共有、確認などもブラウザ上で行うことができます。

OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

0回答

498閲覧

真っ黒のpng画像の特定の画素値を透明化する。

osumosan

総合スコア11

Jupyter

Jupyter (旧IPython notebook)は、Notebook形式でドキュメント作成し、プログラムの記述・実行、その実行結果を記録するツールです。メモの作成や保存、共有、確認などもブラウザ上で行うことができます。

OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2022/12/18 08:38

編集2022/12/18 16:53

前提

https://teratail.com/questions/0vl3yd7kmwsl47
こちらの質問の続きです。動画から得られた画像に対して学習モデルを用いた検出はできるようになりました。その続きになります。

python

1import segmentation_models as sm 2sm.set_framework('tf.keras') 3sm.framework() 4import glob 5import matplotlib.pyplot as plt 6import tensorflow as tf 7import numpy as np 8import cv2 9import os 10import shutil 11import re 12 13from tensorflow.python.keras.models import load_model 14from PIL import Image 15 16#データセット 17x_image_size = 320 #インプット画像のサイズ 18y_image_size = 224 #インプット画像のサイズ 19 20#画像表示の関数 21def visualize(**images): 22 n = len(images) 23 plt.figure(figsize=(32, 16)) 24 for i, (name, image) in enumerate(images.items()): 25 plt.subplot(1, n, i + 1) 26 plt.xticks([]) 27 plt.yticks([]) 28 plt.title(' '.join(name.split('_')).title()) 29 plt.imshow(image) 30 plt.show() 31 32def atoi(text): 33 return int(text) if text.isdigit() else text 34 35def natural_keys(text): 36 return [ atoi(c) for c in re.split(r'(\d+)', text) ] 37 38#判別したい画像群用配列 39TestImgArray = [] 40 41#TestImageディレクトリ内の画像をTestIArrayに格納していく 42dir = 'C:/Users/XXXX/Desktop/VideoImage/VideoImages' 43dir_NumSum = sorted(glob.glob(dir+"/*.png"), key = natural_keys) 44for i, file in enumerate(dir_NumSum): 45 image = Image.open(file) #画像の読み込み 46 image = image.convert("RGB") #RGBに変換 47 image = image.resize((x_image_size, y_image_size)) #サイズ変更 48 image = np.asarray(image) #画像データを配列へ変更 49 image = np.expand_dims(image, axis=0) 50 pr_mask = model.predict(image) 51 52 #抽出画像の描画 53 visualize( 54 image = image.squeeze(), 55 A_Prediction = pr_mask[..., 1].squeeze(), 56 B_Prediction = pr_mask[..., 2].squeeze(), 57 ) 58 59 print(type(A_Prediction)) 60 61 #顔部分のマスクを取得 62 A_Prediction = pr_mask[..., 1].squeeze() 63 cv2.imwrite("C:/Users/XXXX/Desktop/VideoImage/MaskImages/FaceMasks/FaceMask_%d.png" % i, A_Prediction) 64 65 #口部部分のマスクを取得 66 B_Prediction = pr_mask[..., 2].squeeze() 67 cv2.imwrite("C:/Users/XXXX/Desktop/VideoImage/MaskImages/MouthMasks/MouthMask_%d.png" % i, B_Prediction)

できたこと

皆様のご助力のおかげで、リンク先で質問させていただいたことは解決いたしました。
次は、取得できた画像(学習モデルが判別した顔パーツ)から、マスク画像の生成を行おうとしています。
取得できた画像は以下のように真っ黒なのですが、学習モデルがパーツを判別した部分の画素値は[1, 1, 1]となっています。
学習モデルから得られたpng画像

これより、画素値が[0, 0, 0]となっている個所を透過させるプログラムを作成し、以下の画像が得られました。

python

1#ライブラリの読み込み 2import cv2 3import numpy as np 4import glob 5import re 6import matplotlib.pyplot as plt 7 8from IPython.display import Image, display 9 10MaskPath = "C:/Users/XXXX/Desktop/VideoImage/MaskImages/FaceMasks/" 11ClearPath = "C:/Users/XXXX/Desktop/VideoImage/MaskImages/ClearMask/" 12 13i = 0 14 15for i in range(300): 16 img = cv2.imread(MaskPath + "FaceMask_" + str(i)+".png") 17 18 #マスク画像を生成 19 mask = np.all(img[:] == [0], axis=-1) 20 21 # 元画像をBGR形式からBGRA形式に変換 22 dst = cv2.cvtColor(img, cv2.COLOR_BGR2BGRA) 23 24 #マスク画像をもとに透明化 25 dst[mask,3] = 0 26 27 #画像保存 28 cv2.imwrite(ClearPath+str(i)+"result.png", dst) 29 30 i += 1

画素値[1, 1, 1]のみを表示

やりたいこと

動画から画像を取得しているので、30fps, 10秒の動画の場合、300枚の画像が取得されます。
現状の流れとしましては

  1. 動画から取得された300枚の画像1枚1枚にパーツの判別を行う。
  2. 「できたこと」であげたような真っ黒な画像が300枚(600枚)生成されるので、これを専用のディレクトリに保存。(最初のプログラム63行目, 67行目)
  3. 専用ディレクトリに格納された300枚の画像一枚一枚に対して、透過の処理を行う。(2番目のプログラム)

という操作をしています。

これを、最初のプログラムだけで完結させることはできないか
(3.を、最初のプログラムの専用ディレクトに保存する段階でできないか)

python

1 #顔部分のマスクを取得 2 A_Prediction = pr_mask[..., 1].squeeze() 3 cv2.imwrite("C:/Users/XXXX/Desktop/VideoImage/MaskImages/FaceMasks/FaceMask_%d.png" % i, A_Prediction) 4 5 #口部部分のマスクを取得 6 B_Prediction = pr_mask[..., 2].squeeze() 7 cv2.imwrite("C:/Users/XXXX/Desktop/VideoImage/MaskImages/MouthMasks/MouthMask_%d.png" % i, B_Prediction)

が一番やりたいことで、
それが無理ならば3.の処理を行いたいのですが、エラーが発生してしまい詰まっています。

発生している問題・エラーメッセージ

2番目のプログラムを実行すると以下のエラーが発生します。

TypeError Traceback (most recent call last) \AppData\Local\Temp\ipykernel_19140\2419611442.py in <module> 9 10 #マスク画像を生成 ---> 11 mask = np.all(img[:] == [0], axis=-1) 12 13 # 元画像をBGR形式からBGRA形式に変換 TypeError: 'NoneType' object is not subscriptable

試したこと

試したことと言いますか、2番目のプログラムは最初の数枚程度であれば透過画像を出力してくれるので、途中で止まる理由がわかりません。
2番目のプログラムの15行目、0~300という指定を行っているのにディレクトリ内に100枚しか画像がなく、実行の途中で存在しない画像を参照しようとすることが原因のエラーでした。大変失礼しました。また、2番目のプログラムは改変を行い、真っ黒画像から透過画像を作成するプログラムを以下のように改変しました。

python

1#ライブラリの読み込み 2import cv2 3import numpy as np 4import glob 5import re 6import matplotlib.pyplot as plt 7 8from IPython.display import Image, display 9 10def atoi(text): 11 return int(text) if text.isdigit() else text 12 13def natural_keys(text): 14 return [ atoi(c) for c in re.split(r'(\d+)', text) ] 15 16dir = 'C:/Users/XXXX/Desktop/VideoImage/MaskImages/FaceMasks' 17dir_NumSum = sorted(glob.glob(dir+"/*.png"), key = natural_keys) 18for i, file in enumerate(dir_NumSum): 19 img = cv2.imread(file) 20 21 #透過処理 22 mask = np.all(img[:] == [0], axis=-1) 23 dst = cv2.cvtColor(img, cv2.COLOR_BGR2BGRA) 24 dst[mask,3] = 0 25 26 #画像保存 27 cv2.imwrite("C:/Users/XXXX/Desktop/VideoImage/MaskImages/ClearMask/ClearMask_%d.png" % i, dst)

先ほども申し上げた通り 変更後のプログラムにせよ、最初のプログラムで真っ黒のpng画像を取得して、2番目のプログラムで透過作業を行うことは変わっていません。素人ながらに冗長だと思いますので、最初のプログラムで透過までできる方法があればアドバイス頂けたらと思います。何卒よろしくお願い申し上げます。

補足情報(FW/ツールのバージョンなど)

実行環境
・CPU:windows11
・GPU:RTX3060
・メモリ:16GB

構築環境
・CUDA 11.0
・cuDNN 8.0
・tensorflow-gpu == 2.4.0
・python 3.7

備考
・利用モデルはSegmentation models
・Jupyter notebook上での動作を想定

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

meg_

2022/12/18 11:34

> 試したことと言いますか、2番目のプログラムは最初の数枚程度であれば透過画像を出力してくれるので、途中で止まる理由がわかりません。 特定の画像で止まるのでしょうか?ランダムでしょうか?
osumosan

2022/12/18 16:36

コメント頂き、ありがとうございます。 自分でもう一度確認したところ、単純に2番目のプログラムでfor文の指定を300にしているにもかかわらず、ディレクトリ内に画像が300未満しか入っていないことによるエラーでした… ディレクトリに100枚しか画像がないのに、101枚目を参照したら、そりゃエラーになりますよね…お騒がせしました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問