Web Analytics

こつこつエンジニア

現役アプリ開発者によるIT系特化ブログ

【VS(C#)+OpenCV(C++)】WEBカメラの映像を表示&顔認識してみる

f:id:madai21:20211014190049j:plain

はじめに

前回まで動画ファイルからの再生や静止画像から人の顔を認識させることをしました。
madai21.hatenablog.com
madai21.hatenablog.com
今回はWEBカメラを使ってリアルタイムにWEBカメラの映像を表示させつつ、人の顔認識もさせてみたいと思います。

環境

この記事で作成したVisualStudio2019+OpenCV4のプロジェクトがあることを前提に進めます。
madai21.hatenablog.com

手順

  1. WEBカメラを準備
  2. WEBカメラの映像をリアルタイムに表示
  3. WEBカメラの映像から人物の顔認識

WEBカメラを準備

WEBカメラはこちらを使いたいと思います。

私はYahoo!ショッピングで購入したのですが、開けたらこんな感じでした。
f:id:madai21:20210728234605j:plain
こちらが一緒に同梱されていた説明書です。
f:id:madai21:20210728235519j:plain
なぜかマスクも3枚同梱されていました^^;
子供用の給食マスクですねw
f:id:madai21:20210728235618j:plain
さてどこかにWebカメラを固定しようと思いましたが、ここで何かおかしいことに気づきました・・・。
f:id:madai21:20210728235750j:plain
ん?ラベル逆・・・?^^;
こっち向きですねww
f:id:madai21:20210728235934j:plain
とりあえず気にせずUSBをPCに挿します。
これだけでもうWebカメラが使えます、楽ですね^^

WEBカメラの映像をリアルタイムに表示

コードを修正してリアルタイムにWebカメラの映像を表示させてみましょう。

C++/CLI(OpenCVラッパー)プロジェクトの編集

OpenCVWrapper.hを開いて以下の内容に編集します。

#pragma once
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui_c.h>
#include <msclr/marshal_cppstd.h>
#include <vector>
using namespace System;
using namespace msclr::interop;
namespace OpenCVWrapper {
	public ref class OpenCVWrapperCls
	{
	public:
		static void ShowWebCamera()
		{
			auto vc = cv::VideoCapture(0);
			while (vc.isOpened())
			{
				cv::Mat mat;
				vc >> mat;
				if (mat.empty()) {
					continue;
				}
 
				cv::imshow("Show Web Camera Window", mat);
				auto key = cv::waitKey(1);
				if (key == 27) {
					break;
				}
			}
			cv::destroyAllWindows();
		}
	};
}

動画ファイルの時は

cv::VideoCapture(動画ファイルのパス)
でしたが、今回は
cv::VideoCapture(0)
としています。
この数値はカメラデバイスのIDとなります。
1台しか接続していない場合は0です。

C#コンソールアプリプロジェクトの編集

Program.csを開いて以下の内容に編集します。

using System;
 
namespace OpenCVConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            OpenCVWrapper.OpenCVWrapperCls.ShowWebCamera();
        }
    }
}

さぁ実行してみましょう。
これでWebカメラの映像をリアルタイムに表示できましたね^^

WEBカメラの映像から人物の顔認識

さぁ次はWebカメラの映像からリアルタイムに人物の顔認識させてみましょう。

C++/CLI(OpenCVラッパー)プロジェクトの編集

OpenCVWrapper.hを開いて以下の内容に編集します。

#pragma once
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui_c.h>
#include <msclr/marshal_cppstd.h>
#include <vector>
using namespace System;
using namespace msclr::interop;
namespace OpenCVWrapper {
	public ref class OpenCVWrapperCls
	{
	public:
		static void ShowWebCamera()
		{
			auto vc = cv::VideoCapture(0);
			while (vc.isOpened())
			{
				cv::Mat mat;
				vc >> mat;
				if (mat.empty()) {
					continue;
				}
 
				std::vector<cv::Rect> faces;
				cv::CascadeClassifier cc("C:\\opencv\\data\\haarcascades\\haarcascade_frontalface_alt.xml");
				cc.detectMultiScale(mat, faces);

				for (int i = 0; i < faces.size(); i++) {
					rectangle(mat, cv::Point(faces[i].x, faces[i].y), cv::Point(faces[i].x + faces[i].width, faces[i].y + faces[i].height), cv::Scalar(0, 0, 255), 3, CV_AA);
				}
 
				cv::imshow("Show Web Camera Window", mat);
				auto key = cv::waitKey(1);
				if (key == 27) {
					break;
				}
			}
			cv::destroyAllWindows();
		}
	};
}

実行すると・・・ちゃんと認識してくれてますね^^

写真なので精度は若干悪いですが、リアルな人物なら精度よく検出してくれそうですね。

おわりに

動画と違ってWebカメラFPSの性能以上出ることはないので、異常に早くなることはありませんでした。
なのでOpenCVのVideoCaptureはWebカメラとかでなら使えそうですね^^
リアルタイムに人物の顔を検出することで何かいろいろ面白そうなことができそうです。
私も折角Webカメラも購入したので色々試してみたいと思います。