1. 程式人生 > >程式碼C++, opencv實現人臉識別,人臉檢測,人臉匹配,視訊中的人臉檢測,攝像頭下的人臉檢測等

程式碼C++, opencv實現人臉識別,人臉檢測,人臉匹配,視訊中的人臉檢測,攝像頭下的人臉檢測等

前一段時間寫了一個人臉相關的演算法,包括視訊中的人臉檢測,相機的人臉檢測,影象中人臉檢測,還有人臉識別。

使用的是VS2013和opencv。

首先建立標頭檔案common.h

#ifndef _COMMON_H
#define _COMMON_H

#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <fstream>
#include <string>
#include <ctime>
#include <io.h>
#include <direct.h>
//#include <cstdlib>


static const char help[] = "face detection on image:   needs image\n" \
                            "face detection on video:   needs video\n"  \
                            "face detection on camera:  needs camera\n" \
                            "face recognition:  needs images\n";

/*
  功能:判斷該路徑指向的是檔案還是資料夾

  函式:isFileOrFolder
  
  檔案返回:   0
  資料夾返回: 1  
*/
bool isFileOrFolder(const std::string fileName);

#endif
然後就是建立common.cpp檔案,這裡面有相關的實現。
#include "common.h"

bool isFileOrFolder(const std::string fileName)
{
  const char* path = fileName.c_str();
  struct _stat buf = { 0 };
  _stat(path, &buf);
  return buf.st_mode & _S_IFDIR;
}
然後就是視訊中的人臉檢測建立檔案face_detection_video.h
#ifndef _FACE_DETETION_VIDEO_H_
#define _FACE_DETETION_VIDEO_H_

#include "common.h"
void face_detetion_video(const std::string videoPath, const std::string cascadeName);

#endif

接著建立對應的cpp檔案,face_detection_video.cpp

#include "face_deteion_video.h"

void face_detetion_video(const std::string videoPath, const std::string cascadeName)
{
  cv::VideoCapture cap(videoPath);
  if (!cap.isOpened())
  {
    std::cout << "不能開啟該視訊檔案!" << std::endl;
    return;
  }

  double scale = 2;
  cv::CascadeClassifier cascade;
  cascade.load(cascadeName);
  std::vector<cv::Rect> faces;
  
  double fps = cap.get(CV_CAP_PROP_FPS);  //獲取幀率

  bool isVideoRewriteFile = true; // 是否把視訊重新寫入檔案, 預設是false:不重新寫入檔案
  double dWidth = 0;
  double dHeight = 0;
  cv::Size frameSize;
  cv::VideoWriter vdWr;
  if (isVideoRewriteFile)
  {
    dWidth = cap.get(CV_CAP_PROP_FRAME_WIDTH);
    dHeight = cap.get(CV_CAP_PROP_FRAME_HEIGHT);
    frameSize = cv::Size(static_cast<int>(dWidth), static_cast<int>(dHeight));

    size_t pos = videoPath.find_last_of('.');
    std::string videoWritePath = videoPath.substr(0, pos);
    videoWritePath = videoWritePath + "_Result.avi";
    vdWr = cv::VideoWriter(videoWritePath, CV_FOURCC('M', 'J', 'P', 'G'), fps, frameSize, true);
    if (!vdWr.isOpened())
    {
      std::cout << "不能寫入視訊!" << std::endl;
      isVideoRewriteFile = false;
    }
  }

  while (1)
  {
    cv::Mat_<uchar> frame;
    bool bSuccess = cap.read(frame);
    if (!bSuccess)
    {
      break;
    }

    cv::Mat smallImg(cvRound(frame.rows / scale), cvRound(frame.cols / scale), CV_8UC1);  //cvRound對double型資料進行四捨五入
    cv::resize(frame, smallImg, smallImg.size(), 0, 0, cv::INTER_LINEAR);
    cvtColor(smallImg, smallImg, CV_RGB2GRAY);
    cv::equalizeHist(smallImg, smallImg);                                                 //equalizeHist提高影象的亮度和對比度

    cascade.detectMultiScale(smallImg, faces,
                              1.1, 2, 0
                              /*|CV_HAAR_FIND_BIGGEST_OBJECT
                              |CV_HAAR_DO_ROUGH_SEARCH*/
                              | CV_HAAR_SCALE_IMAGE
                              ,
                              cv::Size(30, 30));

    for (std::vector<cv::Rect>::const_iterator r = faces.begin(); r != faces.end(); r++){
      cv::Rect rect(0, 0, 0, 0);

      rect.x = int(r->x*scale);
      rect.y = int(r->y*scale);
      rect.width = int((r->width - 1)*scale);
      rect.height = int((r->height - 1)*scale);

      cv::rectangle(frame, rect, cv::Scalar(0, 0, 0), 3, 8);
    }

    //是否把檢測結果寫入檔案
    if (isVideoRewriteFile)
    {
      vdWr.write(frame);
    }

    cv::imshow("Video", frame);
    cv::waitKey((int)(1000 / fps));

  }

  cap.release();
  vdWr.release();
}
然後是影象中的尋找人臉,檔名face_detection_img.h
#ifndef _FACE_DETETION_IMAGE_H_
#define _FACE_DETETION_IMAGE_H_

