[深層学習] 畳み込みニューラル ネットワーク (tensorflow) に基づく顔認識プロジェクト (1)

イベントアドレス: CSDN 21 日間ラーニング チャレンジ

序文

LeNet-5 手書き数字の導入から、最近の天気認識の研究まで、しばらく前に調査を行いました。私はC++/Qtの開発に従事しており、Qtに精通しているため、Qtインターフェイスに基づいた顔認識を実装したいので、大きな投票をしたいと思います。

畳み込みニューラル ネットワークの概念に慣れていない場合は、次の記事を参照してください:畳み込みは実際に何をしますか?
ニューラル ネットワークのトレーニング プロセスや環境の構築方法を理解したい場合は、この記事を参照してください。記事:環境の構築とトレーニングのプロセス

ps: 少し前に、何人かの友人が、普通にトレーニングできたが、多くの機能を理解していなかったと答えたので、ここで使用するすべての機能を紹介します。

基本的な考え方

具体的な手順は次のとおりです。

  1. 最初にデータを収集する必要があります。私の考えは、OpenCV を介してカメラを呼び出して顔写真を収集することです。
  2. 次に、主にデータセット、トレーニング セット、検証セット、およびテスト セットを分類するために、前処理を実行します。損失関数などの適切なパラメーターを選択します。画像のグレースケール、正規化など
  3. モデルのトレーニングを開始するには、事前にラベルのキーと値のペアを作成します。
  4. 顔認識効果をテストし、OpenCV を介して顔写真をキャプチャし、画像を前処理して最後にモデルに渡し、認識結果をテキスト形式で画面に出力し、q を入力して終了するまで繰り返します。

環境について

図書館 バージョン
パイソン 3.7.0
テンソルフロー 2.1
OpenCV 3.4.2
pyQt 5.15.7

OpenCV

OpenCV は、BSD ライセンス (オープン ソース) に基づいてリリースされたクロスプラットフォームのコンピューター ビジョン ライブラリであり、Linux、Windows、Android、および Mac OS オペレーティング システムで実行できます。軽量で効率的 - 一連の C 関数と少数の C++ クラスで構成され、Python、Ruby、MATLAB などの言語へのインターフェイスを提供し、画像処理とコンピューターで多くの一般的なアルゴリズムを実装します。ヴィジョン。

OpenCV は C++ 言語で記述されており、その主要なインターフェイスも C++ 言語ですが、依然として多数の C 言語インターフェイスが保持されています。このライブラリには、広範な Python、Java、および MATLAB/OCTAVE (バージョン 2.5) インターフェイスもあります。これらの言語の API インターフェイス関数は、オンライン ドキュメントから入手できます。C#、Ch、Ruby もサポートするようになりました。

OpenCVの特徴

  1. C/C++ で書かれたオープンソースのコンピューター ビジョン ライブラリ。
  2. 使用目的は、リアルタイム アプリケーションの開発です。
  3. オペレーティング システム、ハードウェア、およびグラフィックス マネージャーに依存しません。
  4. 一般的な画像/ビデオの読み込み、保存、およびモジュールの取得。
  5. 低レベルと高レベルのアプリケーション開発キット。

OpenCVが持つ機能

  1. データの割り当て、解放、コピー、設定、および変換を含む、画像データに対する操作。
  2. 画像や動画の入出力;
  3. 行列、ベクトル、および線形代数の操作を伴うアルゴリズム プログラム。
  4. さまざまな動的データ構造を操作できます。
  5. 基本的なデジタル画像処理機能を備えています。
  6. さまざまな構造を分析できます。
  7. カメラのキャリブレーション;
  8. 動きの分析;
  9. ターゲットの識別;
  10. 基本的な GUI 機能を備えています。

OpenCVをインストール

より簡単にインストールするには、Anaconda を使用することをお勧めします。

キー API

インポート方法:import cv2

読んだ

関数: 画像ファイルの読み取り
関数プロトタイプ: imread(filename, flags)
パラメータの紹介:

パラメータ 例証する
ファイルパス image へのフルパスを読む
フラグ フラグビット、読み込み画像のフォーマット {cv2.IMREAD_COLOR, cv2.IMREAD_GRAYSCALE, cv2.IMREAD_UNCHANGED}

