人臉識別和跟蹤程序

/#include "StdAfx.h"
//#include "stdafx.h"
/*-----------------dection and tracing of faces------------------*/
/*--------------------coding by wyz 2017-810---------------------*/
#include "cv.h" 
#include "highgui.h"
#include "windows.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<iostream>
using namespace std;
    


#ifdef _EiC 
#define WIN32 
#endif


static CvMemStorage* storage = 0; 
static CvHaarClassifierCascade* cascade = 0;


void detect_and_draw( IplImage* image );


const char* cascade_name = 
"haarcascade_frontalface_alt.xml"; 
/*    "haarcascade_profileface.xml";*/
HANDLE hCom;  //全局變量,串口句柄
//中心
int CenterPoint=0;
int DivDat;
bool ComOpen=false;
int Angle=0;
int DevCnt=0;
int GetKey;
bool OpenCom()
{

COMMTIMEOUTS TimeOuts;
hCom = CreateFile(TEXT("COM3"),GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);
if(hCom == INVALID_HANDLE_VALUE)
{
//AfxMessageBox("打開COM失敗!");
return FALSE;
}
SetupComm(hCom,1024,1024); //輸入緩衝區和輸出緩衝區的大小都是1024


////設定讀超時
//TimeOuts.ReadIntervalTimeout = 1000;
//TimeOuts.ReadTotalTimeoutMultiplier = 500;
//TimeOuts.ReadTotalTimeoutConstant = 5000;
////設定寫超時
//TimeOuts.WriteTotalTimeoutMultiplier = 500;
//TimeOuts.WriteTotalTimeoutConstant = 2000;
//SetCommTimeouts(hCom, &TimeOuts); //設置超時


DCB dcb;
GetCommState(hCom, &dcb);
dcb.BaudRate = 9600; //波特率爲9600
dcb.ByteSize = 8; //每個字節有8位
dcb.Parity = NOPARITY; //無奇偶校驗位
dcb.StopBits = TWOSTOPBITS; //兩個停止位
SetCommState(hCom, &dcb);


PurgeComm(hCom,PURGE_TXCLEAR|PURGE_RXCLEAR);
printf("Com Open OK...");
return TRUE;


}
void CloseCom()
{
CloseHandle(hCom);
}
void ComSend(unsigned char dir,unsigned char dat) 
{
unsigned char lpOutBuffer[4];
memset(lpOutBuffer,'\0', 4); //前7個字節先清零
if(dat>255)
dat=255;
lpOutBuffer[0] = dir;  //發送緩衝區的第1個字節爲DC1
lpOutBuffer[1] = dat;  //第2個字節爲字符0(30H)
lpOutBuffer[2] = '\r'; //第3個字節爲字符0(30H)
lpOutBuffer[3] = '\n'; // 第4個字節爲字符1(31H)
DWORD dwBytesWrite = 4;
COMSTAT ComStat;
DWORD dwErrorFlags;
BOOL bWriteStat;
ClearCommError(hCom,&dwErrorFlags,&ComStat);
bWriteStat = WriteFile(hCom, lpOutBuffer, dwBytesWrite, &dwBytesWrite, NULL);


PurgeComm(hCom, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);
if (!bWriteStat)
{
printf("Send Fail...\r\n");
return ;
}

}
void StepMotor(int step)
{




if(step>128)
step=128;
else if(step<-128)
step=-128;
step=step/10;
if(ComOpen)
{
Angle = Angle + step;
if(Angle>128)
{
ComSend(0,128);
Angle=0;
printf( "Send  Angle>128\r\n");
return;
}
else if(Angle<-128)
{
ComSend(1,128);
Angle=0;
printf( "Send  Angle<-128\r\n");
return;
}

if(step>0)
{
ComSend(1,step);
}
else
{
ComSend(0,0-step);
}
printf( "Send  DivDat= %d\n",step);
}
}
int main( int argc, char** argv ) 
{ 
// HWND MyWin;
ComOpen=OpenCom();
    cascade_name = "G:\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt2.xml"; 
    cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name, 0, 0, 0 ); 


