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

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

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

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

パス

パス(path)はファイルシステムの場所(階層)を明示したものです。

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

Python

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

Q&A

解決済

1回答

1793閲覧

OpenCVではない新しい顔認識ライブラリを全角パスに対応させたい

TakayukiMoriya

総合スコア26

OpenCV

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

パス

パス(path)はファイルシステムの場所(階層)を明示したものです。

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

Python

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

0グッド

0クリップ

投稿2021/12/31 01:24

#これまでやってきたこと

①OpenCVを使ってJPG画像を顔認識、顔の座標データ(x,y,w,h)を取得
②この座標データを使ってOpenCVでトリミング、文字挿入

上記①〜②の処理をこなす画像処理ツールを作ってきました

#トライしようとしたこと
このツールを更にパワーアップさせるため、以下の2点を盛り込もうとしました
・日本語パスに対応(デフォルトだとOpenCVが全角パスを読めないので)
・顔認識処理の部分をOpenCVではない更に高度なRetinafaceというライブラリに置き換える

そこで、解説本やRetinaFaceのGitHubページ(https://github.com/serengil/retinaface)を参考に以下のコードを作成しました。

Python

1from retinaface import RetinaFace 2import cv2 3import os 4 5def imread2(filename, flags=cv2.IMREAD_COLOR):#OpneCVを日本語パスに対応させる定義 6 buf = np.fromfile(filename, np.uint8) 7 img = cv2.imdecode(buf, flags) 8 return img 9 10def find_all_files(directory):#ディレクトリ以下全てをリスト化する定義 11 for root, dirs, files in os.walk(directory): 12 yield root 13 for file in files: 14 yield os.path.join(root, file) 15 16def face_detect(i,img_path):#顔認識させるための定義 17 18 img = imread2(img_path) 19 img_width = max(img.shape) 20 resp = RetinaFace.detect_faces(img_path, threshold = 0.5)#これが今回新しく試したいRetinaFace 21 22 print(resp)#この「resp」から得られたデータを将来的にトリミングとか文字挿入の画像処理に活用したい 23 24 25input_path = input('画像フォルダのパスを入力してください。') 26 27pictures = []#空のリスト 28folder_path =[]#空のリスト 29 30for file in find_all_files(input_path):#入力されたパス以下のファイルとフォルダを全部リスト化する定義 31 folder_path.append(file) 32 33for file in folder_path:#全ファイルとフォルダのリストの中から.jpgを別の新しいリストに移動 34 base, ext = os.path.splitext(file) 35 if ext == '.jpg': 36 pictures.append(file) 37 38i = 0 39while i < len(pictures):#新しいリストに対して顔認識をする 40 41 img_path = pictures[i] 42 face_detect(i,img_path) 43 print('-----------------------------') 44 45 i = i + 1 46 47print('完了')

#直面した問題

すると、半角パスの画像に対しては以下のように顔や目、口の詳細な情報を取得できました。

{'face_1': {'score': 0.9977211356163025, 'facial_area': [230, 250, 427, 491], 'landmarks': {'right_eye': [277.46255, 358.14325], 'left_eye': [369.09164, 353.0737], 'nose': [323.42743, 419.03287], 'mouth_right': [295.996, 445.4812], 'mouth_left': [365.11304, 441.3468]}}}

しかし全角パスを指定した場合、Windows10環境ではRetinafaceがエラーになってしまい処理が途中で止まってしまいました。OpenCVのエラーは発生しないので、トライしようとしたOpenCVの全角パス対応には成功していると思われます。

更に疑問なのは、同じプログラムをMacBookProで試したところRetinafaceエラーが発生しませんでした。

この問題は文字コードなどが原因で発生していると思われるのですが、Windows10環境で動かしたいので良い解決策があればご教示いただければ幸いです。あるいは、そもそも文字コードが原因だとする私の見立てが間違っているのでしょうか?

以上、お知恵をお借りできれば幸いです。

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

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

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

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

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

yuki23

2021/12/31 01:51

エラーメッセージを提示してください
TakayukiMoriya

2021/12/31 02:02

コピペで申し訳ありません、こちらになります。 --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) ~\AppData\Local\Temp/ipykernel_40436/3243941179.py in <module> 258 259 else: --> 260 face_detect(i,img_path) 261 262 ~\AppData\Local\Temp/ipykernel_40436/3243941179.py in face_detect(i, img_path) 97 img = imread2(img_path) 98 img_width = max(img.shape) ---> 99 resp = RetinaFace.detect_faces(img_path, threshold = 0.5) 100 #print("faces:" + str(len(resp))) 101 #print(resp) ~\anaconda3\lib\site-packages\retinaface\RetinaFace.py in detect_faces(img_path, threshold, model) 73 scores_list = [] 74 landmarks_list = [] ---> 75 im_tensor, im_info, im_scale = preprocess.preprocess_image(img) 76 net_out = model(im_tensor) 77 net_out = [elt.numpy() for elt in net_out] ~\anaconda3\lib\site-packages\retinaface\commons\preprocess.py in preprocess_image(img) 37 scales = [1024, 1980] 38 ---> 39 img, im_scale = resize_image(img, scales) 40 img = img.astype(np.float32) 41 im_tensor = np.zeros((1, img.shape[0], img.shape[1], img.shape[2]), dtype=np.float32) ~\anaconda3\lib\site-packages\retinaface\commons\preprocess.py in resize_image(img, scales) 4 #this function is copied from the following code snippet: https://github.com/StanislasBertrand/RetinaFace-tf2/blob/master/retinaface.py 5 def resize_image(img, scales): ----> 6 img_w, img_h = img.shape[0:2] 7 target_size = scales[0] 8 max_size = scales[1] AttributeError: 'NoneType' object has no attribute 'shape'
退会済みユーザー

