中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

基于OpenCV讀取攝像頭實現單個人臉驗證MFC程序

發布時間:2020-10-19 23:46:12 來源:腳本之家 閱讀:166 作者:iteye_13202 欄目:編程語言

與上一篇博客類似,這篇博客介紹使用OpenCV實現的MFC程序,可以實現單個人臉的驗證,并在圖像和界面給出識別結果。效果圖如下:

基于OpenCV讀取攝像頭實現單個人臉驗證MFC程序

置信度一欄可以填寫判定的閾值,默認為70。打開攝像頭才能進行驗證或拍照,拍照之前可以清除之前拍攝的訓練圖片,可以拍攝多張用于識別。其中mfc中的圖像顯示需要用到CvImage.cpp和CvImage.h兩個文件,該代碼在比較新的OpenCV內已經沒有了,所以可以直接用我代碼里的。

有人說代碼的檢測率不高,其實可以歸結為兩方面的原因,第一人臉檢測率不高,這個可以通過嵌套檢測嘴角、眼睛等來降低,或者背景、光照固定的話可以通過圖像差分來解決;第二是識別方法本身的問題,如果想提高識別率,可以添加多張不同姿態、光照下的人臉作為訓練的樣本,如果有時間的話可以在采集圖像時給出一個人臉框,引導用戶對齊人臉進行采集,三星手機解除鎖屏就有這么一個功能。

下面貼一下主要的代碼:

VideoMFCDlg.cpp

// VideoMFCDlg.cpp : implementation file
//
 
#include "stdafx.h"
#include "VideoMFC.h"
#include "VideoMFCDlg.h"
#include "afxdialogex.h"
 
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
 
 
CvCapture* capture;
CRect rect;
CDC *pDC;
HDC hDC;
CWnd *pwnd;
CvVideoWriter* writer = 0;
IplImage *resizeRes;//存放檢測到的人臉
IplImage* faceGray;//存放檢測到的人臉 灰度圖像
bool bool_cameOpen = false;//全局變量 標志攝像頭是否打開
bool bool_picNum = false;//全局變量 標志訓練圖片是否為空
bool bool_detec_reco = false;//全局變量 
double dConfidence = 0;//置信度
int predictedLabel = 100000;
 
CvMemStorage* storage = 0;
CvHaarClassifierCascade* cascade = 0;
CvHaarClassifierCascade* nested_cascade = 0;
int use_nested_cascade = 0;
const char* cascade_name =
 "../data/haarcascades/haarcascade_frontalface_alt.xml";
const char* nested_cascade_name =
 "../data/haarcascade_eye_tree_eyeglasses.xml";
double scale = 1;
int num_components = 9;
double facethreshold = 9.0;
//cv::Ptr<cv::FaceRecognizer> model = cv::createFisherFaceRecognizer();
cv::Ptr<cv::FaceRecognizer> model = cv::createLBPHFaceRecognizer();//LBP的這個方法在單個人臉驗證方面效果最好
//cv::Ptr<cv::FaceRecognizer> model = cv::createEigenFaceRecognizer();
vector<Mat> images;
vector<int> labels;
 
IplImage *frame, *frame_copy = 0;
IplImage *image = 0;
const char* scale_opt = "--scale="; // 分類器選項指示符號 
int scale_opt_len = (int)strlen(scale_opt);
const char* cascade_opt = "--cascade=";
int cascade_opt_len = (int)strlen(cascade_opt);
const char* nested_cascade_opt = "--nested-cascade";
int nested_cascade_opt_len = (int)strlen(nested_cascade_opt);
int i;
const char* input_name = 0;
 
// CAboutDlg dialog used for App About
CString strConfidence = "70";
CEdit* pEdtConfidence;
CString strTip = "";
CEdit* pTip;
 
class CAboutDlg : public CDialogEx
{
public:
 CAboutDlg();
 
// Dialog Data
 enum { IDD = IDD_ABOUTBOX };
 
 protected:
 virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
 
// Implementation
protected:
 DECLARE_MESSAGE_MAP()
};
 
CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
{
}
 
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
 CDialogEx::DoDataExchange(pDX);
}
 
BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()
 
 
// CVideoMFCDlg dialog
 
 
 
 
CVideoMFCDlg::CVideoMFCDlg(CWnd* pParent /*=NULL*/)
 : CDialogEx(CVideoMFCDlg::IDD, pParent)
{
 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
 
void CVideoMFCDlg::DoDataExchange(CDataExchange* pDX)
{
 CDialogEx::DoDataExchange(pDX);
}
 
BEGIN_MESSAGE_MAP(CVideoMFCDlg, CDialogEx)
 ON_WM_SYSCOMMAND()
 ON_WM_PAINT()
 ON_WM_QUERYDRAGICON()
 ON_BN_CLICKED(IDC_BUTTON1, &CVideoMFCDlg::OnBnClickedButton1)
 ON_WM_TIMER()
 ON_BN_CLICKED(IDC_BUTTON2, &CVideoMFCDlg::OnBnClickedButton2)
 ON_WM_CLOSE()
 ON_EN_CHANGE(IDC_EdtConfidence, &CVideoMFCDlg::OnEnChangeEdtconfidence)
 ON_BN_CLICKED(IDC_Photograph, &CVideoMFCDlg::OnBnClickedPhotograph)
 ON_BN_CLICKED(IDC_Recognize, &CVideoMFCDlg::OnBnClickedRecognize)
 ON_BN_CLICKED(IDC_ClearPictures, &CVideoMFCDlg::OnBnClickedClearpictures)
END_MESSAGE_MAP()
 
 
// CVideoMFCDlg message handlers
BOOL CVideoMFCDlg::OnDestroy()
{
 cvReleaseImage( &resizeRes );
 cvReleaseImage( &faceGray );
 return TRUE; 
}
BOOL CVideoMFCDlg::OnInitDialog()
{
 CDialogEx::OnInitDialog();
 
 // Add "About..." menu item to system menu.
 
 // IDM_ABOUTBOX must be in the system command range.
 ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
 ASSERT(IDM_ABOUTBOX < 0xF000);
 
 CMenu* pSysMenu = GetSystemMenu(FALSE);
 if (pSysMenu != NULL)
 {
 BOOL bNameValid;
 CString strAboutMenu;
 bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
 ASSERT(bNameValid);
 if (!strAboutMenu.IsEmpty())
 {
 pSysMenu->AppendMenu(MF_SEPARATOR);
 pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
 }
 }
 
 
 // Set the icon for this dialog. The framework does this automatically
 // when the application's main window is not a dialog
 SetIcon(m_hIcon, TRUE); // Set big icon
 SetIcon(m_hIcon, FALSE); // Set small icon
 
 // TODO: Add extra initialization here
 pwnd = GetDlgItem(IDC_ShowImage);
 //pwnd->MoveWindow(35,30,352,288);
 pDC =pwnd->GetDC();
 //pDC =GetDC();
 hDC= pDC->GetSafeHdc();
 pwnd->GetClientRect(&rect);
 
 GetDlgItem(IDC_BUTTON2)->EnableWindow(false);
 GetDlgItem(IDC_Photograph)->EnableWindow(false);
 GetDlgItem(IDC_Recognize)->EnableWindow(false);
 pEdtConfidence = (CEdit*) GetDlgItem(IDC_EdtConfidence);
 pTip = (CEdit*) GetDlgItem(IDC_Tip);
 pEdtConfidence->SetWindowText("70");
 pEdtConfidence->GetWindowText(strConfidence);
 pTip->SetWindowText( strTip );
 if(read_img_number()>0)
 bool_picNum = true;
 else
 bool_picNum = false;
 return TRUE; // return TRUE unless you set the focus to a control
}
 
void CVideoMFCDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
 if ((nID & 0xFFF0) == IDM_ABOUTBOX)
 {
 CAboutDlg dlgAbout;
 dlgAbout.DoModal();
 }
 else
 {
 CDialogEx::OnSysCommand(nID, lParam);
 }
}
 
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
 