#include "common.h"

void face_detetion_img(const std::string imagePath, const std::string cascadeName);



#endif

接著就是對應標頭檔案face_detection_img.cpp
#include "face_detetion_img.h"


void face_detetion_img(const std::string imgPath, const std::string cascadeName)
{
  //bool fileOrFolder = isFileOrFolder(imgPath);
  
  std::ifstream fin;
  fin.open(imgPath);

  cv::CascadeClassifier cascade;
  double scale = 1.3;
  std::vector<cv::Rect> faces;
  cv::Mat gray;

  // --Detection
  cascade.load(cascadeName);
  std::string name;
  while (getline(fin, name)){
    name.erase(0, name.find_first_not_of(" \t"));
    name.erase(name.find_last_not_of(" \t") + 1);

    // Read Image
    cv::Mat_<uchar> image = cv::imread(name, 0);
    if (image.empty())
    {
      continue;
    }

    // Read Opencv Detection Bbx
    cv::Mat smallImg(cvRound(image.rows / scale), cvRound(image.cols / scale), CV_8UC1); //cvRound對double型資料進行四捨五入
    cv::resize(image, smallImg, smallImg.size(), 0, 0, cv::INTER_LINEAR);
    cv::equalizeHist(smallImg, smallImg);                                              //equalizeHist提高影象的亮度和對比度
    // --Detection
    cascade.detectMultiScale(smallImg, faces,
                              1.1, 2, 0
                              /*|CV_HAAR_FIND_BIGGEST_OBJECT
                              |CV_HAAR_DO_ROUGH_SEARCH*/
                              | CV_HAAR_SCALE_IMAGE
                              ,
                              cv::Size(30, 30));
    for (std::vector<cv::Rect>::const_iterator r = faces.begin(); r != faces.end(); r++){
      cv::Rect rect(0, 0, 0, 0);

      rect.x = int(r->x*scale);
      rect.y = int(r->y*scale);
      rect.width = int((r->width - 1)*scale);
      rect.height = int((r->height - 1)*scale);

      cv::rectangle(image, rect, cv::Scalar(0, 255, 0), 3, 8);
    }

    cv::imshow("test", image);
    char s = cv::waitKey(0);
    if ('s' == s )
    {
      size_t pos = name.find_last_of('.');
      std::string filename = name.substr(0, pos);
      
      filename = filename + ".bmp";
      std::cout << filename << std::endl;
      cv::imwrite(filename, image);
    }
  }
  fin.close();
}

然後就是從攝像投中讀取人臉資訊。建立檔案face_detection_camera.h
#ifndef _FACE_DETETION_CAMERA_H_
#define _FACE_DETETION_CAMERA_H_

#include "common.h"
void face_detetion_camera(const std::string cascadeName);

#endif
接著就是對應cpp檔案,face_detection_camera.cpp
#include "face_detetion_camera.h"

