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

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

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

dlibは、機械学習のC++の画像処理ライブラリの一つ。性能の高い顔の器官検出が簡単にでき、Pythonバインドもあります。オープンソースで無料で使用でき、機械学習以外の様々な機能も搭載されています。

OpenCV

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

Python

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

Q&A

解決済

1回答

1058閲覧

openCVでの顔検出数や顔器官座標の検出数が0になる

a_summer_days

総合スコア6

dlib

dlibは、機械学習のC++の画像処理ライブラリの一つ。性能の高い顔の器官検出が簡単にでき、Pythonバインドもあります。オープンソースで無料で使用でき、機械学習以外の様々な機能も搭載されています。

OpenCV

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

Python

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

0グッド

0クリップ

投稿2020/06/16 12:10

編集2020/06/16 13:01

現在Python, openCVを用いて顔検出のプログラムを作成しています。

cascade = cv2.CascadeClassifier(cascade_path) facerect = cascade.detectMultiScale(frame,scaleFactor=1.1,minNeighbors=1,minSize=(100,100)) if len(facerect) > 0: for rect in facerect: 処理

このようなコードを実行しようとした際に、len(facerect)が0になってしまいif内の処理を実行できません。
検出した顔を四角で囲むという処理は通っているので、顔の検出自体はできているはずなのですが...

また、dlibについても

dets = detector(frame[:, :, ::-1]) if len(dets) > 0: 処理

このコードについても同じ問題が発生しています。

そこで質問です。

顔を認識できているのにlen(facerect)やlen(dets)が0となる理由と解決策をご教示いただきたいです。

追記:今回使用したプログラム全体です。(動画をフレーム分割し、各画像から顔を検出,顔を囲んだ画像を保存という流れです)

import glob import cv2 import os import dlib import csv import matplotlib.pyplot as plt import numpy as np from PIL import Image, ImageDraw %matplotlib inline import pandas as pd from pandas import DataFrame, Series count=0 movie='パス.mov'#使用する動画 cap = cv2.VideoCapture(movie) while True: ret, img = cap.read() if ret == True: count += 1 cv2.imwrite('パス' + "Sample" + '_' + str("{0:05d}".format(count)) +'.jpg', img) #画像として保存する else: break files = sorted(glob.glob(r"パス/*.jpg") )# .jpgを整理する cascade = cv2.CascadeClassifier("パスhaarcascade_frontalface_default.xml") facerect = cascade.detectMultiScale(img,minSize=(100,100)) count=0 if len(facerect) > 0: for f in files: count += 1 img = cv2.imread(f) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) faces = cascade.detectMultiScale(gray, minSize=(100, 100)) for (x,y,w,h) in faces: img = cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2) roi_gray = gray[y:y+h, x:x+w] roi_color = img[y:y+h, x:x+w] cv2.imwrite('パス' + "Sample_after" + '_' + str("{0:05d}".format(count)) +'.jpg', img) #画像として保存する cv2.waitKey(0) cv2.destroyAllWindows()

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

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

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

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

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

Q71

2020/06/16 12:31

> len(facerect)が0になってしまいif内の処理を実行できません。 >検出した顔を四角で囲むという処理は通っている facerectは何を表しているのでしょうか。コード中の「処理」は、何をしているのでしょうか。 この「処理」で、検出した顔を囲むのでは?違うのなら、「検出した顔を囲む」為に、どの変数を元に処理しているのでしょうか?
tiitoi

2020/06/16 12:54

・コード全体を貼ってください ・ある画像では検出できるのに、ある画像だと検出できないということであれば、単に今の検出器の性能では、検出できなかったという話になります
a_summer_days

2020/06/16 12:57

facerectはcascade.detectMultiScale()にて検出した顔のリストです。 また検出した顔を囲むというのは、本当に顔が検出されているかを確認するために実行しただけで、本来は別の処理を行う予定です。 試験用に作成した「検出した顔を囲む」コードを質問に追記いたします。
tiitoi

2020/06/16 13:12

以下の2つはなぜ必要なのでしょうか?img に入っているのは最後に取得した動画のフレームなので、そこに顔が写っていない (または写っているけど検出できなかった) 場合は if 文は False になると思うのですが。 facerect = cascade.detectMultiScale(img,minSize=(100,100)) と if len(facerect) > 0:
Q71

2020/06/16 13:24

iPhoneで見ているので間違っているかもですが。 while true と cascade = のインデントが同じなので、顔検出するのは一番最後のフレームか、画像がない(おそらく空の)情報ですよね? ここのインデントが正しくて、毎フレーム検出しているとしても、「if len(facerect) > 0:」が正の時に実行されるブロックの中に顔に四角を描くロジックが入っているので、「len(facerect)が0になってしまいif内の処理を実行できません。 検出した顔を四角で囲むという処理は通っている」ということにはならないと思うのですが?
a_summer_days

2020/06/16 13:25

最後に取得した画像にも顔は検出されていました。 また、その2文はこの顔を囲むプログラムには必要のないものですが、本来私の作成したいプログラム(卒論のためのもの)に必要な文章です。 補足ではありますが、ややこしいので質問の流れを書かせていただきます ①元々卒論のためにプログラムを作成 ②そのなかで、検出されていることの確認のために「if len(facerect) > 0:」が必要だが,値が0となりif内の処理が実行されない ③len(facerect) = 0となるのは顔が検出されていないときだとネットで発見 ④顔が検出されているのかを確認するためにこのプログラムを作成して確かめた ⑤顔は検出され,死角でも囲われているのにlen(facerect) = 0となる理由がわからない,質問
Q71

2020/06/16 13:36

22:25のコメントから、プログラムが2本あると推測します。①と④です。 この推測が正しいなら、④が描いているのは①が「検出なし」とした時と違う画像と考えられます。 プログラムは、書いた意図どおりには動きません。書いてある通りに動きます。意図と書いてあることが違う時、「バグ」と言われます。まずは、2つあると思われるプログラムの、意図と実際が一致しているかを確認することを勧めます。 ちなみに、追加されたコードは動きません。capがコメントアウトされています。本当に、意図と書いてあることが一致しているか、確認することを強く勧めます。
guest

回答1

0

ベストアンサー

python

1while True: 2 ret, img = cap.read() 3 if ret == True: 4 count += 1 5 cv2.imwrite('パス' + "Sample" + '_' + str("{0:05d}".format(count)) +'.jpg', img) #画像として保存する 6 else: 7 break

動画ファイルを逐次読み込んでいき、これ以上取得するフレームがない場合、cap.read() は (False, None) を返します。
このループが終了した段階で、None が img に代入されており、それに対して顔検出を行っているのでその返り値 facerect も空になります。つまり、img には最後のフレームの画像ではなく、None が入っています。(print して確認してみてください)

コードの変更を最小限で修正するには、以下のように frame という仮変数に入れておき、ret == True の場合に img = frame に代入すれば、ループ終了時点で img には最後のフレームの画像が入るようになると思います。

python

1while True: 2 ret, frame = cap.read() 3 if ret == True: 4 img = frame 5 count += 1 6 cv2.imwrite('パス' + "Sample" + '_' + str("{0:05d}".format(count)) +'.jpg', img) #画像として保存する 7 else: 8 break

ちなみに img は BGR 画像なので、顔検出する前にグレースケールに変換しておく必要もあると思います。

投稿2020/06/16 13:35

編集2020/06/16 13:37
tiitoi

総合スコア21956

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

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

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問