予防が私たちのすべてです。データ漏洩に対する適切な保護は、数百万ドルの損失につながる可能性のある悪影響を防ぐのに役立ちます。現代の世界では、各組織が機密情報を処理および保存しています。大規模な組織になると、機密情報の量は膨大です。コンピュータの「セキュリティ」の状態は、各ユーザーがすべての情報セキュリティルールを遵守したときに達成される概念上の理想です。
多くの従業員がPCのロックを忘れたり、意図的にロックしたりしないため、オフィスにいる従業員は時々自分のコンピューターを離れ、電源が入ったコンピューターは無人で、ファイルやフォルダーにアクセスできるようになっています。 -「5メートル後退したのに、なぜブロックするのか!?」残念ながら、資料に興味のある他の従業員はそのような瞬間を利用することができます。
このような状況でデータのセキュリティをどのように確保できますか?方法の1つは、ユーザーの顔を認識できるバイオメトリック認証テクノロジーを使用することです。
顔認識は新しい概念ではなく、現在、このタスクを実行するための多くのツールがあります。顔認識の方法やツールに特に精通していない場合は、オープンソースのコンピュータービジョンライブラリ(オープンソースのコンピュータービジョンライブラリ)とPythonプログラミング言語を使用すると、目標をできるだけ早く達成できる優れたソリューションになります。
ソフトウェアを決定しました。もう1つのハードウェア(Webカメラ)が必要です。今、どのように顔認識を設定しますか?まず、フレーム内の顔を検出する必要があります。顔を検出する方法の1つは、2001年にすでに説明されているViola-Jones法です。私たちは実践にもっと興味があるので、理論的な詳細には立ち入りません。この方法は、画像の積分表現への変換、スキャンウィンドウ法、Haar機能の使用などの基本原則に基づいていることだけを説明します。メソッドの説明を読んだり、公式WebサイトでOpenCVのインストールに関する情報を確認したりできます。以下は、Webサイトのビデオストリームから顔を検出できるようにするPythonコードです。
import cv2 as cv
import numpy as np
face_cascade = 'haarcascade_frontalface_default.xml'
cam = 1
classifier = cv.CascadeClassifier(face_cascade)
video_stream = cv.VideoCapture(cam)
while True:
retval, frame = video_stream.read()
gray_frame = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
found_faces = classifier.detectMultiScale(gray_frame, 1.2, 5, minSize=(197, 197))
for x, y, w, h in found_faces:
cv.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 2)
cv.namedWindow('Stream', cv.WINDOW_NORMAL)
cv.imshow('Stream', frame)
k = cv.waitKey(30) & 0xFF
if k == 27:
break
video_stream.release()
cv.destroyAllWindows()
上記のコードでは、最初に、動作に必要な2つのモジュールcv2(コンピュータービジョン)とnumpy(マトリックスの処理)をインポートします。変数face_cascadeで、Haarカスケードを使用してxmlファイルへのパスを保存します。このファイル、およびその他のファイル(たとえば、目の検出用)は、githubページにあります。
可変カムでは、Webカメラの番号を書き込みます。接続されているカメラが複数ある場合、デフォルトで接続されている唯一のカメラの数は0です。次に、CascadeClassifierメソッドを使用して分類オブジェクトが作成され、カメラへの接続はcv.VideoCapture(cam)です。次に、ループで、read()メソッドを使用して画像をフレームごとにframe変数に読み込みます。分類子は画像をグレースケールで処理するため、cvtColorメソッドを使用して、画像を目的の形式に変換します。 detectMultiScaleメソッドは、検出されたすべての面のパラメーターを含むリストを返します。これは、長方形(頂点座標(x、y)および長方形の幅と高さ(w、h))です。次の行は、プログラムが機能するためのオプションですが、デバッグには役立ちます。rectangleメソッドは、検出された面の代わりにソースフレームにフレームを追加し、imshowはビデオストリームを含むウィンドウを表示します。
ここではすべてが非常に単純ですが、さらに興味深いものです。今、私たちは顔を認識する必要があります。どうやってするの? OpenCVには、顔認識のためのいくつかのメソッドが含まれています。その中には、LBPH(ローカルバイナリパターンヒストグラム)メソッドがあります。ここでは、さらに詳しく説明し、それがどのように機能するかを少し理解します。
一般に、画像ピクセルと元のピクセルを囲むさらに8つのピクセルの輝度値が取得されます。ピクセルの明るさの値を持つ3x3のテーブルになります。次に、0または1が同じテーブルに書き込まれます。最も外側のピクセルの輝度値が中央のピクセルの輝度値を超える場合は1が設定され、それ以外の場合は-0になります。次に、結果のコードが左上のセルから時計回りに読み取られ、10進数に変換され、この数値が書き込まれます。適切な位置に画像サイズのマトリックスに。そして、各ピクセルについてもそうです。
マトリックスは特定の数のセグメントに分割され(デフォルトでは、これは8×8グリッドです)、セグメントごとにヒストグラムが作成され、最後に、ヒストグラムを連結することによって、画像全体を特徴付ける結果が得られます。認識中に、同じヒストグラムが調査対象の画像に対してプロットされ、トレーニングデータと比較されます。
この方法を使用しますが、最初にもう1つの重要な手順を実行する必要があります。それは、面のあるベースを作成することです。一般に、データベースの構造は次のようになります。
--Storage\\
--Person_1\\
--img_1.jpg
--img_2.jpg
…
--img_n.jpg
…
--Person_m\\
--img_1.jpg
--img_2.jpg
…
--img_n.jpg
はい、顔の画像をベースにしています。次に、アルゴリズムをトレーニングまたはトレーニングするためのベースを何らかの方法で処理する必要があります。処理は、すべての画像のリストと各人のIDまたはタグのリストを生成することに要約されます。このアクションの最も単純なコードは次のようになります。
storage = 'storage'
images = []
labels = []
names = {}
id = 0
for subdir in os.scandir(storage):
names[id] = subdir.name
subdir_path = os.path.join(storage, subdir.name)
for file in os.scandir(subdir_path):
if file.name.split('.')[-1].lower() not in ['png', 'bmp', 'jpeg', 'gif']:
continue
file_path = os.path.join(subdir_path, file.name)
image = cv.imread(file_path, 0)
label = id
images.append(image)
labels.append(label)
id += 1
ここでも、すべてが非常に単純です。 storage変数は、個人の顔の画像を含むフォルダーを含むフォルダーへのパスを格納し、次に画像のリスト、タグのリスト、および名前の付いた辞書を格納します。仕組み:特定の人のフォルダのすべての画像が画像のリストに追加されます(たとえば、15個あります)。これがストレージの最初のフォルダである場合、ラベルは0に等しくなります。したがって、0がラベルのリストに同時に15回追加されます。名前の辞書には、キーがラベルで、値が人物の名前(特定の人物の画像が含まれるフォルダーの名前)であるレコードが作成されます。そして、ストレージ全体についても同様です。上記のコードでは、imreadメソッドを使用した行に注意する必要があります。ここでは、画像が読み取られ、ピクセルの明るさのマトリックスとして表され、image変数に書き込まれます。
今、楽しい部分はアルゴリズムを訓練することです:
recognizer = cv.face.LBPHFaceRecognizer_create(1, 8, 8, 8, 130)
recognizer.train(images, np.array(labels))
コードの最初の行では、LBPHFaceRecognizer_createメソッドを使用してアルゴリズムを初期化します。 LBPHアルゴリズムの説明を覚えていますか?上記の関数のパラメータには、説明した内容が含まれています。境界に沿ってピクセルが目的のピクセルの周囲に配置される半径、半径によって形成される「円」からのピクセル数、水平方向と垂直方向のセグメント数、および認識の決定に影響するしきい値人、つまり、要件が厳しいほど、しきい値は低くなります。次に、トレーニング用のtrainメソッドを呼び出し、画像とラベルのリストを引数として渡します。これで、アルゴリズムはデータベースから顔を記憶し、それらを認識できるようになります。問題は小さいですが、ループの最初のコードに数行追加する必要があります(found_facesのx、y、w、hの場合):顔を検出した後、それを認識する必要があります。顔が認識されない場合は、または他の人が認識されたら、すぐにコンピュータをロックしてください!
roi = gray_frame[y:y+h, x:x+w]
name, dist = recognizer.predict(roi)
cv.putText(frame, '%s - %.0f' % (names[name], dist), (x, y), cv.FONT_HERSHEY_DUPLEX, 1, (0, 255, 0), 3)
if names[name] != "Ivan Petrov":
ctypes.windll.user32.LockWorkStation()
最初の行で、roi(関心領域から)は、検出された顔を含む画像のフラグメントを書き込む変数です。次の行では、predictメソッドが呼び出されると、顔の認識が直接行われます。このメソッドは、認識された顔に対応するラベルと、検出された顔と認識された顔との間の不一致の程度を特徴付ける値を返します(小さいほど、正しい顔が認識されたという信頼度が高くなります)。次に、再度デバッグの目的で、putTextメソッドを使用して、認識された人の名前でフレームにテキストを追加します。そして最後に、最も単純な条件を確認します。PCの非所有者が認識された場合(これは名前付きの辞書が必要な場所です)、コンピューターをロックします。ご覧のとおり、ctypes.windll.user32.LockWorkStation()行がブロッキングを担当しています。それを機能させるにはcv2とnumpyの他にctypesモジュールをインポートする必要があります。
その結果、他人の顔が認識されるとすぐにPCがブロックされるか、原則として認識されませんでした。 PCのロックを解除した後、プログラムは引き続き実行されます。従業員が職場を離れる場合にPCロックを追加することもできます。ここにはかなりのニュアンスがあることを理解するために、長く考える必要はありません。たとえば、背景に別の顔が認識された場合はどうなりますか?この状況では、顔のように見えるオブジェクトの最小サイズを設定できます。そうすると、背景の顔は無視されます(このため、detectMultiScaleメソッドにminSizeパラメーターがあります)。他の状況では、必要に応じて適切な解決策を見つけることもできます。
ブロッキングが正しく機能するための最も重要な要素の1つは、写真データベース内の画像の品質です。第一に、特定の人のために、角度や顔の表情が異なるものがたくさんあることが望ましい。第二に、照明は独自の調整を行うため、この点を考慮し、さまざまな照明条件で撮影された画像を使用する価値があります。そして第三に、従業員の職場にあるWebサイトから画像を記録する必要があります。OpenCVに画像を保存する方法もあります。コードに関しては、確実に拡張され、追加機能が追加されるため、クラスを使用して関数に「ラップ」することができます。完璧に制限はありません!主なことは、プログラムのアクションの順序を覚えておくことです。写真を使用したデータベースの処理、トレーニング、検出、認識です。
ウェビナー03.09.202010-00モスクワ時間に、講演者は、使用されているソースコードとテクノロジーを使用してオブジェクトを検出するためのニューラルネットワークをトレーニングするための実用的な方法を紹介し、質問にも答えます。次のリンクから登録できます:newtechaudit.ru/vebinar-computer-vision