void face_detetion_camera(const std::string cascadeName)
{
  cv::VideoCapture cap(0);
  if (!cap.isOpened())
  {
    std::cout << "不能開啟該視訊檔案!" << std::endl;
    return;
  }

  double scale = 2;
  cv::CascadeClassifier cascade;
  cascade.load(cascadeName);
  std::vector<cv::Rect> faces;

  bool isVideoRewriteFile = false; // 是否把攝像頭讀取的資料寫入檔案。
  double dWidth = 0;
  double dHeight = 0;
  cv::Size frameSize;
  cv::VideoWriter vdWr;
  char tmp[1024] = { 0 };
  if (isVideoRewriteFile)
  {
    dWidth = cap.get(CV_CAP_PROP_FRAME_WIDTH);
    dHeight = cap.get(CV_CAP_PROP_FRAME_HEIGHT);
    frameSize = cv::Size(static_cast<int>(dWidth), static_cast<int>(dHeight));

    time_t t = time(0);
    memset(tmp, 0, sizeof(tmp));
    strftime(tmp, sizeof(tmp), "../camera_out_video/%Y.%m.%d-%H.%M.%S", localtime(&t));
    std::string videoWritePath(tmp);
    videoWritePath = videoWritePath + ".avi";
    vdWr = cv::VideoWriter(videoWritePath, CV_FOURCC('M', 'J', 'P', 'G'), 20, frameSize, true);
    if (!vdWr.isOpened())
    {
      std::cout << "不能寫入視訊!" << std::endl;
      isVideoRewriteFile = false;
    }
  }

  while (1)
  {
    cv::Mat frame;
    bool bSuccess = cap.read(frame);
    if (!bSuccess)
    {
      break;
    }

    cv::Mat smallImg(cvRound(frame.rows / scale), cvRound(frame.cols / scale), CV_8UC1);  //cvRound對double型資料進行四捨五入
    cv::resize(frame, smallImg, smallImg.size(), 0, 0, cv::INTER_LINEAR);
    cvtColor(smallImg, smallImg, CV_RGB2GRAY);
    cv::equalizeHist(smallImg, smallImg);                                                 //equalizeHist提高影象的亮度和對比度

    cascade.detectMultiScale(smallImg, faces,
                                1.1, 2, 0
                                /*|CV_HAAR_FIND_BIGGEST_OBJECT
                                |CV_HAAR_DO_ROUGH_SEARCH*/
                                | CV_HAAR_SCALE_IMAGE
                                ,
                                cv::Size(30, 30));

    for (std::vector<cv::Rect>::const_iterator r = faces.begin(); r != faces.end(); r++){
      cv::Rect rect(0, 0, 0, 0);

      rect.x = int(r->x*scale);
      rect.y = int(r->y*scale);
      rect.width = int((r->width - 1)*scale);
      rect.height = int((r->height - 1)*scale);

      cv::rectangle(frame, rect, cv::Scalar(0, 0, 0), 3, 8);
    }

    //是否把檢測結果寫入檔案
    if (isVideoRewriteFile)
    {
      vdWr.write(frame);
    }

    cv::imshow("Video", frame);
    if (27 == cv::waitKey(20)){     // 按下ESC鍵,結束視訊
      break;
    }

  }

  cap.release();
  vdWr.release();
}
最後是人臉識別的標頭檔案:face_recognition.h
#ifndef _FACE_RECOGNITION_H_
#define _FACE_RECOGNITION_H_

#include "common.h"

void preDeal_original_img(const std::string recognitionPath, const std::string cascadeName);
std::vector<std::pair<cv::Mat, std::string >> get_CropFace_And_ImgPathName(const std::string recognitionPath, const std::string cascadeName);
bool matchFace(cv::Mat detectFace, cv::Mat dbFace);
void face_recognition(std::string recognitionPath, const std::string cascadeName);

#endif

以及對應的cpp檔案:face_recognition.cpp

#include "face_recognition.h"

