【OpenCV C++】顔認識をリアルタイムで行いたい ~1日目~
どうも、プログラミングの鬼シヨツ鬼です。
この記事では「OpenCV(C++)でWebカメラから取り込んだ映像の顔認識をリアルタイムに行いたいぜ」って人に向けて、僕が試行錯誤した開発記を連載6回で書いています。
ソースコードも載せていますので、ぜひ、参考にしてください。
ちなみに、この記事は下記の動画と関連しています。
こちらの動画を先に見ていただくと、実際に動く際のイメージが掴めます。
YouTube:【自作】ゆゆうたさんをバーチャルユーチューバー化してみた
また、OpenCVのインストール方法はこちらの動画をご覧ください。
YouTube:OpenCVのインストール方法【Visual Studio】【C++】
目次
本記事は次のように、日記っぽく、だんだんアップグレードしていく構成で書いています。
初心者の人は最初から読んでいくと、開発していく気分を味わって頂けます。
中級者以上の方は必要なところだけつまみ食いする感じでもOKです。
- 目次
- 1日目:とりあえずカメラ起動して、顔認識してみた
- 2日目:検出範囲を半分にしたら、検出が早くなった!
- 3日目:結論の出ない試行錯誤。。。
- 4日目:顔の追従検索で検出速度向上!
- 5日目:端っこ対策と斜め対策
- 6日目:ついに、バーチャルユーチューバー化!?
- まとめ
※記事が長くなりすぎるため、2~6日目は後続記事へのリンクです
1日目:とりあえずカメラ起動して、顔認識してみた
やりたいこと
・カメラの起動
・顔認識
ソースコード
カメラキャプチャのみ
とりあえずカメラを起動しないと何も始まらないので、OpenCVを使ってプログラムからWebカメラを開いてみたいと思います。
#include <opencv2\opencv.hpp> #include <opencv2/highgui.hpp> #include <vector> int main(void) { //デバイスのオープン cv::VideoCapture cap(0); //カメラデバイスが正常にオープンしたか確認. if (!cap.isOpened()) { //読み込みに失敗したときの処理 return -1; } //取得したフレーム cv::Mat frame; //無限ループ while (1) { //USBカメラが得た動画の1フレームを格納 cap >> frame; //画像を表示. cv::imshow("win", frame); //キーボード入力を受け付ける const int key = cv::waitKey(1); //qボタンが押されたとき if (key == 'q'/*113*/) { break;//whileループから抜ける. } } //すべてのウィンドウを閉じる cv::destroyAllWindows(); return 0; }
単純な顔認識
単純な顔認識なら簡単に実現できるので、開いたカメラ映像から顔を検出してみます。
#include "opencv2/opencv.hpp" #include "opencv2/highgui.hpp" #include <vector> using namespace cv; using namespace std; int main(void) { //デバイスのオープン VideoCapture cap(0); //カメラデバイスが正常にオープンしたか確認. if (!cap.isOpened()) { //読み込みに失敗したときの処理 return -1; } //取得したフレーム Mat frame; //カスケード分類器格納場所 CascadeClassifier cascade; //正面顔情報が入っているカスケード cascade.load("C:/opencv/sources/data/haarcascades/haarcascade_frontalface_alt.xml"); //輪郭情報を格納場所 vector<Rect> faces; //無限ループ while (1) { //USBカメラが得た動画の1フレームを格納 cap >> frame; //格納されたフレームに対してカスケードファイルに基づいて顔を検知 cascade.detectMultiScale(frame, faces, 1.1, 3, 0, Size(20, 20)); //検出した顔の個数"faces.size()"分ループを行う for (int i = 0; i < faces.size(); i++) { //検出した顔を赤色矩形で囲む rectangle(frame, Point(faces[i].x, faces[i].y), Point(faces[i].x + faces[i].width, faces[i].y + faces[i].height), Scalar(0, 0, 255), 3); } //画像を表示. imshow("win", frame); //キーボード入力を受け付ける const int key = waitKey(1); //qボタンが押されたとき if (key == 'q'/*113*/) { break;//whileループから抜ける. } } //すべてのウィンドウを閉じる destroyAllWindows(); return 0; }
解説
顔の学習データxmlファイルをちゃんと指定することが大切。
ここが間違っているとエラーで動きません。
まとめ
とりあえずカメラを開くことができました!
また、単純に顔認識をするだけなら、数行付け加えるだけで実現することができました。
しかし、検出に時間がかかるため、映像が非常にカクつきます。。。
2日目は検出速度を上げる工夫をしていきます!
2日目:検出範囲を半分にしたら、検出が早くなった!
続きはこちらの記事へ
【OpenCV C++】顔認識をリアルタイムで行いたい ~2日目~ - シヨツ鬼のブログ
3日目:結論の出ない試行錯誤。。。
続きはこちらの記事へ
【OpenCV C++】顔認識をリアルタイムで行いたい ~3日目~ - シヨツ鬼のブログ
4日目:顔の追従検索で検出速度向上!
続きはこちらの記事へ
【OpenCV C++】顔認識をリアルタイムで行いたい ~4日目~ - シヨツ鬼のブログ
5日目:端っこ対策と斜め対策
続きはこちらの記事へ
【OpenCV C++】顔認識をリアルタイムで行いたい ~5日目~ - シヨツ鬼のブログ
6日目:ついに、バーチャルユーチューバー化!?
続きはこちらの記事へ
【OpenCV C++】顔認識をリアルタイムで行いたい ~6日目~ - シヨツ鬼のブログ