void CVideoMFCDlg::OnPaint()
{
 if (IsIconic())
 {
 CPaintDC dc(this); // device context for painting
 
 SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
 
 // Center icon in client rectangle
 int cxIcon = GetSystemMetrics(SM_CXICON);
 int cyIcon = GetSystemMetrics(SM_CYICON);
 CRect rect;
 GetClientRect(&rect);
 int x = (rect.Width() - cxIcon + 1) / 2;
 int y = (rect.Height() - cyIcon + 1) / 2;
 
 // Draw the icon
 dc.DrawIcon(x, y, m_hIcon);
 }
 else
 {
 CDialogEx::OnPaint();
 }
}
 
// The system calls this function to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CVideoMFCDlg::OnQueryDragIcon()
{
 return static_cast<HCURSOR>(m_hIcon);
}
 
 
/*****************************************打開攝像頭*******************************************/
void CVideoMFCDlg::OnBnClickedButton1()
{
 // TODO: Add your control notification handler code here
 //AfxMessageBox("OK");
 if(!capture)
 {
 capture = cvCaptureFromCAM(0);
 //AfxMessageBox("OK");
 }
 
 if (!capture)
 {
 AfxMessageBox("無法打開攝像頭");
 return;
 }
 //writer=cvCreateVideoWriter("MyVideo.avi",CV_FOURCC('x','v','I','D'),25,cvSize(640,480));
 // 測試
 IplImage* m_Frame;
 m_Frame=cvQueryFrame(capture);
 CvvImage m_CvvImage;
 m_CvvImage.CopyOf(m_Frame,1); 
 if (true)
 {
 m_CvvImage.DrawToHDC(hDC, &rect);
 //cvWaitKey(10);
 }
 
 // 設置計時器,每10ms觸發一次事件
 SetTimer(1,10,NULL);
 
 
 cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name, 0, 0, 0 ); // 加載分類器 
 if( !cascade ) 
 {
  MessageBox("無法加載分類器文件,請確認!");
 }
 storage = cvCreateMemStorage(0); // 創建內存存儲器 
 
 //if( !input_name || (isdigit(input_name[0]) && input_name[1] == '\0') ) // 判斷輸入參數是視頻序號,還是文件 
  capture = cvCaptureFromCAM( !input_name ? 0 : input_name[0] - '0' ); // 創建視頻讀取結構 
 /*
 else if( input_name )
 {
  image = cvLoadImage( input_name, 1 ); // 如果是圖像則加載 
  if( !image )
 {
   capture = cvCaptureFromAVI( input_name ); // 不是圖像則嘗試視頻讀取 
 cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 640); 
 cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, 480); ////////////////////////////////////////////////////////////////////
 }
 }*/
 //else
 // image = cvLoadImage( "lena.bmp", 1 ); //都沒有則調用程序所在目錄的lena.jpg圖片 
 //cvNamedWindow( "result", 1 );
 
 GetDlgItem(IDC_BUTTON1)->EnableWindow(false);
 GetDlgItem(IDC_BUTTON2)->EnableWindow(true);
 GetDlgItem(IDC_Photograph)->EnableWindow(true);
 GetDlgItem(IDC_Recognize)->EnableWindow(true);
 bool_detec_reco = false;
 bool_cameOpen = true;
}
 