void preDeal_original_img(const std::string recognitionPath, const std::string cascadeName)
{
  std::ifstream fin;
  fin.open(recognitionPath);
  if (!fin)
  {
    std::cout << "Cannot open " + recognitionPath << std::endl;
    return;
  }

  // --Detection
  cv::CascadeClassifier cascade;
  cascade.load(cascadeName);
  if (cascade.empty())
  {
    std::cout << "Cascade path error!" << std::endl;
    return;
  }

  double scale = 1.3;
  std::vector<cv::Rect> faces;
  cv::Mat gray;

  std::string name;
  std::string camera_face = "../camera_face/";
  while (getline(fin, name)){
    if (name.empty())
    {
      continue;
    }
    name.erase(0, name.find_first_not_of(" \t"));
    name.erase(name.find_last_not_of(" \t") + 1);

    // Read Image
    cv::Mat img = cv::imread(name);
    if (img.empty())
    {
      continue;
    }

    cv::Mat_<uchar> image;
    if (img.channels() != 1)
    {
      cvtColor(img, image, CV_BGR2GRAY);
      image.convertTo(image, CV_8UC1);
    }
    else{
      image = img;
    }
    

    // 改變影象
    cv::Mat smallImg(cvRound(image.rows / scale), cvRound(image.cols / scale), CV_8UC1); //cvRound對double型資料進行四捨五入
    cv::resize(image, smallImg, smallImg.size(), 0, 0, cv::INTER_LINEAR);
    cv::equalizeHist(smallImg, smallImg);                                              //equalizeHist提高影象的亮度和對比度
    // --Detection
    cascade.detectMultiScale(smallImg, faces,
                              1.1, 3, 0
                              /*|CV_HAAR_FIND_BIGGEST_OBJECT
                              |CV_HAAR_DO_ROUGH_SEARCH*/
                              | CV_HAAR_SCALE_IMAGE
                              ,
                              cv::Size(30, 30));
    if (faces.size() > 0)
    {
      size_t pos = name.find_last_of('\\');
      std::string filename = name.substr(pos + 1);

      if (-1 == _access(camera_face.c_str(), 0))
      {
        _mkdir(camera_face.c_str());
      }

      filename = camera_face + filename;
      std::cout << filename << std::endl;
      cv::imwrite(filename, img);
    }

  }
  fin.close();

  //處理後的圖片路徑名寫入Path_Image.txt中
  std::string getImgPathTxt = "cd " + camera_face + " && dir /b/s/p/w *.jpg > Path_Images.txt";
  system(getImgPathTxt.c_str());
}

std::vector<std::pair<cv::Mat, std::string >> get_CropFace_And_ImgPathName(const std::string recognitionPath, const std::string cascadeName)
{
  std::vector<std::pair<cv::Mat, std::string>> cropFaceAndImgPathNames;
  std::pair<cv::Mat, std::string> cropFaceAndImgPathName;

  cv::CascadeClassifier cascade;
  cascade.load(cascadeName);
  if (cascade.empty())
  {
    std::cout << "Cascade path error!" << std::endl;
    return std::vector<std::pair<cv::Mat, std::string >>();
  }

  std::ifstream fdatabase;
  fdatabase.open(recognitionPath);
  if (!fdatabase)
  {
    std::cout << "Cannot open " + recognitionPath << std::endl;
    return std::vector<std::pair<cv::Mat, std::string >>();
  }

  double scale = 1.3;
  std::vector<cv::Rect> faces;
  cv::Mat gray;
  std::string name;
  
  std::cout << "[";

  while (getline(fdatabase, name)){
    if (name.empty())
    {
      continue;
    }
    name.erase(0, name.find_first_not_of(" \t"));
    name.erase(name.find_last_not_of(" \t") + 1);

    // Read Image
    cv::Mat img = cv::imread(name);
    if (img.empty())
    {
      continue;
    }
    cv::Mat image;
    if (img.channels() != 1)
    {
      cvtColor(img, image, CV_BGR2GRAY);
      image.convertTo(image, CV_8UC1);
    }
    else{
      image = img;
    }
    
    // Read Opencv Detection Bbx
    cv::Mat smallImg(cvRound(image.rows / scale), cvRound(image.cols / scale), CV_8UC1); //cvRound對double型資料進行四捨五入
    cv::resize(image, smallImg, smallImg.size(), 0, 0, cv::INTER_LINEAR);
    cv::equalizeHist(smallImg, smallImg);                                              //equalizeHist提高影象的亮度和對比度
    // --Detection
    cascade.detectMultiScale(smallImg, faces,
                              1.1, 3, 0
                              /*|CV_HAAR_FIND_BIGGEST_OBJECT
                              |CV_HAAR_DO_ROUGH_SEARCH*/
                              | CV_HAAR_SCALE_IMAGE
                              ,
                              cv::Size(30, 30));
    for (std::vector<cv::Rect>::iterator r = faces.begin(); r != faces.end(); r++)
    {
      cv::Rect face;
      face.x = int(r->x * scale);
      face.y = int(r->y * scale);
      face.width = int(r->width * scale);
      face.height = int(r->height * scale);

      // 邊界檢查,左邊界,上邊界,右邊界,下邊界。
      /*face.x = face.x < 1 ? 1 : face.x;
      face.y = face.y < 1 ? 1 : face.y;
      face.width = (face.x + face.width) > image.cols ? (image.cols - face.x) : face.width;
      face.height = (face.y + face.height) > image.rows ? (image.rows - face.y) : face.height;*/

      cv::Mat cropFace;
      cropFace = img(face);
      /*cv::moveWindow("cropface", 960 - cropFace.cols / 2, 540 - cropFace.rows / 2);
      cv::imshow("cropface", cropFace);
      cv::waitKey(100);
      cv::destroyWindow("cropface");*/
      
      cropFaceAndImgPathName = make_pair(cropFace, name);  //cropFaceAndImgPathName = std::pair<cv::Mat, std::string>(cropFace, name);

      cropFaceAndImgPathNames.push_back(cropFaceAndImgPathName);

      std::cout << '.';
    }

  }

  fdatabase.close();
  
  std::cout << "]" << std::endl;

  return cropFaceAndImgPathNames;
}

