筆者の所属している株式会社BFTでは2023年6月より、十数人の有志により毎月テーマを決めて、コーディングを行っています。その成果物については月に1回開催される開発勉強会で、コードのレビューが行われます。

開発勉強会の目的は下記の通りです。

1.1カ月という短期間である程度実用性のあるコードが書けるようになる
2.参加者のコードをレビューできるようになる
3.複数人で同じテーマのもとコーディングを行うことでモチベーションを保つ

本記事では、Python初心者の筆者が第1回の開発勉強会に参加して、実際にプログラミングを行った際に学んだことを紹介します。

リアルタイム顔検出をPC内蔵カメラで実現

2023年6月のテーマは「PC内蔵カメラで操作者以外の人を検出した際に画面が切り替わるプログラム」でした。
どのような場面での使用を想定しているかというと、仕事をさぼっているときに周囲にばれないようにすること(※1)、機密情報を取り扱っているときに画面を見られないようにすることを想定しています。
コーディングを行うにあたりテーマ及び、ユースケースを具体化した結果、図1のフローチャートのような流れのプログラムを実装するのが良いと考えました。

※1
あくまでもプログラミングの勉強のために分かりやすいユースケースとして挙げられたものであり、実際に仕事をさぼりたくて実装しているものではありません。

リアルタイム顔検出のフローチャート
図1, リアルタイム顔検出のフローチャート

図1をプログラムとして実装する際、顔検出に関しては下記1~3に示す課題がありました。

1.リアルタイムで顔検出を行う必要がある
→プログラムは常にループ処理を行う形で実装
2.自分が顔検知の対象になることを避ける必要がある
→自分は常に画面を見ていることを前提とし、検出した顔の数が2以上の場合に画面切り替えを行う
3.通りすがりの人(画面を見ていない人)は検知しないようにする必要がある
→OpenCVのhaarcascades(※後述)を使用し、目を基準に顔検出を行う

また、リアルタイムで顔検出を行う方法は様々ありますが、今回は手軽さという観点からPythonのライブラリの1つであるOpenCVを用いて実装することとしました。

OpenCVについて

今回顔検出に用いたOpenCVは、画像や動画の処理・解析が行えるオープンソースのライブラリです。Python環境では、下記のpip install コマンドを実行するだけで使えるようになるため、本記事のように初学者がプログラムで画像を扱う際におすすめのツールです。

> pip install opencv-python

※pip installコマンドを使った際に下記のようなメッセージが出ることがあります。その場合はメッセージの指示に従って「python.exe -m pip install –upgrade pip」コマンドを実行します。

メッセージ例
[notice] A new release of pip is available: 23.2 -> 23.2.1
[notice] To update, run: python.exe -m pip install –upgrade pip

先述したhaarcascadesはOpenCVで用意されている人検出、顔検出等に利用できます。こちらよりダウンロードし、プログラムから参照する場所に配置することで利用できるようになります。様々な種類のファイルがあるため、用途によってダウンロードするファイルを選ぶのが良いかと思います。今回は顔検出の用途だったため、正面を向いた顔を検出できる「haarcascade_frontalface_alt.xml」を選択しました。
使いたいxmlファイルをクリックし、図2の赤枠のボタンをクリックすることでダウンロードできます。

xmlファイルのダウンロード
図2, xmlファイルのダウンロード

Pythonによる画面切り替えの実装

顔検出同様、PCの画面切り替えを行う方法もさまざま考えられます。筆者はPythonのpyautoguiライブラリを用いてAlt+Tabを実行することで画面切り替えを行おうとしていましたが、ウィンドウが1つしかない場合に画面の切り替えが行われず、失敗したため断念しました。

今回の勉強会で、他の方々はどのように実装していたかというと、多くの参加者が図3のフローチャートに示す、用意した画像をOpenCVのimreadで読み込み、同じくOpenCVのimshowでデスクトップに写すという方法で画面切り替えの実装を行っていました。