退会済みユーザー

2021/12/31 02:24

> AttributeError: 'NoneType' object has no attribute 'shape' よくあるのはimg = Noneの状態でprint(img.shape)のような処理をしたパターンです。 日本語を含むパスで > img = imread2(img_path) の後に print(img.shape) をして、Noneと出るか(224,224,3)のようになるか教えてもらえますか?
TakayukiMoriya

2021/12/31 02:27

ご回答ありがとうございます。 小生のコードでも img = imread2(img_path) と記述しているのですが、それのimread2の大元が def imread2(filename, flags=cv2.IMREAD_COLOR):#OpneCVを日本語パスに対応させる定義 buf = np.fromfile(filename, np.uint8) img = cv2.imdecode(buf, flags) return img なので、私のコードでも画像を開く際に全角パスに対応したOpenCVを使っているので問題はないと思うのです・・・。
TakayukiMoriya

2021/12/31 02:32

ご回答ありがとうございます print(img.shape) を新しく記述したところ、問題なく画像の情報が以下のように書き出されるようです・・・。 #(360, 640, 3) OpenCVで画像を開いて読み込むところまではうまく行っているような雰囲気です。
guest

回答1

0

ベストアンサー

バージョンの違いなどでまったく同じコードという保証はありませんが、retinafaceのコードによれば、
RetinaFaceは、

resp = RetinaFace.detect_faces(img_path, threshold = 0.5)#これが今回新しく試したいRetinaFace

の引数img_pathRetinaFace.get_image(img_path)に突っ込み、さらに内部で、img = cv2.imread(img_path)をしています。

日本語のパスの画像データではなく、日本語のパスという文字列をretinaface(つまるところcv2.imread())に送っているということです。

対策
A. 自力で作ったRetinaFace.get_image(img_path)に対応する修正コードをretinafaceのコードに組み込む
B. 自力で作ったコードの一部に、RetinaFaceの推論エンジン部分をRetinaFace.xxxxxのような感じで呼び出すようにする

どちらでも行けると思います。


追補
元のコードのget_imageの関数以降を自前のコードで使えば対策B、get_imageの関数を自前の読み込み関数に差し替えれば対策Aです。

Python3

1def detect_faces(img_path, threshold=0.9, model = None, allow_upscaling = True): 2 """ 3 TODO: add function doc here 4 """ 5 6 img = get_image(img_path)

投稿2021/12/31 02:35

編集2021/12/31 02:41
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

TakayukiMoriya

2021/12/31 02:46

だんだん理解できてきました。 A.でアドバイスいただいた「retinafaceのコードに組み込む」が今の私の実力に見合ってると思うのですが、つまり自分のPCの Cドライブのどこかにインストール済みのRetinaFaceのソースコードのOpenCVに関わる部分をいじるという理解でよろしいでしょうか?
退会済みユーザー

退会済みユーザー

2021/12/31 02:53 編集

モジュールのインストール先は、Numpyの場合以下のように確認できます。 import numpy as np print(np.__file__) 同じ感じでRetinaFaceのパスも見れるはずですので、そこのソースコードを書き換えることになります。 ※1 別のPCにインストールするときにも同じ修正をしないと使えませんのでご注意ください。 ※2 作者に「こうするといいよ」と連絡して、作者にこの修正をコミットしてもらえればTakayukiMoriyaさんの名前がクレジットに表示されるかもしれませんね!こうなると、※1の問題は自動的に解決できるようになります。たぶんキリル文字を使う人たちや中国語、韓国語など二バイト文字を使う人たちはみんな同じことを思っているはずですので…。
TakayukiMoriya

2021/12/31 03:31

ありがとうございます。やってみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問