bool matchFace(cv::Mat detectFace, cv::Mat dbFace)
{
  IplImage* srcImg = cvCloneImage(&(IplImage)detectFace);
  IplImage* dstImg = cvCloneImage(&(IplImage)dbFace);

  IplImage* src;
  IplImage* dst;

  if (srcImg->nChannels != 1)
  {
    src = cvCreateImage(cvSize(srcImg->width, srcImg->height), srcImg->depth, 1);
    cvCvtColor(srcImg, src, CV_BGR2GRAY);
  }

  if (dstImg->nChannels != 1)
  {
    dst = cvCreateImage(cvSize(dstImg->width, dstImg->height), dstImg->depth, 1);
    cvCvtColor(dstImg, dst, CV_BGR2GRAY);
  }
 
  int histogramBins = 256;
  float histogramRange1[2] = { 0, 255 };
  float *histogramRange[1] = { &histogramRange1[0] };
  CvHistogram *Histogram1 = cvCreateHist(1, &histogramBins, CV_HIST_ARRAY, histogramRange);
  CvHistogram *Histogram2 = cvCreateHist(1, &histogramBins, CV_HIST_ARRAY, histogramRange);

  cvCalcHist(&src, Histogram1);
  cvCalcHist(&dst, Histogram2);
  
  cvNormalizeHist(Histogram1, 1);
  cvNormalizeHist(Histogram2, 1);
  
  
  // CV_COMP_CHISQR,CV_COMP_BHATTACHARYYA這兩種都可以用來做直方圖的比較,值越小,說明圖形越相似  
  //printf("CV_COMP_CHISQR : %.4f\n", cvCompareHist(Histogram1, Histogram2, CV_COMP_CHISQR));
  //printf("CV_COMP_BHATTACHARYYA : %.4f\n", cvCompareHist(Histogram1, Histogram2, CV_COMP_BHATTACHARYYA));  


  // CV_COMP_CORREL, CV_COMP_INTERSECT這兩種直方圖的比較,值越大,說明圖形越相似  
  //printf("CV_COMP_CORREL : %.4f\n", cvCompareHist(Histogram1, Histogram2, CV_COMP_CORREL));  
  //printf("CV_COMP_INTERSECT : %.4f\n", cvCompareHist(Histogram1, Histogram2, CV_COMP_INTERSECT));
  double simility = cvCompareHist(Histogram1, Histogram2, CV_COMP_CHISQR);

  if (simility > 0.5)
  {
    return false;
  }

  return true;
}