画面切り替えのフローチャート
図3, 画面切り替えのフローチャート

気を付けた点など

一般的にプログラミングを行う際の注意点として、下記について気を付けるようレビューにてコメントをいただきました。

・変数や関数に分かりやすい名前を付ける(キャメルケースを参考にするとよい)
・無駄な処理は省く
・他者が見ても何をやっているかわかるよう、コメントを入れる

Pythonでのプログラミングにおいて気を付けることとしては下記が挙げられました。

・main.pyを実行するだけで動作するようにする(1つのPythonファイルに長々と処理を書かないようにする)
・Pythonは「’ ’」と「” ”」を区別しないため、プログラム内でどちらを使うか決めておき、統一する
・importをif文の中に入れない

今回一番評価されたプログラムの紹介

開発勉強会では毎回投票でその月の一番良かったプログラムを決めています。ここでは今回の開発勉強会で一番評価されたプログラムを紹介します。

今回選ばれたプログラムは下記の点において評価されました。

・上述したプログラミングにおいて気を付けることがおさえられている。
・使用する場面に応じて2パターンの処理が、1つのプログラムの実行で実現できる。

実装環境

・Python 3.11.4
・opencv-python 1.25.2
・pygame 2.5.0
※pygameはmixerで後述する警告音を鳴らすために使います。

プログラムの配置

プログラムの配置を図4に示します。機能ごとに配置するフォルダを変え、main.pyの実行のみで動くよう設計されています。

プログラムの配置
図4, プログラムの配置

プログラムの処理内容

プログラムの処理内容を図5のフローチャートに示します。また、画面遷移を図6に示します。

評価されたプログラムのフローチャート
評価されたプログラムのフローチャート
評価されたプログラムのフローチャート
図5, 一番評価されたプログラムのフローチャート
評価されたプログラムの画像遷移
図6, 一番評価されたプログラムの画像遷移

コマンドプロンプトに0が入力された場合は「仕事さぼりモード」、1が入力された場合は「機密情報取り扱いモード」の処理を行います。

初期処理では、コマンドプロンプトに入力された数値をもとに、使用するカメラ(今回はPC内蔵カメラ)の選択と、顔検出用のファイルパス、警告音のファイルパス、デスクトップに映す画像ファイルパスの定義を行っています。Enterキーが押下されるまで顔検出を行い、他人の顔を検出した際は「仕事さぼりモード」では仕事をしているように見える画像、「機密情報取り扱いモード」では誰かがPCの画面を見ているという警告の画像を、デスクトップに映します。「機密情報取り扱いモード」の場合は警告音も鳴らします。

顔検出については、上述したhaarcascadesの「haarcascade_frontalface_alt.xml」を用いています。ループ処理によりEnterキーが押されるまで常にカメラの出力を監視し、カメラに操作者以外が写った(顔の数が2以上と判定した)場合、かつ顔を四角で囲った時に20×20ピクセル以上になる場合に上記の他人検出時の処理を行います。

画面切り替えの際はOpenCVのnamedWindowとresizeでデスクトップに表示する画像の大きさを指定します。

Pythonでプログラムを書いた感想

ライブラリが豊富であるという点からPythonでの実装を行いましたが、筆者は今までPythonを触った経験がほとんどなかったため、知らないライブラリを思い通りに動くようにプログラムに落とし込むことが難しかったと感じました。特に、顔検出に関しては先述した課題を解決できず、未実装のまま勉強会当日を迎えてしまいました。
しかし、勉強会に参加したことで他の方の様々な考え方を聞くことができ、柔軟な発想が身についたと感じています。また、実際にそこまで多くない行数でしっかりリアルタイムで動くプログラムをいくつも見て感動し、きちんと動くプログラムを書けるようになりたいと感じました。
レビューに関しては知識不足でどうしても受け身になりがちだったため、少しずつ経験を積み、半年くらいでレビュアーになれればと思っています。