/********************************************設置定時器*********************************************/
void CVideoMFCDlg::OnTimer(UINT_PTR nIDEvent)
{
 //顯示攝像頭
 IplImage* m_Frame;
 m_Frame=cvQueryFrame(capture);
 //AllocConsole();
 //判斷是檢測還是識別人臉
 if(bool_cameOpen)
 {
 if(!bool_detec_reco)//false只為識別
 {
 detect_and_draw(m_Frame);//檢測人臉
 //_cprintf("%s\n", "jiance");
 }
 else if(bool_picNum)//false代表訓練圖片為空
 recog_and_draw(m_Frame);//檢測和識別人臉
 }
 CvvImage m_CvvImage;
 m_CvvImage.CopyOf(m_Frame,1); 
 if (true)
 {
 m_CvvImage.DrawToHDC(hDC, &rect);
 //cvWriteFrame(writer,m_Frame); //將幀圖像通過writer寫入文件
 //cvWaitKey(10);
 }
 if(bool_detec_reco)
 {
 if(predictedLabel <= dConfidence)
 {
 CString tipPhoto = strTip + "\r\n驗證成功!!";
 pTip->SetWindowText( tipPhoto );
 }
 else
 {
 CString tipPhoto = strTip + "\r\n驗證失敗!!";
 pTip->SetWindowText( tipPhoto );
 }
 }
 
 CDialogEx::OnTimer(nIDEvent);
}
 
//關閉攝像頭按鈕
void CVideoMFCDlg::OnBnClickedButton2()
{
 // TODO: Add your control notification handler code here
 cvReleaseVideoWriter(&writer);
 cvReleaseCapture(&capture);
 CDC MemDC; 
 CBitmap m_Bitmap1;
 m_Bitmap1.LoadBitmap(IDB_BITMAP1); 
 MemDC.CreateCompatibleDC(NULL);
 MemDC.SelectObject(&m_Bitmap1);
 pDC->StretchBlt(rect.left,rect.top,rect.Width(),rect.Height(),&MemDC,0,0,48,48,SRCCOPY); 
 GetDlgItem(IDC_BUTTON1)->EnableWindow(true);
 GetDlgItem(IDC_BUTTON2)->EnableWindow(false);
 GetDlgItem(IDC_Photograph)->EnableWindow(false);
 GetDlgItem(IDC_Recognize)->EnableWindow(false);
 bool_cameOpen = false;
}
 
//關閉窗體
void CVideoMFCDlg::OnClose()
{
 // TODO: Add your message handler code here and/or call default
 cvReleaseCapture(&capture);
 CDialogEx::OnClose();
}
 
 
 
void CVideoMFCDlg::OnEnChangeEdtconfidence()
{
}
 
//拍照按鈕
void CVideoMFCDlg::OnBnClickedPhotograph()
{
 // TODO: 在此添加控件通知處理程序代碼
 if (!faceGray)
 {
 pTip->GetWindowText(strTip);
 CString tipPhoto = strTip + "\r\n拍照失敗,請將攝像頭對準人臉";
 pTip->SetWindowText( tipPhoto );
 return;
 }
 Mat img(faceGray,0);
 stringstream ss;
 ss << (read_img_number()+1);
 string faceImgName = "..//einfacedata//trainingdata//"+ss.str()+".jpg";
 imwrite(faceImgName,img);
 
 //pTip->GetWindowText(strTip);
 CString tipPhoto = strTip + "\r\n拍照成功!已存為" + ("/einfacedata/trainingdata/"+ss.str()+".jpg").c_str();
 pTip->SetWindowText( tipPhoto );
 //MessageBox("OK");
}
 
//開始驗證按鈕
void CVideoMFCDlg::OnBnClickedRecognize()
{
 // TODO: 在此添加控件通知處理程序代碼
 images.clear();
 labels.clear();
 pEdtConfidence->GetWindowText(strConfidence);
 
 try
 {
 dConfidence = atoi((const char *)strConfidence); 
 }
 catch(cv::Exception &e)
 {
 MessageBox("置信度請輸入整數!");
 return;
 }
 
 model->set("threshold", dConfidence);
 //string output_folder;
 //output_folder = string("../einfacedata");
 
 //讀取你的CSV文件路徑
 //string fn_csv = string("../einfacedata/at.txt");
 
 //兩個容器來存放圖像數據和對應的標簽
 /*
 try
 {
 read_csv(fn_csv, images, labels); 
 }
 catch(cv::Exception &e)
 {
 cerr<<"Error opening file "<<fn_csv<<". Reason: "<<e.msg<<endl;
 exit(1);
 }
 */
 if(!read_img(images, labels))
 {
 AfxMessageBox("Error in reading images!");
 //MessageBox("Error in reading images!");
 images.clear();
 labels.clear();
 return;
 }
 
 //如果沒有讀到足夠的圖片,就退出
 if(images.size() < 1)
 {
 MessageBox("This demo needs at least 1 images to work!");
 return;
 }
 //training
 model->train(images, labels);
 
 bool_detec_reco = true;
 bool_picNum = true;
 
}
 