フラグのパラメータの詳細な紹介は次のとおりです。

フラグビット 例証する
cv2.IMREAD_COLOR カラー画像を読み込み、アルファチャンネルを無視するデフォルトのパラメータは、実際のパラメータとして 1 に置き換えることができます
cv2.IMREAD_GRAYSCALE グレースケール イメージを読み込みます。代わりに 0 を引数として使用できます
cv2.IMREAD_UNCHANGED 名前が示すように、引数として -1 に置き換えることができるアルファ チャネルを含む完全なイメージを読み込みます。

注: A チャネルとも呼ばれるアルファ チャネルは、8 ビットのグレースケール チャネルです。このチャネルは、256 レベルのグレースケールを使用して画像の透明度情報を記録し、透明、不透明、半透明の領域を定義します。完全な透明を意味し、白は不透明を意味し、グレーは半透明を意味します

名前付きウィンドウ

機能 ·: 新しい表示ウィンドウを作成します。窓の種類を指定できます。
関数プロトタイプ: void nameWindow(const string& winname,int flags = WINDOW_AUTOSIZE) ;
パラメータ紹介:

パラメータ 例証する
ウィンネーム ウィンドウの名前
WINDOW_AUTOSIZE ウィンドウの ID。デフォルトは WINDOW_AUTOSIZE です。

2 番目のパラメーターについては、ここで詳しく説明します。

ロゴの分類 例証する
WINDOW_AUTOSIZE ウィンドウ サイズは画像サイズに自動的に適応し、手動で変更することはできません。
WINDOW_NORMAL ユーザーはこのウィンドウのサイズを変更できます
WINDOW_OPENGL ウィンドウの作成時に OpenGL がサポートされる

cv2.imshow() を使用する場合、画像が大きすぎると不完全になり、調整できません。したがってcv2.imshow()、その前に次のステートメントを追加しcv2.namedWindow('image', 0)ます。
ここで、namedWindow と imshow のウィンドウ名は同じである必要があることに注意してください。そうしないと、複数のウィンドウが作成されます。
waitKey: 待機時間をミリ秒単位で示します。0 は待機を意味します。

import cv2
import sys

img = cv2.imread("C:\\Users\\Administrator\\Desktop\\9.jpg", 1)  # 参数1:图片路径。参数2:显示原图
cv2.namedWindow("aa", 0)
cv2.imshow("aa", img)
cv2.waitKey(0) # 0表示不自动退出  如5000表示等待5秒

操作結果:
ここに画像の説明を挿入

cv2.VideoCapture(0)

The parameter 0 means that the first camera in the computer is used by default. 既存のビデオを読み取る必要がある場合、パラメーターはビデオが配置されているパスに変更されます

cap=cv2.VideoCapture('video.mp4')

カスケード分類子

OpenCV の下の data\haarcascades には、haar 機能でトレーニングされた 4 つのカスケード分類器があります。

  1. haarcascade_frontalface_alt.xml
  2. haarcascade_frontalface_alt_tree.xml
  3. haarcascade_frontalface_alt2.xml
  4. haarcascade_frontalface_default.xml
    では、ここではカスケード分類子について説明していません。興味のある友人は、カスケード分類子について詳しく学んでください。

このプロジェクトでは、haarcascade_frontalface_alt2. 分類子が使用されます。CascadeClassifier 関数を使用して分類子を追加します。

classfier = cv2.CascadeClassifier("./model/haarcascade_frontalface_alt2.xml")

cap.isOpened()

ビデオ オブジェクトが正常に読み取られたかどうかを判断し、ビデオ オブジェクトが正常に読み取られた場合は True を返し、失敗した場合は False を返します。

わかりました、フレーム = cap.read()

戻り値okは1フレーム分のデータを読み込んだ場合のboolean型で、正しく読み込めた場合はTrue、読み込みに失敗した場合や動画の最後まで読み込めた場合はFalseを返します。フレームは各フレームの画像で、画像は 3 次元の行列、つまり frame.shape = (640,480,3) であり、読み取った画像はBGR形式です。

cv2.cvtColor(フレーム, cv2.COLOR_BGR2GRAY)

関数: 色空間変換関数。最初のパラメーターは変換する画像、2 番目のパラメーターは変換する形式です。

フォーマット紹介