CvCapture* pCap = cvCreateCameraCapture( 0 );//這裏-1也可以,不過我的電腦裝的有CyberLink YouCam軟件,
//OpenCV會默認調用該攝像頭,而不調用系統的驅動
//IplImage *camframe = NULL;


if (cvCreateCameraCapture == NULL)


{ cout<<"no camera"<<endl;
// system("pause");
return(0);
}


//cvNamedWindow("Camera",CV_WINDOW_FULLSCREEN);


/*while ((camframe = cvQueryFrame(pCap)) != 0 &&  cvWaitKey(20) != 27)  
{
camframe = cvQueryFrame(pCap);


cvShowImage("Camera", camframe); 
}
*/
//cvReleaseCapture(&pCap);  
//cvDestroyWindow("Camera");  





    if( !cascade ) 
    { 
        fprintf( stderr, "ERROR: Could not load classifier cascade\n" ); 
        return -1; 
    } 
    storage = cvCreateMemStorage(0); 
 //   cvNamedWindow( "result", 1 ); 
 //    
 //   const char* filename = "lena.jpg"; 
 //   IplImage* image = cvLoadImage( filename, 1 );


 //   if( image ) 
 //   { 
 //       detect_and_draw( image ); 
 //       cvWaitKey(0); 
 //       cvReleaseImage( &image );   
 //   }


 //   cvDestroyWindow("result"); 
//return 0;
  
//========================================================
    // CvCapture 是一個結構體,用來保存圖像捕獲所需要的信息。
    // opencv提供兩種方式從外部捕獲圖像,一種是從攝像頭中,一種
    // 是通過解碼視頻得到圖像。兩種方式都必須從第一幀開始一幀一幀
    // 的按順序獲取,因此每獲取一幀後都要保存相應的狀態和參數。
    // 比如從視頻文件中獲取,需要保存視頻文件的文件名,相應的******
    // 類型,下一次如果要獲取將需要解碼哪一幀等。 這些信息都保存在
    // CvCapture結構中,每獲取一幀後,這些信息都將被更新,獲取下一幀
    // 需要將新信息傳給獲取的api接口
    //=======================================================
    //CvCapture* capture = 0;
    //===========================================================
    // IplImage 是結構體類型,用來保存一幀圖像的信息,也就是一幀
    // 圖像的所有像素值構成的一個矩陣
    //===========================================================
    IplImage *frame, *frame_copy = 0;
     
     // 創建一個窗口,用“result”作爲窗口的標識符
     cvNamedWindow("Camera", 1 );
     
     // ==========================================
     // 初始化一個視頻捕獲操作。
     // 告訴底層的捕獲api我想從 Capture1.avi中捕獲圖片,
     // 底層api將檢測並選擇相應的******並做好準備工作
     //==============================================
   //capture = cvCaptureFromFile("hello.avi");


frame = cvQueryFrame(pCap);
if(frame != 0)
{
CenterPoint=frame->width/2;
}
else
return 0;
   while ((frame = cvQueryFrame(pCap)) != 0 )  
{
frame = cvQueryFrame(pCap);


detect_and_draw( frame ); 
//cvShowImage("Camera", frame); 
// 如果你敲了鍵盤,就退出程序,否則繼續捕獲下一幀


GetKey = cvWaitKey( 10 );
if( GetKey == 13 )//回車鍵退出
 break;
}
   cvReleaseCapture(&pCap);
    cvDestroyWindow("Camera");
// system("pause");

    return 0;
  //  // 如果 初始化失敗,那麼capture爲空指針,程序停止,
  //  // 否則進入捕獲循環
  //  if( capture )
  //  {
  //      if( cvGrabFrame( capture ))
  //            frame = cvRetrieveFrame( capture );
//// 如果獲取緩存或轉換失敗,則退出循環
//if( frame )
//{
// CenterPoint=frame->width/2;
//}
// 