//清除訓練圖片
void CVideoMFCDlg::OnBnClickedClearpictures()
{
 // TODO: 在此添加控件通知處理程序代碼
 if(delete_img())
 {
 //pTip->GetWindowText(strTip);
 CString tipPhoto = strTip + "\r\n刪除成功!";
 pTip->SetWindowText( tipPhoto );
 bool_detec_reco = false;
 bool_picNum = false;
 }
 else
 {
 //pTip->GetWindowText(strTip);
 CString tipPhoto = strTip + "\r\n刪除失敗!";
 pTip->SetWindowText( tipPhoto );
 }
}

detect_recog.cpp和上一篇博客類似

#include "stdafx.h"
#include "cv.h"
#include "highgui.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <math.h>
#include <float.h>
#include <limits.h>
#include <time.h>
#include <ctype.h>
#include "detect_recog.h"
#include <opencv2\contrib\contrib.hpp> 
#include <opencv2\core\core.hpp> 
#include <opencv2\highgui\highgui.hpp> 
#include <iostream>
#include <fstream>
#include <sstream>
#include <stdio.h>
#include <io.h> 
#include <direct.h> 
#include <sys/types.h>
#include <conio.h>
using namespace std;
using namespace cv;
void detect_and_draw( IplImage* img ) // 只是檢測,并圈出人臉
{
 static CvScalar colors[] = 
 {
  {{0,0,255}},
  {{0,128,255}},
  {{0,255,255}},
  {{0,255,0}},
  {{255,128,0}},
  {{255,255,0}},
  {{255,0,0}},
  {{255,0,255}}
 };
 IplImage *gray, *small_img;
 int i, j;
 gray = cvCreateImage( cvSize(img->width,img->height), 8, 1 );
 small_img = cvCreateImage( cvSize( cvRound (img->width/scale),
       cvRound (img->height/scale)), 8, 1 );
 cvCvtColor( img, gray, CV_BGR2GRAY ); // 彩色RGB圖像轉為灰度圖像 
 cvResize( gray, small_img, CV_INTER_LINEAR );
 cvEqualizeHist( small_img, small_img ); // 直方圖均衡化 
 cvClearMemStorage( storage );
 if( cascade )
 {
  double t = (double)cvGetTickCount(); 
  CvSeq* faces = cvHaarDetectObjects( small_img, cascade, storage,
           1.1, 2, 0
           //|CV_HAAR_FIND_BIGGEST_OBJECT
           |CV_HAAR_DO_ROUGH_SEARCH
           //|CV_HAAR_DO_CANNY_PRUNING
           //|CV_HAAR_SCALE_IMAGE
           ,
           cvSize(30, 30) );
  t = (double)cvGetTickCount() - t; // 統計檢測使用時間 
  //printf( "detection time = %gms\n", t/((double)cvGetTickFrequency()*1000.) );
  for( i = 0; i < (faces ? faces->total : 0); i++ )
  {
   CvRect* r = (CvRect*)cvGetSeqElem( faces, i ); // 將faces數據從CvSeq轉為CvRect 
   CvMat small_img_roi;
   CvSeq* nested_objects;
   CvPoint center,recPt1,recPt2;
   CvScalar color = colors[i%8]; // 使用不同顏色繪制各個face,共八種色 
   int radius;
   center.x = cvRound((r->x + r->width*0.5)*scale); // 找出faces中心 
   center.y = cvRound((r->y + r->height*0.5)*scale);
 recPt1.x = cvRound((r->x)*scale);
 recPt1.y = cvRound((r->y)*scale);
 recPt2.x = cvRound((r->x + r->width)*scale);
 recPt2.y = cvRound((r->y + r->height)*scale);
   radius = cvRound((r->width + r->height)*0.25*scale); 
 
 cvGetSubRect( small_img, &small_img_roi, *r );
 
 IplImage *result;
 CvRect roi;
 roi = *r;
 result = cvCreateImage( cvSize(r->width, r->height), img->depth, img->nChannels );
 cvSetImageROI(img,roi);
 // 創建子圖像
 cvCopy(img,result);
 cvResetImageROI(img);
 
 //IplImage *resizeRes;
 CvSize dst_cvsize;
 dst_cvsize.width=(int)(100);
 dst_cvsize.height=(int)(100);
 resizeRes=cvCreateImage(dst_cvsize,result->depth,result->nChannels);
 cvResize(result,resizeRes,CV_INTER_NN);
 faceGray = cvCreateImage(cvGetSize(resizeRes), IPL_DEPTH_8U, 1);//創建目標圖像 
 cvCvtColor(resizeRes,faceGray,CV_BGR2GRAY);//cvCvtColor(src,des,CV_BGR2GRAY)
   cvShowImage( "resize", resizeRes );
 cvRectangle(img,recPt1,recPt2,color,1, 8,0);
 //rectangle(img,recPt1,recPt2,color,1,8,0);
 //cvCircle( img, center, radius, color, 3, 8, 0 ); // 從中心位置畫圓,圈出臉部區域
   if( !nested_cascade )
    continue;
   nested_objects = cvHaarDetectObjects( &small_img_roi, nested_cascade, storage,
          1.1, 2, 0
          //|CV_HAAR_FIND_BIGGEST_OBJECT
          //|CV_HAAR_DO_ROUGH_SEARCH
          //|CV_HAAR_DO_CANNY_PRUNING
          //|CV_HAAR_SCALE_IMAGE
          ,
          cvSize(0, 0) );
   for( j = 0; j < (nested_objects ? nested_objects->total : 0); j++ )
   {
    CvRect* nr = (CvRect*)cvGetSeqElem( nested_objects, j );
    center.x = cvRound((r->x + nr->x + nr->width*0.5)*scale);
    center.y = cvRound((r->y + nr->y + nr->height*0.5)*scale);
    radius = cvRound((nr->width + nr->height)*0.25*scale);
    cvCircle( img, center, radius, color, 3, 8, 0 );
   }
  }
 }
 //cvShowImage( "result", img );
 cvReleaseImage( &gray );
 cvReleaseImage( &small_img );
}
//檢測并識別人臉,并在每幀圖片上寫入結果
void recog_and_draw( IplImage* img )
{
 static CvScalar colors[] = 
 {
  {{0,0,255}},
  {{0,128,255}},
  {{0,255,255}},
  {{0,255,0}},
  {{255,128,0}},
  {{255,255,0}},
  {{255,0,0}},
  {{255,0,255}}
 };
 IplImage *gray, *small_img;
 int i, j;
 gray = cvCreateImage( cvSize(img->width,img->height), 8, 1 );
 small_img = cvCreateImage( cvSize( cvRound (img->width/scale),
       cvRound (img->height/scale)), 8, 1 );
 cvCvtColor( img, gray, CV_BGR2GRAY ); // 彩色RGB圖像轉為灰度圖像 
 cvResize( gray, small_img, CV_INTER_LINEAR );
 cvEqualizeHist( small_img, small_img ); // 直方圖均衡化 
 cvClearMemStorage( storage );
 if( cascade )
 {
  double t = (double)cvGetTickCount(); 
  CvSeq* faces = cvHaarDetectObjects( small_img, cascade, storage,
           1.1, 2, 0
           //|CV_HAAR_FIND_BIGGEST_OBJECT
           //|CV_HAAR_DO_ROUGH_SEARCH
           |CV_HAAR_DO_CANNY_PRUNING
           //|CV_HAAR_SCALE_IMAGE
           ,
           cvSize(30, 30) );
  t = (double)cvGetTickCount() - t; // 統計檢測使用時間 
  //printf( "detection time = %gms\n", t/((double)cvGetTickFrequency()*1000.) );
  for( i = 0; i < (faces ? faces->total : 0); i++ )
  {
   CvRect* r = (CvRect*)cvGetSeqElem( faces, i ); // 將faces數據從CvSeq轉為CvRect 
   CvMat small_img_roi;
   CvSeq* nested_objects;
   CvPoint center,recPt1,recPt2;
   CvScalar color = colors[i%8]; // 使用不同顏色繪制各個face,共八種色 
   int radius;
   center.x = cvRound((r->x + r->width*0.5)*scale); // 找出faces中心 
   center.y = cvRound((r->y + r->height*0.5)*scale);
 recPt1.x = cvRound((r->x)*scale);
 recPt1.y = cvRound((r->y)*scale);
 recPt2.x = cvRound((r->x + r->width)*scale);
 recPt2.y = cvRound((r->y + r->height)*scale);
   radius = cvRound((r->width + r->height)*0.25*scale); 
 
 cvGetSubRect( small_img, &small_img_roi, *r );
 
 IplImage *result;
 CvRect roi;
 roi = *r;
 result = cvCreateImage( cvSize(r->width, r->height), img->depth, img->nChannels );
 cvSetImageROI(img,roi);
 // 創建子圖像
 cvCopy(img,result);
 cvResetImageROI(img);
 
 //IplImage *resizeRes;
 CvSize dst_cvsize;
 dst_cvsize.width=(int)(100);
 dst_cvsize.height=(int)(100);
 resizeRes=cvCreateImage(dst_cvsize,result->depth,result->nChannels);
 cvResize(result,resizeRes,CV_INTER_NN);
 
 faceGray = cvCreateImage(cvGetSize(resizeRes), IPL_DEPTH_8U, 1);//創建目標圖像 
 cvCvtColor(resizeRes,faceGray,CV_BGR2GRAY);//cvCvtColor(src,des,CV_BGR2GRAY)
   cvShowImage( "resize", resizeRes );
 cvRectangle(img,recPt1,recPt2,color,3, 8,0);
 //cvCircle( img, center, radius, color, 3, 8, 0 ); // 從中心位置畫圓,圈出臉部區域
 
 Mat test = faceGray;
 //images[images.size() - 1] = test;
 model->train(images, labels);
 //predictedLabel = model->predict(test);
 double predicted_confidence = 0.0;
 model->predict(test,predictedLabel,predicted_confidence);
 stringstream strStream;
 strStream<<predicted_confidence;
 string ss = strStream.str(); 
 cvText(img, ss.c_str(), r->x+r->width*0.5, r->y); 
 if(predicted_confidence <= dConfidence)
 cvText(img, "Result:YES", 0, 30); 
 else
 cvText(img, "Result:NO", 0, 30); 
 //cout << "predict:"<<model->predict(test) << endl;
 //cout << "predict:"<< predictedLabel << "\nconfidence:" << predicted_confidence << endl;
 
   if( !nested_cascade )
    continue;
   
   nested_objects = cvHaarDetectObjects( &small_img_roi, nested_cascade, storage,
          1.1, 2, 0
          //|CV_HAAR_FIND_BIGGEST_OBJECT
          //|CV_HAAR_DO_ROUGH_SEARCH
          //|CV_HAAR_DO_CANNY_PRUNING
          //|CV_HAAR_SCALE_IMAGE
          ,
          cvSize(0, 0) );
   for( j = 0; j < (nested_objects ? nested_objects->total : 0); j++ )
   {
    CvRect* nr = (CvRect*)cvGetSeqElem( nested_objects, j );
    center.x = cvRound((r->x + nr->x + nr->width*0.5)*scale);
    center.y = cvRound((r->y + nr->y + nr->height*0.5)*scale);
    radius = cvRound((nr->width + nr->height)*0.25*scale);
    cvCircle( img, center, radius, color, 3, 8, 0 );
   }
  }
 }
 //cvShowImage( "result", img );
 cvReleaseImage( &gray );
 cvReleaseImage( &small_img );
}
void cvText(IplImage* img, const char* text, int x, int y) 
{ 
 CvFont font; 
 double hscale = 1.0; 
 double vscale = 1.0; 
 int linewidth = 2; 
 cvInitFont(&font,CV_FONT_HERSHEY_SIMPLEX | CV_FONT_ITALIC,hscale,vscale,0,linewidth); 
 CvScalar textColor =cvScalar(0,255,255); 
 CvPoint textPos =cvPoint(x, y); 
 cvPutText(img, text, textPos, &font,textColor); 
}
 