フォーマット 例証する
cv2.COLOR_BGR2RGB BGR 形式を RGB 形式に変換する
cv2.COLOR_BGR2GRAY BGR 形式をグレースケール イメージに変換する

classfier.detectMultiScale

関数: 写真内のすべての顔を検出し、各顔の座標とサイズをベクトル (長方形で表される) に保存
関数プロトタイプ: void detectMultiScale(const Mat& image,CV_OUT vector & objects,double scaleFactor = 1.1,int minNeighbors = 3, int flags = 0,Size minSize = Size(),Size maxSize = Size());

パラメータ紹介:

パラメータ 例証する
画像 検出する画像は、通常、検出速度を上げるためにグレースケール画像です。
オブジェクト 検出されたオブジェクトの長方形フレーム ベクトル グループ。
スケール係数 2 つの連続したスキャンでの検索ウィンドウの倍率を示します。デフォルトは 1.1 です。つまり、各検索ウィンドウが 10% ずつ拡大されます。
minNeighbors 検出対象を構成する隣接する長方形の最小数を示します (既定値は 3)。検出対象を構成する小さな四角形の数が min_neighbors - 1 未満の場合は除外されます。min_neighbors が 0 の場合、関数は検出されたすべての候補矩形を何も操作せずに返します. この設定値は、通常、検出結果のユーザー定義の組み合わせプログラムで使用されます。
フラグ デフォルト値を使用するか、CV_HAAR_DO_CANNY_PRUNING を使用します。CV_HAAR_DO_CANNY_PRUNING に設定すると、関数はキャニー エッジ検出を使用して、エッジが多すぎるまたは少なすぎる領域を除外します。したがって、これらの領域は通常、顔が配置されている領域ではありません。
minSizeとmaxSize 取得したターゲット領域の範囲を制限するために使用されます。

cv2.rectangle

機能: 対角線上の 2 つの頂点によって、指定された単純な太さまたは塗りつぶされた四角形を描画します。
ここでは、主に顔領域をフレーミングするために使用されます。
関数プロトタイプ: voidrectangle(Mat& img, Point pt1, Point pt2, const Scalar& color, int thickness=1, int lineType=8, int shift=0)

パラメータ紹介:

パラメータ 例証する
画像 画像。
pt1 四角形の頂点。
pt2 長方形の対角線上の別の頂点
线条颜色 (RGB) 或亮度(灰度图像 )(grayscale image)。
thickness 组成矩形的线条的粗细程度。取负值时(如 CV_FILLED)函数绘制填充了色彩的矩形。
line_type 线条的类型。见cvLine的描述
shift 坐标点的小数点位数。

框出人脸区域
通过 OpenCV 的 Harr 分类器检测人脸,并输出识别结果(x,y,w,h)。
图片坐标以左上角为原点;
(x,y)代表人脸区域左上角坐标;
w代表人脸区域的宽度(width);
h代表人脸区域的高度(height)。

x, y, w, h = faceRect  # 原图上框出需要保存的图
color = (0, 0, 255)  # 识别出人脸后要画的边框的颜色,RGB格式

# frame 是原图,(x - 10, y - 10) 是图片的左上角的那个点,(x + w + 10, y + h + 10)是图片右下角的点 color, 2 颜色和线的宽度
cv2.rectangle(frame, (x - 10, y - 10), (x + w + 10, y + h + 10), color, 2)

imwrite

功能:用于将图像保存到指定的文件,可以为各种格式的图像。
函数原型:imwrite(const String & filename,InputArray img,const std::vector & params = std::vector<int>() )
参数介绍

参数 说明
filename 需要保存图像的文件名,要保存图片为哪种格式,就带什么后缀。
img 要保存的图像。
params 表示为特定格式保存的参数编码。

编码参数:

编码 说明
IMWRITE_JPEG_QUALITY Python :cv.IMWRITE_JPEG_QUALITY 对于JPEG,它可以是从0到100的质量(越高越好)。默认值为95。
IMWRITE_JPEG_PROGRESSIVE Python:cv.IMWRITE_JPEG_PROGRESSIVE 启用JPEG功能,0或1,默认为False。
IMWRITE_JPEG_OPTIMIZE Python:cv.IMWRITE_JPEG_OPTIMIZE 启用JPEG功能,0或1,默认为False。
IMWRITE_JPEG_RST_INTERVAL Python:cv.IMWRITE_JPEG_RST_INTERVAL JPEG重启间隔,0 - 65535,默认为0 - 无重启。
IMWRITE_JPEG_LUMA_QUALITY Python:cv.IMWRITE_JPEG_LUMA_QUALITY 单独的亮度质量等级,0 - 100,默认为0 - 不使用。
IMWRITE_JPEG_CHROMA_QUALITY Python:cv.IMWRITE_JPEG_CHROMA_QUALITY 单独的色度质量等级,0 - 100,默认为0 - 不使用。
IMWRITE_PNG_COMPRESSION Python:cv.IMWRITE_PNG_COMPRESSION 对于PNG,它可以是从0到9的压缩级别。值越高意味着更小的尺寸和更长的压缩时间。如果指定,则策略更改为IMWRITE_PNG_STRATEGY_DEFAULT(Z_DEFAULT_STRATEGY)。默认值为1(最佳速度设置)。
IMWRITE_PNG_STRATEGY Python:cv.IMWRITE_PNG_STRATEGY 其中一个品种:: ImwritePNGFlags,默认为IMWRITE_PNG_STRATEGY_RLE。
IMWRITE_PNG_BILEVEL Python:cv.IMWRITE_PNG_BILEVEL 二进制级别PNG,0或1,默认为0。
IMWRITE_PXM_BINARY Python:cv.IMWRITE_PXM_BINARY 对于PPM,PGM或PBM,它可以是二进制格式标志,0或1.默认值为1。
IMWRITE_WEBP_QUALITY Python:cv.IMWRITE_WEBP_QUALITY 覆盖EXR存储类型(默认为FLOAT(FP32))对于WEBP,它可以是1到100的质量(越高越好)。默认情况下(不带任何参数),如果质量高于100,则使用无损压缩。
IMWRITE_PAM_TUPLETYPE Python:cv.IMWRITE_PAM_TUPLETYPE 对于PAM,将TUPLETYPE字段设置为为格式定义的相应字符串值。
IMWRITE_TIFF_RESUNIT Python:cv.IMWRITE_TIFF_RESUNIT 对于TIFF,用于指定要设置的DPI分辨率单位; 请参阅libtiff文档以获取有效值。
IMWRITE_TIFF_XDPI Python:cv.IMWRITE_TIFF_XDPI 对于TIFF,用于指定X方向DPI。
IMWRITE_TIFF_YDPI Python:cv.IMWRITE_TIFF_YDPI 对于TIFF,用于指定Y方向DPI。
IMWRITE_TIFF_COMPRESSION Python:cv.IMWRITE_TIFF_COMPRESSION 对于TIFF,用于指定图像压缩方案。请参阅libtiff以获取与压缩格式对应的整数常量。注意,对于深度为CV_32F的图像,仅使用libtiff的SGILOG压缩方案。对于其他支持的深度,可以通过此标志指定压缩方案; LZW压缩是默认值。
IMWRITE_JPEG2000_COMPRESSION_X1000 Python:cv.IMWRITE_JPEG2000_COMPRESSION_X1000 对于JPEG2000,用于指定目标压缩率(乘以1000)。该值可以是0到1000.默认值是1000。

rectangle

功能:是在图像上绘制一个简单的矩形
函数原型:cv2.rectangle(img, pt1, pt2, color[, thickness[, lineType[, shift]]])

参数介绍

参数 说明
img 图片路径
pt1 和 pt2 これらはそれぞれ長方形の左上隅と右下隅を表し、x 座標軸は水平方向、y 座標軸は垂直方向です。(pt1 座標の x または y が pt2 座標の x または y より大きい場合、pt1 および pt2 パラメーターはそれぞれ長方形の左下および右上隅を表し、pt1 および pt2 は両方とも整数でなければなりません)
長方形の境界線の色は、ここでの 3 つ (0、0、255) がそれぞれ BGR に対応することに注意してください。
厚さ CV_FILLED のように、長方形の境界線の太さが負の場合、長方形全体を塗りつぶすことを意味します。
線種 アルゴリズムチャネル
シフト ポイント座標の小数点以下の桁数

cv2.FONT_HERSHEY_SIMPLEX