//// 捕獲循環
//        for(;;)
//        {
//            // 調用cvGrabFrame,讓底層api解碼一幀圖像
//            // 如果解碼失敗,就退出循環
//            // 如果成功,解碼的圖像保存在底層api的緩存中
//            if( !cvGrabFrame( capture ))
//                break;
//            
// // 將解碼得到圖像信息從緩存中轉換成IplImage格式放在frame中
// frame = cvRetrieveFrame( capture );
//
// // 如果獲取緩存或轉換失敗,則退出循環
// if( !frame )
// break;
// detect_and_draw( frame ); 
//
// // 將frame中的圖像信息在窗口result中顯示
// // detect_and_draw( frame ); 
// cvShowImage( "source", frame );
//
// // 暫停一會兒,讓你看一下圖像
// //Sleep(10);
//            
//            // 如果你敲了鍵盤,就退出程序,否則繼續捕獲下一幀
//            if( cvWaitKey( 10 ) >= 0 )
//                break;
//        }
//
//        // 退出程序之前要清理一下堆棧中的內存,免得內存泄露
//        //cvReleaseImage( &frame );注意不需要這句,因爲frame是從視頻中捕獲的,沒有單獨分配內存,無需釋放,當capture 釋放的時候frame自然就釋放了。
//        
//        // 退出之前結束底層api的捕獲操作,免得它們佔着茅坑不拉屎
//        // 比如會使得別的程序無法訪問已經被它們打開的文件
//        cvReleaseCapture( &capture );
//    
//}
//    cvDestroyWindow("source");
// //cvDestroyWindow("result");
//    return 0; 
}




void detect_and_draw(IplImage* img ) 
{ 
    double scale=1.2; 
    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}} 
    };//Just some pretty colors to draw with
DevCnt++;
if(DevCnt>5)
DevCnt=0;


    //Image Preparation 
    // 
    IplImage* gray = cvCreateImage(cvSize(img->width,img->height),8,1); 
    IplImage* small_img=cvCreateImage(cvSize(cvRound(img->width/scale),cvRound(img->height/scale)),8,1); 
    cvCvtColor(img,gray, CV_BGR2GRAY); 
    cvResize(gray, small_img, CV_INTER_LINEAR);


    cvEqualizeHist(small_img,small_img); //直方圖均衡


    //Detect objects if any 
    // 
    cvClearMemStorage(storage); 
    double t = (double)cvGetTickCount(); 
    CvSeq* objects = cvHaarDetectObjects(small_img,cascade,storage,1.1,2,0,cvSize(30,30));


    t = (double)cvGetTickCount() - t; 
    printf( "detection time = %gms\n", t/((double)cvGetTickFrequency()*1000.) );


    //Loop through found objects and draw boxes around them 
    for(int i=0;i<(objects? objects->total:0);++i) 
    { 
        CvRect* r=(CvRect*)cvGetSeqElem(objects,i); 
        cvRectangle(img, cvPoint(r->x*scale,r->y*scale), cvPoint((r->x+r->width)*scale,(r->y+r->height)*scale), colors[i%8]);
//獲取中心點
DivDat=(r->x*scale+r->width*scale/2-CenterPoint)*128/320;
if((i==0))
StepMotor(DivDat);


    } 
    for( int i = 0; i < (objects? objects->total : 0); i++ ) 
    { 
        CvRect* r = (CvRect*)cvGetSeqElem( objects, i ); 
        CvPoint center; 
        int radius; 
        center.x = cvRound((r->x + r->width*0.5)*scale); 
        center.y = cvRound((r->y + r->height*0.5)*scale); 
        radius = cvRound((r->width + r->height)*0.25*scale); 
        cvCircle( img, center, radius, colors[i%8], 3, 8, 0 ); 
    }


    cvShowImage( "Camera", img ); 
    cvReleaseImage(&gray); 
    cvReleaseImage(&small_img); 
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章