Mat norm_0_255(cv::InputArray _src)
{
 Mat src = _src.getMat();
 Mat dst;
 
 switch(src.channels())
 {
 case 1:
 cv::normalize(_src, dst, 0, 255, cv::NORM_MINMAX, CV_8UC1);
 break;
 case 3:
 cv::normalize(_src, dst, 0, 255, cv::NORM_MINMAX, CV_8UC3);
 break;
 default:
 src.copyTo(dst);
 break;
 }
 
 return dst;
}
 
void read_csv(const string &filename, vector<Mat> &images, vector<int> &labels, char separator)
{
 std::ifstream file(filename.c_str(), ifstream::in);
 if(!file)
 {
 string error_message = "No valid input file was given.";
 CV_Error(CV_StsBadArg, error_message);
 }
 
 string line, path, classlabel;
 while(getline(file, line))
 {
 stringstream liness(line);
 getline(liness, path, separator); //遇到分號就結束
 getline(liness, classlabel);  //繼續從分號后面開始,遇到換行結束
 if(!path.empty() && !classlabel.empty())
 {
 images.push_back(imread(path, 0));
 labels.push_back(atoi(classlabel.c_str()));
 }
 }
}
//實現了從trainningdata 目錄下直接讀取jpg文件作為訓練集
bool read_img(vector<Mat> &images, vector<int> &labels)
{
 long file; 
 struct _finddata_t find; 
 //AllocConsole();
 string path = "..//einfacedata//trainingdata/";
 char filepath[60];
 //_chdir("..//einfacedata//trainingdata"); 
 if((file=_findfirst("..//einfacedata//trainingdata/*.jpg", &find))==-1L) 
 { 
 AfxMessageBox("Cannot find the dir");
  return false; 
 } 
 int i = 0;
 images.push_back(imread(path+find.name, 0));
 labels.push_back(0); 
 while(_findnext(file, &find)==0) 
 { 
 //_cprintf("%s\n", path+find.name);
 //_cprintf("%d\n", i++);
 images.push_back(imread(path+find.name, 0));
 labels.push_back(0); 
 } 
 _findclose(file);
 return true;
}
//實現了從trainningdata 目錄下讀取jpg文件數目
int read_img_number()
{
 long file; 
 int i = 0;
 struct _finddata_t find; 
 //AllocConsole();
 string path = "..//einfacedata//trainingdata/";
 char filepath[60];
 if((file=_findfirst("..//einfacedata//trainingdata/*.jpg", &find))==-1L) 
  return i;
 i++;
 while(_findnext(file, &find)==0) 
 { 
 i++;
 } 
 _findclose(file);
 return i;
}
bool delete_img()
{
 system( "del ..\\einfacedata\\trainingdata\\" ); 
 return true;
}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

荔波县| 栾城县| 蛟河市| 绵竹市| 萨嘎县| 龙川县| 洛宁县| 克什克腾旗| 友谊县| 长武县| 凌云县| 凤阳县| 桃园市| 石渠县| 建宁县| 遵义市| 鹤庆县| 灵石县| 当涂县| 仁化县| 梓潼县| 理塘县| 普兰县| 哈密市| 南皮县| 吴江市| 霍林郭勒市| 上虞市| 临城县| 靖边县| 甘洛县| 濉溪县| 赞皇县| 陆丰市| 磐石市| 雷山县| 遂川县| 张家川| 吐鲁番市| 常宁市| 瑞安市|