ははは、これは主に、現在何枚の顔写真がキャプチャされているかを示すためのものです。そのため、そこに立って写真を撮っているときに、黒い目を汚して待つ必要がなくなります。

cv2.putText

関数: 写真にテキストを追加
関数プロトタイプ: cputText(img, text, org, fontFace, fontScale, color, thickness=None, lineType=None, bottomLeftOrigin=None):

パラメータ紹介:

パラメータ 例証する
画像 写真
文章 追加するテキスト
組織 画像にテキストを追加する位置
フォントフェイス フォントの種類
fontScale フォントサイズ
フォントの色
太さフォントの太さ

語()

機能:文字のASCII値を返す。入力qアクティブエンド用です。

コード

# coding: utf-8

import cv2
import sys

def catch_usb_video(window_name, camera_idx):
    '''使用cv2.imshow()的时候,如果图片太大,会显示不全并且无法调整。
    因此在cv2.imshow()的前面加上这样的一个语句:cv2.namedWindow('image', 0),
    得到的图像框就可以自行调整大小,可以拉伸进行自由调整。'''
    cv2.namedWindow(window_name, 0)

    # 视频来源,可以来自一段已存好的视频,也可以直接来自USB摄像头
    cap = cv2.VideoCapture(camera_idx)

    # 告诉OpenCV使用人脸识别分类器  级联分类器
    '''
    Haar特征是一种反映图像的灰度变化的,像素分模块求差值的一种特征。它分为三类:边缘特征、线性特征、中心特征和对角线特征。
    '''
    classfier = cv2.CascadeClassifier("./model/haarcascade_frontalface_alt2.xml")
    # 识别出人脸后要画的边框的颜色,RGB格式
    color = (0, 0, 255)
    num = 0
    while cap.isOpened():
        ok, frame = cap.read()  # 读取一帧数据
        if not ok:
            break
            # 将当前帧转换成灰度图像
        grey = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        # 人脸检测,1.2和2分别为图片缩放比例和需要检测的有效点数
        faceRects = classfier.detectMultiScale(grey, scaleFactor=1.2, minNeighbors=3, minSize=(32, 32))
        #  faceRects = [405 237 222 222]
        if len(faceRects) > 0:  # 大于0则检测到人脸
            for faceRect in faceRects:  # 单独框出每一张人脸
                # 在原图上框出需要保存的图
                x, y, w, h = faceRect
                cv2.rectangle(frame, (x - 10, y - 10), (x + w + 10, y + h + 10), color, 2)
                # 将当前帧保存为图片
                # frame 是原图,(x - 10, y - 10) 是图片的左上角的那个点,(x + w + 10, y + h + 10)是图片右下角的点
                # color, 2 颜色和线的宽度
                img_name = '%s/%d.jpg' % ('./deep_learning/zhangmeng', num)
                image = frame[y - 10: y + h + 10, x - 10: x + w + 10]
                cv2.imwrite(img_name, image)
                num += 1
                if num > (500):  # 如果超过指定最大保存数量退出循环
                    break
            # 画出矩形框
            cv2.rectangle(frame, (x - 10, y - 10), (x + w + 10, y + h + 10), color, 2)
            # 显示当前捕捉到了多少人脸图片了,这样站在那里被拍摄时心里有个数,不用两眼一抹黑傻等着
            font = cv2.FONT_HERSHEY_SIMPLEX
            cv2.putText(frame, 'num:%d' % (num), (x + 30, y + 30), font, 1, (255, 0, 255), 4)
            # 超过指定最大保存数量结束程序
        if num > (500):
            break
        # 显示图像
        cv2.imshow(window_name, frame)
        c = cv2.waitKey(1)
        if c & 0xFF == ord('q'):
            break
    # 释放摄像头并销毁所有窗口
    cap.release()
    cv2.destroyAllWindows()


if __name__ == '__main__':
    catch_usb_video("face", 0)

運用実績

私の友人が識別テストに出演しました
ここに画像の説明を挿入

ここでは、写真が正常に保存されていることも確認できます。
ここに画像の説明を挿入

要約する

というわけでここまでで、今のところOpenCV関連のいくつかのAPI関数を理解するのが一番難しいと感じています。他に過度な技術設計はありません。

おすすめ

転載: blog.csdn.net/qq_45254369/article/details/126376276