void face_recognition(std::string recognitionPath, const std::string cascadeName)
{
  bool isPreDeal = false;
  if (isPreDeal)              //是否進行預處理
  {
    preDeal_original_img(recognitionPath, cascadeName);
    recognitionPath = "../camera_face/";
  }

  //獲取資料庫中人臉影象
  std::string face_Database = "../face_database/Path_Images.txt";
  std::vector<std::pair<cv::Mat, std::string>> cropFaceAndImgPathNames;
  std::cout << "開始資料庫中人臉資料的讀取..." << std::endl;
  cropFaceAndImgPathNames = get_CropFace_And_ImgPathName(face_Database, cascadeName);
  std::cout << "結束資料庫中人臉資料的讀取。" << std::endl;

  //開始人臉匹配
  std::ifstream frecognition;
  frecognition.open(recognitionPath);
  if (!frecognition)
  {
    std::cout << "Images path Error!" << std::endl;
    return;
  }

  cv::CascadeClassifier cascade;
  cascade.load(cascadeName);
  if (cascade.empty())
  {
    std::cout << "Cascade path error!" << std::endl;
    return;
  }

  double scale = 1.3;
  std::vector<cv::Rect> faces;
  cv::Mat gray;
  std::string name;

  bool isExist = false;   //資料庫中是否存在該匹配檔案

  while (getline(frecognition, name)){
    if (name.empty())
    {
      continue;
    }
    name.erase(0, name.find_first_not_of(" \t"));
    name.erase(name.find_last_not_of(" \t") + 1);

    // Read Image
    cv::Mat img = cv::imread(name);
    cv::Mat image;
    if (img.channels() != 1)
    {
      cvtColor(img, image, CV_BGR2GRAY);
      image.convertTo(image, CV_8UC1);
    }
    else{
      image = img;
    }
    
    // Read Opencv Detection Bbx
    cv::Mat smallImg(cvRound(image.rows / scale), cvRound(image.cols / scale), CV_8UC1); //cvRound對double型資料進行四捨五入
    cv::resize(image, smallImg, smallImg.size(), 0, 0, cv::INTER_LINEAR);
    cv::equalizeHist(smallImg, smallImg);                                              //equalizeHist提高影象的亮度和對比度
    // --Detection
    cascade.detectMultiScale(smallImg, faces,
                              1.1, 3, 0
                              /*|CV_HAAR_FIND_BIGGEST_OBJECT
                              |CV_HAAR_DO_ROUGH_SEARCH*/
                              | CV_HAAR_SCALE_IMAGE
                              ,
                              cv::Size(30, 30));
    for (std::vector<cv::Rect>::iterator r = faces.begin(); r != faces.end(); r++)
    {
      cv::Rect face;
      face.x = int(r->x * scale);
      face.y = int(r->y * scale);
      face.width = int(r->width * scale);
      face.height = int(r->height * scale);

      cv::Mat detectFace = img(face);

      for (std::vector<std::pair<cv::Mat, std::string>>::iterator dbFace = cropFaceAndImgPathNames.begin(); dbFace != cropFaceAndImgPathNames.end(); dbFace++)
      {
        std::pair<cv::Mat, std::string> dbFaceImg = *dbFace;
        bool isMatch = matchFace(detectFace, dbFaceImg.first);
        if (isMatch){
          std::cout << name + " Matching " + dbFaceImg.second + " successful!" << std::endl;
          cv::imshow("detectFace", detectFace);
          cv::imshow("databaseFace", dbFaceImg.first);
          cv::waitKey(200);
          cv::destroyWindow("detectFace");
          cv::destroyWindow("databaseFace");
          isExist = true;
        }
      }

    }
  }

  if (!isExist)
  {
    std::cout << name + " Matching failed!" << std::endl;
  }

  frecognition.close();
}

還有最後的主函式:main.cpp
#include "common.h"
#include "face_detetion_img.h"
#include "face_deteion_video.h"
#include "face_detetion_camera.h"
#include "face_recognition.h"


int main(int argc, char ** argv)
{
  
  std::string cascadeFileName = "./../haarcascade_DataBase/haarcascade_frontalface_alt.xml";
  
  //bool fileOrDir = isFileOrFolder(filePath);
  
  if (argc < 2)
  {
    printf(help);
  }
  else if (strcmp(argv[1], "face_detetion_img") == 0)
  {
    std::string imgPath = "E:/1/ImagePath.txt";
    face_detetion_img(imgPath, cascadeFileName);
  }
  else if (strcmp(argv[1], "face_detetion_video") == 0)
  {
    std::string videoPath = "E:\\DeepLeaning\\codes\\FindFaceInVideo\\VGGFace\\chengshd\\IMG_3170.mp4";
    face_detetion_video(videoPath, cascadeFileName);
  }
  else if (strcmp(argv[1], "face_detetion_camera") == 0)
  {
    face_detetion_camera(cascadeFileName);
  }
  else if (strcmp(argv[1], "face_recognition") == 0)
  {
    std::string recognitionPath = "E:/camera/Path_Images.txt";
    face_recognition(recognitionPath, cascadeFileName);
  }
  else
  {
    printf(help);
  }

  return 0;
}
如果想使用程式碼,適當修改一下都是可以使用的。