1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371 |
- // libfacecapture.cpp : 定义 DLL 应用程序的导出函数。
- //
- #include "libfacecapture.h"
- #include <string.h>
- #ifdef _WIN32
- #include <atlstr.h>
- #include <windows.h>
- #else
- #include <pthread.h>
- #include <semaphore.h>
- #include <errno.h>
- #endif
- #include <math.h>
- #include <time.h>
- #include "cv.h"
- #include "highgui.h"
- #include "libvideoqueue.h"
- #define SLASH '/'
- #define BACK_SLASH '\\'
- #define MB_SLASH_STR "/"
- #define MB_BACK_SLASH_STR "\\"
- #define W_SLASH_STR L"/"
- #define W_BACK_SLASH_STR L"\\"
- #if defined(UNICODE) || defined(_UNICODE)
- #define SLASH_STR W_SLASH_STR
- #define BACK_SLASH_STR W_BACK_SLASH_STR
- #else
- #define SLASH_STR MB_SLASH_STR
- #define BACK_SLASH_STR MB_BACK_SLASH_STR
- #endif
- #ifdef _WIN32
- #define SPLIT_SLASH BACK_SLASH
- #define SPLIT_SLASH_STR BACK_SLASH_STR
- #define MB_SPLIT_SLASH_STR MB_BACK_SLASH_STR
- #define W_SPLIT_SLASH_STR W_BACK_SLASH_STR
- #define LINE_BREAK_STR "\r\n"
- #else
- #define SPLIT_SLASH SLASH
- #define SPLIT_SLASH_STR SLASH_STR
- #define MB_SPLIT_SLASH_STR MB_SLASH_STR
- #define W_SPLIT_SLASH_STR W_SLASH_STR
- #define LINE_BREAK_STR "\n"
- #endif
- #define CASCADE_FACE "haarcascade_frontalface_alt.xml"
- #define CASCADE_EYE "haarcascade_mcs_eyepair_small.xml"
- #define CASCADE_NOSE "haarcascade_mcs_nose.xml"
- #define CASCADE_MOUTH "haarcascade_mcs_mouth.xml"
- #define MAX_FACE_NUM 6 //最多保留6张人脸
- #define RGB_IMG 1 //RGB格式的图像
- //将图像区域分成9宫格,此枚举用来表示人脸所处9宫格的区域
- enum FaceRegionEnum
- {
- FaceError = 0,
- FaceRegionLeftup, //左上角
- FaceRegionUp, //正上方
- FaceRegionRightUP, //右上角
- FaceRegionLeft, //左边
- FaceRegionCenter, //中央
- FaceRegionRight, //右边
- FaceRegionLeftDn, //左下角
- FaceRegionDn, //正下方
- FaceRegionRightDn, //右下角
- };
- //运动跟踪结果
- struct CMotionTrackRslt
- {
- int nObjNum; //当前图像中运动物体的数量
- CvRect ObjRect[MAX_FACE_NUM]; //存放运动物体
- };
- //客户位置
- struct CCustomerRegion
- {
- FaceRegionEnum eRegion; //人脸中心点在图像9宮格中属于哪个宮格
- CvRect stFaceRect; //脸部矩形,使用crect表示人脸在图像中精确位置
- CvRect stUpperBodyRect; //脸部剪辑矩形,使用crect表示人脸剪辑区域
- };
- //客户信息,程序内部逻辑使用
- struct CCustomerInfo
- {
- uint64_t FaceID; //人脸ID号
- CameraEnum eCamera; //1、2号摄像头
- CCustomerRegion stRegion; //客户位置,客户脸部的矩形区域
- SceneEnum eScene; //0不确定,1开始锁定、2失去锁定、3晃动、4向前、5向后
- DistanceEnum eDistance; //0不确定,1操作距离,2近端,3远端
- PoseEnum ePose; //0不确定,1-站立,2-坐立
- CCover stCustomerCover; //覆盖属性
- BrightnessEnum eBrightness; //人脸亮度
- SexEnum eSex; //0不知道,1女,2男
- YoungOldEnum eYoungOld; //0不知道,1小孩,2年轻人,3中年人,4老人
- HeightEnunm eHeight; //0不知道,1矮,2中等,3高
- };
- //计算过程中用于存储人脸的缓存
- struct CAllFaceInfo
- {
- int nTatolFaceNum; //当前图像帧中人脸数量
- CCustomerInfo astFaceInfo[MAX_FACE_NUM]; //所有用户的人脸,astFaceInfo[0]为主用户的人脸
- };
- //图像亮度调整参数
- struct CBrightAdjParam
- {
- double fLow; //映射前低值
- double fHigh; //映射前高值
- double fBottom; //映射后低值
- double fTop; //映射后高值
- double fGamma; //gamma变换值
- };
- //用于本地保存人脸的结构体
- struct CLocalFaceInfo
- {
- CCover stFaceCover; //人脸覆盖
- CCustomerRegion stCustomerRegion; //人脸位置
- IplImage*img; //人脸图像
- };
- enum MonitorStateEnum
- {
- NoBody = 0, //当前没有人
- SomebodyFar, //远距离有人
- SomebodyClose, //有人在靠近
- SomebodyOperate //客户进入操作区域
- };
- class Clibfacecapture_impl
- {
- public:
- Clibfacecapture_impl(bool *pResult, CHostApi *pHostAPI, CVideoMonitorEvent*pHost, const char* EnvironVideoName, const char* OperateVideoName = NULL, MonitorEnum eMonitorType = MotionTarckAndFaceDetect)
- {
- m_pResult = pResult;
- m_pHostApi = pHostAPI;
- m_pHostEvent = pHost;
- m_eType = eMonitorType;
- m_pFaceCascade = NULL; //脸部分类器
- m_pEyeCascade = NULL; //眼睛分类器
- m_pMouthCascade = NULL; //嘴巴分类器
- m_pNoseCascade = NULL; //鼻子分类器
- m_pFaceStorage = NULL;
- pfaceSeq = NULL;
- m_pProcessImg = NULL;
- #ifdef _WIN32
- m_hVieoMonitorThread = NULL;
- m_nVieoMonitorThreadId = 0;
- #else
- m_videomonitorthreadid = 0;
- #endif
- m_bStopVieoMonitor = true;
- m_pEnvironVideoQueue = NULL;
- m_pOperatorVideoQueue = NULL;
- m_nImgWidth = 0;
- m_nImgHeight = 0;
- m_pMhImg = NULL;
- m_pMhBuf = NULL;
- m_bLightChange = false;
- m_nCameraState = 0;
- m_nLastBuf = 0;
- m_eMonitorState = NoBody;
- memset(m_envqueuename, 0, MAX_PATH);
- memset(m_optqueuename, 0, MAX_PATH);
- if (NULL != EnvironVideoName){
- strncpy(m_envqueuename, EnvironVideoName, (strlen(EnvironVideoName) > MAX_PATH) ? (MAX_PATH - 1) : strlen(EnvironVideoName));
- }
- if (NULL != OperateVideoName) {
- strncpy(m_optqueuename, OperateVideoName, (strlen(OperateVideoName) > MAX_PATH) ? (MAX_PATH - 1) : strlen(OperateVideoName));
- }
- #ifdef _WIN32
- InitializeCriticalSection(&CS);
- m_hStopEventWait= ::CreateEventA(NULL, TRUE, 0, 0);
- if (!m_hStopEventWait) {
- *pResult = false;
- pHostAPI->Debug(FACECAP_INFO, "create hEventWait failed!");
- return;
- }
- #else
- pthread_mutex_init(&cs_mutex, NULL);
- sem_init(&m_semt, 0, 0);
- #endif
- memset(&m_stFaceConfig,0,sizeof(CFaceCaptureConfig));
- memset(&m_stFaceRstStorage,0,sizeof(CFaceCaptureConfig));
- //读取配置文件
- *pResult = pHostAPI->LoadConfig(m_stFaceConfig);
- if (!*pResult){
- pHostAPI->Debug(FACECAP_INFO, "Load Configuration failed!");
- return;
- }
- *pResult = InitFaceCapture(m_stFaceConfig.strFaceDataDirPath);
- if (!*pResult){
- return;
- }
- for (int i = 0; i < MAX_FACE_NUM; i++) {
- m_PreFaceRect[i] = cvRect(0, 0, 0, 0);
- }
- memset(&m_stAllFaceInfo, 0, sizeof(CAllFaceInfo));
- //初始化剪辑区域为屏幕中央区域
- m_stAllFaceInfo.astFaceInfo[0].stRegion.stUpperBodyRect = cvRect(160, 60, 320, 240);
- memset(&m_stObjTrackRslt, 0, sizeof(CMotionTrackRslt));
- memset(&m_stBrightAdjParam, 0, sizeof(CBrightAdjParam));
- *pResult = WriteAllFaceInfo(m_stAllFaceInfo);
- if (!*pResult) {
- return;
- }
- }
- bool StartFaceCapture()
- {
- if (!m_bStopVieoMonitor) {
- m_pHostApi->Debug(FACECAP_INFO, "facetracking thread is already start.");
- return true;
- }
- m_pEnvironVideoQueue = new Clibvideoqueue(m_envqueuename);
- if (strlen(m_optqueuename)) {
- m_pOperatorVideoQueue = new Clibvideoqueue(m_optqueuename);
- }
- else {
- m_pOperatorVideoQueue = NULL;
- }
- //开始视频监控线程
- return StartVideoMonitor(m_pHostApi, m_pHostEvent, m_eType);
- }
- bool StopFaceCapture()
- {
- if (m_bStopVieoMonitor) {
- m_pHostApi->Debug(FACECAP_INFO, "facetracking thread is already stop.");
- return true;
- }
- if (true == StopVideoMonitor()){
- m_pHostApi->Debug(FACECAP_DEBUG, "stop video monitor thread success!");
- }
- if (NULL != m_pEnvironVideoQueue){
- delete m_pEnvironVideoQueue;
- m_pEnvironVideoQueue = NULL;
- }
- if (NULL != m_pOperatorVideoQueue){
- delete m_pOperatorVideoQueue;
- m_pOperatorVideoQueue = NULL;
- }
- return true;
- }
- ~Clibfacecapture_impl()
- {
- #ifdef _WIN32
- DeleteCriticalSection(&CS);
- if (!m_hStopEventWait) {
- CloseHandle(m_hStopEventWait);
- m_hStopEventWait = NULL;
- }
- #else
- pthread_mutex_destroy(&cs_mutex);
- #endif
- if (m_pMhImg){
- cvReleaseImage(&m_pMhImg);
- m_pMhImg = NULL;
- }
- if(m_pMhBuf){
- for (int i=0;i<3;i++){
- if (m_pMhBuf[i] != NULL){
- cvReleaseImage(&m_pMhBuf[i]);
- m_pMhBuf[i] = NULL;
- }
- }
- free(m_pMhBuf);
- }
- if (m_pProcessImg){
- cvReleaseImage(&m_pProcessImg);
- m_pProcessImg = NULL;
- }
- if (m_pFaceCascade){
- cvReleaseHaarClassifierCascade(&m_pFaceCascade);
- m_pFaceCascade = NULL;
- }
- if (m_pEyeCascade){
- cvReleaseHaarClassifierCascade(&m_pEyeCascade);
- m_pEyeCascade = NULL;
- }
- if (m_pMouthCascade){
- cvReleaseHaarClassifierCascade(&m_pMouthCascade);
- m_pMouthCascade = NULL;
- }
- if (m_pNoseCascade){
- cvReleaseHaarClassifierCascade(&m_pNoseCascade);
- m_pNoseCascade = NULL;
- }
- }
- public:
- bool m_bLightChange;
- int m_nCameraState; //0:无故障1:env故障,2:opt故障,3:全部故障
- private:
- #ifdef _WIN32
- HANDLE m_hStopEventWait; // CreateEvent
- CRITICAL_SECTION CS;
- #else
- pthread_mutex_t cs_mutex;
- sem_t m_semt;
- #endif
- bool* m_pResult;
- MonitorEnum m_eType;
- CvHaarClassifierCascade* m_pFaceCascade; //脸部分类器
- CvHaarClassifierCascade* m_pEyeCascade; //眼睛分类器
- CvHaarClassifierCascade* m_pMouthCascade; //嘴巴分类器
- CvHaarClassifierCascade* m_pNoseCascade; //鼻子分类器
- CMotionTrackRslt m_stObjTrackRslt; //运动跟踪的结果
- IplImage *m_pMhImg; //MHI: motion history image
- IplImage **m_pMhBuf;
- int m_nLastBuf;
- CFaceCaptureConfig m_stFaceConfig;
- int m_nImgWidth; //当前摄像头图像宽
- int m_nImgHeight; //当前摄像头图像高
- CvSeq* pfaceSeq; //人脸序列
- CvMemStorage* m_pFaceStorage; //人脸内部存储空间
- IplImage* m_pProcessImg; //用于处理的图像
- //存储前一帧的人脸矩形(不包括人脸)
- CvRect m_PreFaceRect[MAX_FACE_NUM];
- #ifdef _WIN32
- HANDLE m_hVieoMonitorThread;
- unsigned int m_nVieoMonitorThreadId;
- #else
- pthread_t m_videomonitorthreadid;
- #endif
-
- bool m_bStopVieoMonitor;
- Clibvideoqueue* m_pEnvironVideoQueue; //环境摄像头小分辨率视频队列
- Clibvideoqueue* m_pOperatorVideoQueue; //操作摄像头视频队列
- CAllFaceInfo m_stAllFaceInfo;
- CAllFaceInfo m_stFaceRstStorage;
- CBrightAdjParam m_stBrightAdjParam; //亮度调节参数
- volatile MonitorStateEnum m_eMonitorState;
- CVideoMonitorEvent* m_pHostEvent;
- CHostApi* m_pHostApi;
- CameraEnum m_eCamera;
- char m_envqueuename[MAX_PATH];
- char m_optqueuename[MAX_PATH];
- //初始化
- bool InitFaceCapture(const char *base_dir)
- {
- char dir[MAX_PATH] = {0};
- FIGetDir(CASCADE_FACE, base_dir, dir);
- m_pFaceCascade=(CvHaarClassifierCascade*)cvLoad(dir,NULL,NULL,NULL);
- if (!m_pFaceCascade){
- m_pHostApi->Debug(FACECAP_INFO, "加载脸部分类器失败!");
- return false;
- }
- FIGetDir(CASCADE_EYE, base_dir, dir);
- m_pEyeCascade=(CvHaarClassifierCascade*)cvLoad(dir,NULL,NULL,NULL);
- if (!m_pEyeCascade){
- m_pHostApi->Debug(FACECAP_INFO, "加载眼睛分类器失败!");
- return false;
- }
- FIGetDir(CASCADE_MOUTH, base_dir, dir);
- m_pMouthCascade=(CvHaarClassifierCascade*)cvLoad(dir,NULL,NULL,NULL);
- if (!m_pMouthCascade){
- m_pHostApi->Debug(FACECAP_INFO, "加载嘴巴分类器失败!");
- return false;
- }
- FIGetDir(CASCADE_NOSE, base_dir, dir);
- m_pNoseCascade=(CvHaarClassifierCascade*)cvLoad(dir,NULL,NULL,NULL);
- if (!m_pMouthCascade){
- m_pHostApi->Debug(FACECAP_INFO, "加载鼻子分类器失败!");
- return false;
- }
- return true;
- }
- //获取分类器路径
- void FIGetDir(const char*CascadeType,const char *base_dir,char*dir)
- {
- strcpy(dir, m_stFaceConfig.strFaceDataDirPath);
- strcat(dir, SPLIT_SLASH_STR);
- strcat(dir,CascadeType);
- }
- //写人脸检测数据
- bool WriteAllFaceInfo(CAllFaceInfo faceInfo)
- {
- #ifdef _WIN32
- EnterCriticalSection(&CS);
- #else
- pthread_mutex_lock(&cs_mutex);
- #endif
- m_stFaceRstStorage = faceInfo;
- #ifdef _WIN32
- LeaveCriticalSection(&CS);
- #else
- pthread_mutex_unlock(&cs_mutex);
- #endif
- return true;
- }
- //计算人脸所处的区域
- FaceRegionEnum CalcFaceRegion(CvRect FaceRect, int nImgWidth, int nImgHeight)
- {
- //计算人脸的中心坐标
- CvPoint FaceCenter;
- FaceCenter.x = FaceRect.x + (int)FaceRect.width/2;
- FaceCenter.y = FaceRect.y + (int)FaceRect.height/2;
- if(FaceCenter.y < (int)nImgHeight/3)
- {
- if(FaceCenter.x < (int)nImgWidth/3)
- {
- return FaceRegionLeftup;
- }
- else if((FaceCenter.x > (int)nImgWidth/3)&&(FaceCenter.x < (int)nImgWidth*2/3))
- {
- return FaceRegionUp;
- }
- else if (FaceCenter.x > (int)nImgWidth*2/3)
- {
- return FaceRegionRightUP;
- }
- }
- else if((FaceCenter.y > (int)nImgHeight/3)&&(FaceCenter.y < (int)nImgHeight*2/3))
- {
- if(FaceCenter.x < (int)nImgWidth/3)
- {
- return FaceRegionLeft;
- }
- else if((FaceCenter.x > (int)nImgWidth/3)&&(FaceCenter.x < (int)nImgWidth*2/3))
- {
- return FaceRegionCenter;
- }
- else if (FaceCenter.x > (int)nImgWidth*2/3)
- {
- return FaceRegionRight;
- }
- }
- else if(FaceCenter.y > (int)nImgHeight*2/3)
- {
- if(FaceCenter.x < (int)nImgWidth/3)
- {
- return FaceRegionLeftDn;
- }
- else if((FaceCenter.x > (int)nImgWidth/3)&&(FaceCenter.x < (int)nImgWidth*2/3))
- {
- return FaceRegionDn;
- }
- else if (FaceCenter.x > (int)nImgWidth*2/3)
- {
- return FaceRegionRightDn;
- }
- }
- return FaceError;
- }
- void SwitchDetectCamera()
- {
- if (NULL != m_pOperatorVideoQueue) {
- (m_eCamera == EnvironCamera) ? (m_eCamera = OperatorCamera) : (m_eCamera = EnvironCamera);
- }
- }
- //计算人脸到机具的距离
- DistanceEnum CalcFaceDistance(CvRect FaceRect)
- {
- if(FaceRect.height>(int)(m_nImgHeight/m_stFaceConfig.fOperateFaceSize))
- {
- return OperateDistance; //可操作距离0.5m
- }
- else if((FaceRect.height<(int)(m_nImgHeight/m_stFaceConfig.fOperateFaceSize))&&(FaceRect.height>(int)(m_nImgHeight/m_stFaceConfig.fCloseFaceSize)))
- {
- return CloseDistance; //近端1.5m
- }
- else
- {
- return FarDistance; //远端2.5m
- }
- }
- //从共享队列获取图像
- bool GetImgFromVideoQueue(Clibvideoqueue* videoqueue)
- {
- if (videoqueue->GetVideoLens() <= 0){
- if (videoqueue == m_pEnvironVideoQueue){
- m_pHostApi->Debug(FACECAP_DEBUG, "环境相机图像队列为空");
- }
- else if (videoqueue == m_pOperatorVideoQueue){
- m_pHostApi->Debug(FACECAP_DEBUG, "操作相机图像队列为空");
- }
- return false;
- }
- int iSize = videoqueue->GetFrameSize(m_nImgWidth, m_nImgHeight);
- if (0 == iSize) {
- return false;
- }
- videoq_frame* videoframe = new videoq_frame;
- if (m_pProcessImg == NULL){
- m_pProcessImg = cvCreateImage(cvSize(m_nImgWidth, m_nImgHeight), 8, 3); //创建图像
- }
- else{
- if((m_pProcessImg->height != m_nImgHeight)||(m_pProcessImg->width != m_nImgWidth)){
- cvReleaseImage(&m_pProcessImg);
- m_pProcessImg = NULL;
- m_pProcessImg = cvCreateImage(cvSize(m_nImgWidth,m_nImgHeight), 8, 3); //创建图像
- }
- }
- videoframe->data = (unsigned char*)m_pProcessImg->imageData;
- bool bGetvideo = videoqueue->GetVideo(videoframe, 0);
- if (!bGetvideo){
- delete videoframe;
- m_pHostApi->Debug(FACECAP_DEBUG, "从队列获取图像失败");
- return false;
- }
- m_nImgWidth = videoframe->width;
- m_nImgHeight = videoframe->height;
- delete videoframe;
-
- return true;
- }
- //从指定摄像头取图像数据
- //成功时返回true,图像保存在m_pProcessImg结构,同时保存m_nImgWidth, m_nImgHeight值
- //失败时返回false
- bool GetSpecifiedCameraImage(CameraEnum eCamera)
- {
- if (eCamera == EnvironCamera){
- if (m_pEnvironVideoQueue == NULL){
- return false;
- }
- bool bRslt = GetImgFromVideoQueue(m_pEnvironVideoQueue);
- if (!bRslt){
- return false;
- }
- }
- else if(eCamera == OperatorCamera){
- if (m_pOperatorVideoQueue == NULL){
- return false;
- }
- bool bRslt = GetImgFromVideoQueue(m_pOperatorVideoQueue);
- if (!bRslt){
- return false;
- }
- }
- return true;
- }
- //清空上次检测结果
- void ClearInspectResult()
- {
- //清除上一次的记录
- m_stAllFaceInfo.nTatolFaceNum = 0;
- m_stAllFaceInfo.astFaceInfo[0].stCustomerCover.bIsClearFace = false;
- m_stAllFaceInfo.astFaceInfo[0].stCustomerCover.bShowEyes = false;
- m_stAllFaceInfo.astFaceInfo[0].stCustomerCover.bShowMouth = false;
- m_stAllFaceInfo.astFaceInfo[0].stCustomerCover.bShowNose = false;
- m_stAllFaceInfo.astFaceInfo[0].eDistance = UncertainDistance;
- m_stAllFaceInfo.astFaceInfo[0].eHeight = UncertainHeight;
- m_stAllFaceInfo.astFaceInfo[0].ePose = UncertainPose;
- m_stAllFaceInfo.astFaceInfo[0].eSex = UncertainSex;
- m_stAllFaceInfo.astFaceInfo[0].eYoungOld = UncertainAge;
- m_stAllFaceInfo.astFaceInfo[0].eCamera = OperatorCamera;
- for (int i = 1; i < MAX_FACE_NUM; i++){
- memset(&m_stAllFaceInfo.astFaceInfo[i], 0, sizeof(CCustomerInfo));
- }
- }
- //在检测到正方形人脸图像中继续查找眼睛,鼻子,嘴巴
- //检测到时返回true
- //未检测到时返回false
- bool FacialFeatureDetect(CvHaarClassifierCascade *pCascade, CvRect *pFaceRect, CvMemStorage* pFaceStorage)
- {
- //搜索区域图像
- CvRect RegionRect;
- if (pCascade == m_pEyeCascade)
- {
- //眼睛
- RegionRect.x = pFaceRect->x;
- RegionRect.y = pFaceRect->y;
- RegionRect.width = pFaceRect->width;
- RegionRect.height = (int)pFaceRect->height*1/2;
- }
- else if (pCascade == m_pNoseCascade)
- {
- //鼻子
- RegionRect.x = (int)pFaceRect->x+(pFaceRect->width)*1/6;
- RegionRect.y = (int)pFaceRect->y+pFaceRect->height*1/6;
- RegionRect.width = (int)pFaceRect->width*2/3;
- RegionRect.height = (int)pFaceRect->height*2/3;
- }
- else if (pCascade == m_pMouthCascade)
- {
- //嘴巴
- RegionRect.x = (int)pFaceRect->x;
- RegionRect.y = (int)pFaceRect->y+pFaceRect->height*1/2;
- RegionRect.width = (int)pFaceRect->width;
- RegionRect.height = (int)pFaceRect->height*1/2;
- }
- CvRect RectTemp = cvRect(0,0,0,0);
- bool bSetRio = false;
- //设置roi
- if(m_pProcessImg->roi){
- RectTemp.x = m_pProcessImg->roi->xOffset;
- RectTemp.y = m_pProcessImg->roi->yOffset;
- RectTemp.width = m_pProcessImg->roi->width;
- RectTemp.height = m_pProcessImg->roi->height;
- RegionRect.x += RectTemp.x;
- RegionRect.y += RectTemp.y;
- bSetRio = true;
- }
- cvResetImageROI(m_pProcessImg);
- cvSetImageROI(m_pProcessImg, RegionRect);
- //脸部特征搜索
- CvSeq* pFacialFeatureSeq = cvHaarDetectObjects(m_pProcessImg, pCascade, pFaceStorage, 1.2, 2, CV_HAAR_DO_CANNY_PRUNING, cvSize(10,10));
- cvResetImageROI(m_pProcessImg);
- if(bSetRio){
- cvSetImageROI(m_pProcessImg,RectTemp);
- }
- if (pFacialFeatureSeq ? pFacialFeatureSeq->total : 0){
- return true;
- }
- else{
- return false;
- }
- }
- //计算两个人脸数据的距离
- int CalcTwoFaceDistance(CvRect *pSrcRect,CvRect *pDstRect)
- {
- CvPoint p1;
- CvPoint p2;
- p1.x = (int)pSrcRect->x+pSrcRect->width/2;
- p1.y = (int)pSrcRect->y+pSrcRect->height/2;
- p2.x = (int)pDstRect->x+pDstRect->width/2;
- p2.y = (int)pDstRect->y+pDstRect->height/2;
- return (int)sqrt((double)(p1.x-p2.x)*(p1.x-p2.x) + (double)(p1.y-p2.y)*(p1.y-p2.y));
- }
- //计算人脸亮度,同时计算人脸亮度调节参数
- BrightnessEnum CalcFaceBrightness(IplImage*img, CvRect* FaceRect)
- {
- cvResetImageROI(img);
- cvSetImageROI(img,*FaceRect);
- IplImage* FaceImgTmp = cvCreateImage(cvSize(FaceRect->width,FaceRect->height),IPL_DEPTH_8U,3);
- cvCopy(img,FaceImgTmp,NULL);
- cvResetImageROI(img);
- IplImage* FaceImg = cvCreateImage(cvSize(FaceRect->width,FaceRect->height),IPL_DEPTH_8U,1);
- cvCvtColor(FaceImgTmp, FaceImg, CV_BGR2GRAY);
- cvReleaseImage(&FaceImgTmp);
- int aver=0;
- unsigned char *data=(uchar*)FaceImg->imageData;
- for(int i=0;i<FaceRect->height;i++)
- {
- for(int j=0;j<FaceRect->width;j++)
- {
- aver+=data[i*FaceImg->widthStep+j];
- }
- }
- aver=aver/FaceRect->width/FaceRect->height;
- cvReleaseImage(&FaceImg);
- if (aver>230)
- {
- m_stBrightAdjParam.fLow = 0.8;
- m_stBrightAdjParam.fHigh = 1.0;
- m_stBrightAdjParam.fBottom = 0.45;
- m_stBrightAdjParam.fTop = 0.75;
- m_stBrightAdjParam.fGamma = 1;
- return VeryHigh;
- }
- else if((aver<230)&&(aver>205))
- {
- m_stBrightAdjParam.fLow = 0.75;
- m_stBrightAdjParam.fHigh = 1.0;
- m_stBrightAdjParam.fBottom = 0.5;
- m_stBrightAdjParam.fTop = 0.8;
- m_stBrightAdjParam.fGamma = 1;
- return Higher;
- }
- else if((aver<205)&&(aver>180))
- {
- m_stBrightAdjParam.fLow = 0.7;
- m_stBrightAdjParam.fHigh = 1.0;
- m_stBrightAdjParam.fBottom = 0.5;
- m_stBrightAdjParam.fTop = 0.8;
- m_stBrightAdjParam.fGamma = 1;
- return NorMal;
- }
- else if((aver<180)&&(aver>70))
- {
- m_stBrightAdjParam.fLow = 0.0;
- m_stBrightAdjParam.fHigh = 0.0;
- m_stBrightAdjParam.fBottom = 0.0;
- m_stBrightAdjParam.fTop = 0.0;
- m_stBrightAdjParam.fGamma = 0.0;
- return NorMal;
- }
- else if((aver<70)&&(aver>50))
- {
- m_stBrightAdjParam.fLow = 0;
- m_stBrightAdjParam.fHigh = 0.3;
- m_stBrightAdjParam.fBottom = 0.15;
- m_stBrightAdjParam.fTop = 0.55;
- m_stBrightAdjParam.fGamma = 1;
- return NorMal;
- }
- else if((aver<50)&&(aver>30))
- {
- m_stBrightAdjParam.fLow = 0;
- m_stBrightAdjParam.fHigh = 0.25;
- m_stBrightAdjParam.fBottom = 0.25;
- m_stBrightAdjParam.fTop = 0.65;
- m_stBrightAdjParam.fGamma = 1;
- return Lower;
- }
- else
- {
- m_stBrightAdjParam.fLow = 0;
- m_stBrightAdjParam.fHigh = 0.2;
- m_stBrightAdjParam.fBottom = 0.25;
- m_stBrightAdjParam.fTop = 0.65;
- m_stBrightAdjParam.fGamma = 1;
- return VeryLow;
- }
- }
- //计算人脸亮度调节参数
- bool CalcBrightAdjParam(IplImage*img, CvRect* FaceRect)
- {
- cvResetImageROI(img);
- cvSetImageROI(img,*FaceRect);
- IplImage* FaceImgTmp = cvCreateImage(cvSize(FaceRect->width,FaceRect->height),IPL_DEPTH_8U,3);
- cvCopy(img,FaceImgTmp,NULL);
- cvResetImageROI(img);
- IplImage* FaceImg = cvCreateImage(cvSize(FaceRect->width,FaceRect->height),IPL_DEPTH_8U,1);
- cvCvtColor(FaceImgTmp, FaceImg, CV_BGR2GRAY);
- cvReleaseImage(&FaceImgTmp);
- int aver=0;
- unsigned char *data=(uchar*)FaceImg->imageData;
- for(int i=0;i<FaceRect->height;i++)
- {
- for(int j=0;j<FaceRect->width;j++)
- {
- aver+=data[i*FaceImg->widthStep+j];
- }
- }
- aver=aver/FaceRect->width/FaceRect->height;
- if (aver>230)
- {
- m_stBrightAdjParam.fLow = 0.8;
- m_stBrightAdjParam.fHigh = 1.0;
- m_stBrightAdjParam.fBottom = 0.45;
- m_stBrightAdjParam.fTop = 0.75;
- m_stBrightAdjParam.fGamma = 1;
- }
- else if((aver<230)&&(aver>205))
- {
- m_stBrightAdjParam.fLow = 0.75;
- m_stBrightAdjParam.fHigh = 1.0;
- m_stBrightAdjParam.fBottom = 0.5;
- m_stBrightAdjParam.fTop = 0.8;
- m_stBrightAdjParam.fGamma = 1;
- }
- else if((aver<205)&&(aver>180))
- {
- m_stBrightAdjParam.fLow = 0.7;
- m_stBrightAdjParam.fHigh = 1.0;
- m_stBrightAdjParam.fBottom = 0.5;
- m_stBrightAdjParam.fTop = 0.8;
- m_stBrightAdjParam.fGamma = 1;
- }
- else if((aver<70)&&(aver>60))
- {
- m_stBrightAdjParam.fLow = 0;
- m_stBrightAdjParam.fHigh = 0.3;
- m_stBrightAdjParam.fBottom = 0.15;
- m_stBrightAdjParam.fTop = 0.55;
- m_stBrightAdjParam.fGamma = 1;
- }
- else if((aver<60)&&(aver>30))
- {
- m_stBrightAdjParam.fLow = 0;
- m_stBrightAdjParam.fHigh = 0.25;
- m_stBrightAdjParam.fBottom = 0.25;
- m_stBrightAdjParam.fTop = 0.65;
- m_stBrightAdjParam.fGamma = 1;
- }
- else
- {
- m_stBrightAdjParam.fLow = 0;
- m_stBrightAdjParam.fHigh = 0.2;
- m_stBrightAdjParam.fBottom = 0.25;
- m_stBrightAdjParam.fTop = 0.65;
- m_stBrightAdjParam.fGamma = 1;
- }
- cvReleaseImage(&FaceImg);
- return true;
- }
- //人脸检测,获取指定摄像头的图像进行全局检测,比较当前人脸和主人脸信息,将更居中人脸信息保存为主人脸。
- //检测到有人时,返回ture
- //没检测到有人时,返回false
- bool FaceDetectWithSpecifiedCamera(CameraEnum eCamera)
- {
- if (!GetSpecifiedCameraImage(eCamera)){
- m_pHostApi->Debug(FACECAP_DEBUG, "获取图像失败");
- return false;
- }
- CCustomerInfo UserFaceTemp;
- int nFaceSerial = 1;
- memset(&UserFaceTemp, 0, sizeof(CCustomerInfo));
- CvRect* pFaceRect = NULL; //人脸矩形
- int nPreFaceNum = 0;
- cvResetImageROI(m_pProcessImg);
- //内存初始化
- if (m_pFaceStorage){
- m_pFaceStorage = cvCreateMemStorage(0);
- cvClearMemStorage(m_pFaceStorage);
- }
- else{
- m_pFaceStorage = cvCreateMemStorage(0);
- }
- //人脸搜索
- if (m_pFaceCascade == NULL){
- ClearInspectResult();
- return false;
- }
- int isize = (int)(m_nImgHeight/m_stFaceConfig.fDetectFaceSize);
- pfaceSeq = cvHaarDetectObjects(m_pProcessImg, m_pFaceCascade, m_pFaceStorage, 1.1, 3, CV_HAAR_DO_CANNY_PRUNING, cvSize(isize, isize));
- if (!pfaceSeq || !pfaceSeq->total){
- cvReleaseMemStorage(&pfaceSeq->storage);
- pfaceSeq = NULL;
- ClearInspectResult();
- return false;
- }
- else
- {
- //保存上次人脸矩形,对当前人脸位置进行微调防止跳动
- nPreFaceNum = m_stAllFaceInfo.nTatolFaceNum;
- for(int num = 0; num < m_stAllFaceInfo.nTatolFaceNum; num++){
- m_PreFaceRect[num] = m_stAllFaceInfo.astFaceInfo[num].stRegion.stFaceRect;
- }
- //清除上一次的记录
- ClearInspectResult();
- }
- for(int i = 0; i < (pfaceSeq ? pfaceSeq->total : 0)&&(i < MAX_FACE_NUM); i++)
- {
- m_stAllFaceInfo.nTatolFaceNum++;
- //获取脸部矩形
- pFaceRect = (CvRect*)cvGetSeqElem(pfaceSeq, i);
- //如果是前端检测则需要特征检测,如果是坐席则不需检测
- if (m_stFaceConfig.nServersType == 0)
- {
- //找眼睛
- m_stAllFaceInfo.astFaceInfo[nFaceSerial].stCustomerCover.bShowEyes = FacialFeatureDetect(m_pEyeCascade, pFaceRect, m_pFaceStorage);
- //找鼻子
- m_stAllFaceInfo.astFaceInfo[nFaceSerial].stCustomerCover.bShowNose = FacialFeatureDetect(m_pNoseCascade, pFaceRect, m_pFaceStorage);
- //找嘴巴
- m_stAllFaceInfo.astFaceInfo[nFaceSerial].stCustomerCover.bShowMouth = FacialFeatureDetect(m_pMouthCascade, pFaceRect, m_pFaceStorage);
- }
- else
- {
- //找眼睛
- m_stAllFaceInfo.astFaceInfo[nFaceSerial].stCustomerCover.bShowEyes = false;
- //找鼻子
- m_stAllFaceInfo.astFaceInfo[nFaceSerial].stCustomerCover.bShowNose = false;
- //找嘴巴
- m_stAllFaceInfo.astFaceInfo[nFaceSerial].stCustomerCover.bShowMouth = false;
- }
- if(!(m_stAllFaceInfo.astFaceInfo[nFaceSerial].stCustomerCover.bShowEyes||
- m_stAllFaceInfo.astFaceInfo[nFaceSerial].stCustomerCover.bShowNose||
- m_stAllFaceInfo.astFaceInfo[nFaceSerial].stCustomerCover.bShowMouth))
- {
- m_stAllFaceInfo.astFaceInfo[nFaceSerial].stCustomerCover.bIsClearFace = false;
- }
- else
- {
- m_stAllFaceInfo.astFaceInfo[nFaceSerial].stCustomerCover.bIsClearFace = true;
- }
- //计算当前人脸位置,如果当前人脸位置与上次人脸位置小于偏移量则取上次人脸位置,防止人脸图像跳变
- for (int num = 0; num < nPreFaceNum; num++)
- {
- if ((abs(pFaceRect->x - m_PreFaceRect[num].x) < m_stFaceConfig.nFaceSizeOffset)
- && (abs(pFaceRect->y - m_PreFaceRect[num].y) < m_stFaceConfig.nFaceSizeOffset)
- && (abs(pFaceRect->width - m_PreFaceRect[num].width) < (m_stFaceConfig.nFaceSizeOffset*2))
- && (abs(pFaceRect->height - m_PreFaceRect[num].height) < (m_stFaceConfig.nFaceSizeOffset*2)))
- {
- pFaceRect->x = m_PreFaceRect[num].x;
- pFaceRect->y = m_PreFaceRect[num].y;
- pFaceRect->width = m_PreFaceRect[num].width;
- pFaceRect->height = m_PreFaceRect[num].height;
- }
- }
-
- //搜索到人脸,计算人脸数据
- m_stAllFaceInfo.astFaceInfo[nFaceSerial].stRegion.stFaceRect = *pFaceRect;
- m_stAllFaceInfo.astFaceInfo[nFaceSerial].stRegion.eRegion = CalcFaceRegion(*pFaceRect,m_nImgWidth,m_nImgHeight);
- m_stAllFaceInfo.astFaceInfo[nFaceSerial].eDistance = CalcFaceDistance(*pFaceRect);
- m_stAllFaceInfo.astFaceInfo[nFaceSerial].eCamera = eCamera;
-
- //获取UUID
- if (m_stAllFaceInfo.astFaceInfo[nFaceSerial].FaceID == 0)
- {
- m_stAllFaceInfo.astFaceInfo[nFaceSerial].FaceID = m_pHostApi->GenerateUUID();
- }
- //截取人脸图像,放大截取区域,截取半身头像
- CalcUpbodyRegion(pFaceRect);
- m_stAllFaceInfo.astFaceInfo[nFaceSerial].stRegion.stUpperBodyRect = *pFaceRect;
-
- //当前数据的区域和距离,temp数据的区域和距离
- FaceRegionEnum CurRegion = m_stAllFaceInfo.astFaceInfo[nFaceSerial].stRegion.eRegion;
- DistanceEnum CurDistance = m_stAllFaceInfo.astFaceInfo[nFaceSerial].eDistance;
- FaceRegionEnum TempRegion = UserFaceTemp.stRegion.eRegion;
- DistanceEnum TempDistance = UserFaceTemp.eDistance;
- int TempPointDistance = CalcTwoFaceDistance(&UserFaceTemp.stRegion.stFaceRect, &m_stAllFaceInfo.astFaceInfo[0].stRegion.stFaceRect);
- int CurPointDistance = CalcTwoFaceDistance(&m_stAllFaceInfo.astFaceInfo[nFaceSerial].stRegion.stFaceRect, &m_stAllFaceInfo.astFaceInfo[0].stRegion.stFaceRect);
- //计算当前操作者的人脸区域
- if(//如果temp数据为0,则更新temp
- ((TempRegion == FaceError)&&(TempDistance == UncertainDistance)) ||
- //如果当前数据在中心区域,temp数据也在中心区域,且当前距离比temp数据更近,则更新temp
- ((CurRegion == FaceRegionCenter)&&(TempRegion == FaceRegionCenter)&&(CurDistance < TempDistance))||
- //如果当前数据不在中心区域,temp数据也不在中心区域,且当前数据比temp数据更近。则更新temp
- ((TempRegion != FaceRegionCenter)&&(CurRegion != FaceRegionCenter)&&(CurDistance < TempDistance))||
- //如果当前数据在中心区域,temp数据不在中心区域,且当前距离更近,则更新temp
- ((CurRegion == FaceRegionCenter)&&(TempRegion != FaceRegionCenter)&&(CurDistance < TempDistance))||
- //如果当前数据不在中心区域,temp数据在中心区域,且当前数据距离更近,则更新temp
- ((CurRegion != FaceRegionCenter)&&(TempRegion == FaceRegionCenter)&&(CurDistance < TempDistance))||
- //如果当前数据不在中心区域,temp数据也不在中心区域,且距离一样,若当前数据更靠近历史数据,则当前数据作为temp
- ((TempRegion != FaceRegionCenter)&&(CurRegion != FaceRegionCenter)&&(CurDistance == TempDistance)&&(CurPointDistance < TempPointDistance)))
- {
- if((TempRegion != FaceError)&&(TempDistance != UncertainDistance))
- {
- CCustomerInfo Temp = UserFaceTemp;
- UserFaceTemp = m_stAllFaceInfo.astFaceInfo[nFaceSerial];
- m_stAllFaceInfo.astFaceInfo[nFaceSerial] = Temp;
- nFaceSerial++;
- }
- else
- {
- UserFaceTemp = m_stAllFaceInfo.astFaceInfo[nFaceSerial];
- memset(&m_stAllFaceInfo.astFaceInfo[nFaceSerial],0,sizeof(CCustomerInfo));
- }
- }
- else
- {
- nFaceSerial++;
- }
- }
- if((UserFaceTemp.stRegion.eRegion != FaceError)&&(UserFaceTemp.eDistance != UncertainDistance))
- {
- m_stAllFaceInfo.astFaceInfo[0].stRegion.stFaceRect = UserFaceTemp.stRegion.stFaceRect;
- m_stAllFaceInfo.astFaceInfo[0].eDistance = UserFaceTemp.eDistance;
- m_stAllFaceInfo.astFaceInfo[0].stRegion.eRegion = UserFaceTemp.stRegion.eRegion;
- m_stAllFaceInfo.astFaceInfo[0].stRegion.stUpperBodyRect = UserFaceTemp.stRegion.stUpperBodyRect;
- m_stAllFaceInfo.astFaceInfo[0].eCamera = UserFaceTemp.eCamera;
- m_stAllFaceInfo.astFaceInfo[0].stCustomerCover = UserFaceTemp.stCustomerCover;
- //计算人脸亮度
- //if (m_stFaceConfig.nServersType == 0)
- //{
- // m_stAllFaceInfo.astFaceInfo[0].eBrightness = CalcFaceBrightness(m_pProcessImg,&m_stAllFaceInfo.astFaceInfo[0].stRegion.stFaceRect);
- //}
- }
- //清空存储区
- cvResetImageROI(m_pProcessImg);
- if (pfaceSeq != NULL){
- cvReleaseMemStorage(&pfaceSeq->storage);
- pfaceSeq = NULL;
- }
- for(int i = 0; i < MAX_FACE_NUM; i++){
- m_PreFaceRect[i] = cvRect(0,0,0,0);
- }
- if(m_stAllFaceInfo.nTatolFaceNum == 0){
- ClearInspectResult();
- return false;
- }
- else{
- return true;
- }
- }
- bool bIsRectValid(int iWidth, int iHeight, CvRect rect)
- {
- bool bRet = false;
- if ((0 != rect.width) && (0 != rect.height) && (iWidth >= rect.x + rect.width) && (iHeight >= rect.y + rect.height)) {
- bRet = true;
- }
- return bRet;
- }
- //人脸检测,对指定摄像头的指定区域进行全局检测,比较当前人脸和主人脸信息,将更居中人脸信息保存为主人脸。
- //检测到有人时,返回ture
- //没检测到有人时,返回false
- bool FaceDetectWithSpecifiedCameraRegion(CameraEnum eCamera, CvRect rect)
- {
- if (!GetSpecifiedCameraImage(eCamera)){
- return false;
- }
- CvMemStorage* pFaceStorage = NULL;
- if (eCamera == EnvironCamera){
- pFaceStorage = m_pFaceStorage;
- }
- else{
- pFaceStorage = m_pFaceStorage;
- }
- CCustomerInfo UserFaceTemp;
- CCustomerInfo astFaceTemp;
- memset(&astFaceTemp,0,sizeof(CCustomerInfo));
- memset(&UserFaceTemp,0,sizeof(CCustomerInfo));
- CvRect* pFaceRect = NULL; //人脸矩形
- cvResetImageROI(m_pProcessImg);
- if (bIsRectValid(m_pProcessImg->width, m_pProcessImg->height, rect)) {
- cvSetImageROI(m_pProcessImg, rect);
- }
- //内存初始化
- if (pFaceStorage){
- pFaceStorage = cvCreateMemStorage(0);
- cvClearMemStorage(pFaceStorage);
- }
- else{
- pFaceStorage = cvCreateMemStorage(0);
- }
- //人脸搜索
- if (m_pFaceCascade == NULL){
- return false;
- }
- int size = (int)m_nImgHeight/m_stFaceConfig.fDetectFaceSize;
- pfaceSeq = cvHaarDetectObjects(m_pProcessImg, m_pFaceCascade, pFaceStorage, 1.2, 3, CV_HAAR_DO_CANNY_PRUNING, cvSize(size,size));
- if (!pfaceSeq || !pfaceSeq->total)
- {
- cvReleaseMemStorage(&pfaceSeq->storage);
- pfaceSeq = NULL;
- return false;
- }
- for(int i = 0; i < (pfaceSeq?pfaceSeq->total:0)&&(i<MAX_FACE_NUM); i++)
- {
- //获取脸部矩形
- pFaceRect = (CvRect*)cvGetSeqElem(pfaceSeq, i);
- //如果是前端检测则需要特征检测,如果是坐席则不需检测
- if (m_stFaceConfig.nServersType == 0)
- {
- //找眼睛
- astFaceTemp.stCustomerCover.bShowEyes = FacialFeatureDetect(m_pEyeCascade, pFaceRect, pFaceStorage);
- //找鼻子
- astFaceTemp.stCustomerCover.bShowNose = FacialFeatureDetect(m_pNoseCascade, pFaceRect, pFaceStorage);
- //找嘴巴
- astFaceTemp.stCustomerCover.bShowMouth = FacialFeatureDetect(m_pMouthCascade, pFaceRect, pFaceStorage);
- }
- else
- {
- //找眼睛
- astFaceTemp.stCustomerCover.bShowEyes = false;
- //找鼻子
- astFaceTemp.stCustomerCover.bShowNose = false;
- //找嘴巴
- astFaceTemp.stCustomerCover.bShowMouth = false;
- }
- if(!(astFaceTemp.stCustomerCover.bShowEyes||astFaceTemp.stCustomerCover.bShowNose||astFaceTemp.stCustomerCover.bShowMouth))
- {
- astFaceTemp.stCustomerCover.bIsClearFace = false;
- }
- else
- {
- astFaceTemp.stCustomerCover.bIsClearFace = true;
- }
- //计算当前人脸位置如果当前人脸位置与上次人脸位置小于偏移量则取上次人脸位置,防止人脸图像跳变
- //坐标变换
- pFaceRect->x = pFaceRect->x+rect.x;
- pFaceRect->y = pFaceRect->y+rect.y;
- if ((abs(pFaceRect->x - m_stAllFaceInfo.astFaceInfo[0].stRegion.stFaceRect.x) < m_stFaceConfig.nFaceSizeOffset)
- &&(abs(pFaceRect->y-m_stAllFaceInfo.astFaceInfo[0].stRegion.stFaceRect.y) < m_stFaceConfig.nFaceSizeOffset)
- &&(abs(pFaceRect->width-m_stAllFaceInfo.astFaceInfo[0].stRegion.stFaceRect.width) < (m_stFaceConfig.nFaceSizeOffset*2))
- &&(abs(pFaceRect->height-m_stAllFaceInfo.astFaceInfo[0].stRegion.stFaceRect.height) < (m_stFaceConfig.nFaceSizeOffset*2)))
- {
- pFaceRect->x = m_stAllFaceInfo.astFaceInfo[0].stRegion.stFaceRect.x;
- pFaceRect->y = m_stAllFaceInfo.astFaceInfo[0].stRegion.stFaceRect.y;
- pFaceRect->width = m_stAllFaceInfo.astFaceInfo[0].stRegion.stFaceRect.width;
- pFaceRect->height = m_stAllFaceInfo.astFaceInfo[0].stRegion.stFaceRect.height;
- }
-
- //搜索到人脸,计算人脸数据
- astFaceTemp.stRegion.stFaceRect = *pFaceRect;
- astFaceTemp.stRegion.eRegion = CalcFaceRegion(*pFaceRect,m_nImgWidth,m_nImgHeight);
- astFaceTemp.eDistance = CalcFaceDistance(*pFaceRect);
- astFaceTemp.eCamera = eCamera;
- //截取人脸图像,放大截取区域,截取半身头像
- CalcUpbodyRegion(pFaceRect);
- astFaceTemp.stRegion.stUpperBodyRect = *pFaceRect;
- //当前数据的区域和距离,temp数据的区域和距离
- FaceRegionEnum CurRegion = astFaceTemp.stRegion.eRegion;
- DistanceEnum CurDistance = astFaceTemp.eDistance;
- FaceRegionEnum TempRegion = UserFaceTemp.stRegion.eRegion;
- DistanceEnum TempDistance = UserFaceTemp.eDistance;
- int TempPointDistance = CalcTwoFaceDistance(&UserFaceTemp.stRegion.stFaceRect, &m_stAllFaceInfo.astFaceInfo[0].stRegion.stFaceRect);
- int CurPointDistance = CalcTwoFaceDistance(&astFaceTemp.stRegion.stFaceRect, &m_stAllFaceInfo.astFaceInfo[0].stRegion.stFaceRect);
- //计算当前操作者的人脸区域
- if(//如果temp数据为0,则更新temp
- ((TempRegion == FaceError)&&(TempDistance == UncertainDistance)) ||
- //如果当前数据在中心区域,temp数据也在中心区域,且当前距离比temp数据更近,则更新temp
- ((CurRegion == FaceRegionCenter)&&(TempRegion == FaceRegionCenter)&&(CurDistance < TempDistance))||
- //如果当前数据不在中心区域,temp数据也不在中心区域,且当前数据比temp数据更近。则更新temp
- ((TempRegion != FaceRegionCenter)&&(CurRegion != FaceRegionCenter)&&(CurDistance < TempDistance))||
- //如果当前数据在中心区域,temp数据不在中心区域,且当前距离更近,则更新temp
- ((CurRegion == FaceRegionCenter)&&(TempRegion != FaceRegionCenter)&&(CurDistance < TempDistance))||
- //如果当前数据不在中心区域,temp数据在中心区域,且当前数据距离更近,则更新temp
- ((CurRegion != FaceRegionCenter)&&(TempRegion == FaceRegionCenter)&&(CurDistance < TempDistance))||
- //如果当前数据不在中心区域,temp数据也不在中心区域,且距离一样,若当前数据更靠近历史数据,则当前数据作为temp
- ((TempRegion != FaceRegionCenter)&&(CurRegion != FaceRegionCenter)&&(CurDistance == TempDistance)&&(CurPointDistance < TempPointDistance)))
- {
- UserFaceTemp = astFaceTemp;
- memset(&astFaceTemp, 0, sizeof(CCustomerInfo));
- }
- }
- if((UserFaceTemp.stRegion.eRegion != FaceError)&&(UserFaceTemp.eDistance != UncertainDistance))
- {
- m_stAllFaceInfo.astFaceInfo[0].stRegion.stFaceRect = UserFaceTemp.stRegion.stFaceRect;
- m_stAllFaceInfo.astFaceInfo[0].eDistance = UserFaceTemp.eDistance;
- m_stAllFaceInfo.astFaceInfo[0].stRegion.eRegion = UserFaceTemp.stRegion.eRegion;
- m_stAllFaceInfo.astFaceInfo[0].stRegion.stUpperBodyRect = UserFaceTemp.stRegion.stUpperBodyRect;
- m_stAllFaceInfo.astFaceInfo[0].eCamera = UserFaceTemp.eCamera;
- m_stAllFaceInfo.astFaceInfo[0].stCustomerCover = UserFaceTemp.stCustomerCover;
- //计算人脸亮度
- //if (m_stFaceConfig.nServersType == 0){
- // m_stAllFaceInfo.astFaceInfo[0].eBrightness = CalcFaceBrightness(m_pProcessImg,&m_stAllFaceInfo.astFaceInfo[0].stRegion.stFaceRect);
- //}
- }
-
- //清空存储区
- if (pfaceSeq != NULL){
- cvReleaseMemStorage(&pfaceSeq->storage);
- pfaceSeq = NULL;
- }
- cvResetImageROI(m_pProcessImg);
- return true;
- }
- //调整图像亮度
- bool AdjustImgBrightness(char* src,int width,int height,CBrightAdjParam stAdjParam,int ImgColorType = RGB_IMG)
- {
- if(stAdjParam.fLow<0&&stAdjParam.fLow>1&&stAdjParam.fHigh<0&&stAdjParam.fHigh>1
- &&stAdjParam.fBottom<0&&stAdjParam.fBottom>1&&stAdjParam.fTop<0&&stAdjParam.fTop>1&& stAdjParam.fLow>stAdjParam.fHigh)
- return false;
- if (((stAdjParam.fHigh-0.0)<0.001)&&((stAdjParam.fTop-0.0)<0.001))
- return false;
- double low2 = stAdjParam.fLow*255;
- double high2 = stAdjParam.fHigh*255;
- double bottom2 = stAdjParam.fBottom*255;
- double top2 = stAdjParam.fTop*255;
- double err_in = high2 - low2;
- double err_out = top2 - bottom2;
- int x,y;
- double val;
- int nChannels = 0;
- if (ImgColorType = RGB_IMG)
- {
- nChannels = 3;
- }
- else
- {
- nChannels = 1;
- }
- // intensity transform
- for( y = 0; y < height; y++)
- {
- for (x = 0; x < width*3; x++)
- {
- val = ((uchar*)(src + width*nChannels*y))[x];
- val = pow((val - low2)/err_in, stAdjParam.fGamma) * err_out + bottom2;
- if(val>255)
- val=255;
- if(val<0)
- val=0; // Make sure src is in the range [low,high]
- ((uchar*)(src + width*nChannels*y))[x] = (uchar) val;
- }
- }
- return true;
- }
- //形态学结构元素的映射
- IplConvKernel* IpStructuringElementMap(IplConvKernel* se)
- {
- CvMat *mat = cvCreateMat( se->nRows, se->nCols, CV_32SC1);
- memcpy(mat->data.i, se->values, sizeof(int) * se->nRows * se->nCols );
- cvFlip(mat, NULL, -1);
- IplConvKernel* semap = cvCreateStructuringElementEx( se->nCols, se->nRows,
- se->nCols-se->anchorX-1, se->nRows-se->anchorY-1, 0, NULL );
- semap->nShiftR = se->nShiftR;
- memcpy( semap->values, mat->data.i, sizeof(int) * se->nRows * se->nCols );
- cvReleaseMat(&mat);
- return semap;
- }
- //形态学闭运算
- void IpMorpClose(const IplImage*src,IplImage* dst,IplConvKernel* se=NULL, int iterations=1)
- {
- cvDilate(src,dst,se,iterations );
- IplConvKernel* semap = IpStructuringElementMap(se);
- cvErode(src,dst,semap,iterations );
- cvReleaseStructuringElement(&semap);
- }
- //计算半身头像区域,按4:3比例剪辑,防止超出图像界限
- void CalcUpbodyRegion(CvRect* pFaceRect)
- {
- if (m_nImgWidth > m_nImgHeight)
- {
- pFaceRect->y = ((pFaceRect->y-pFaceRect->height*1/3)<0)?0:(int)(pFaceRect->y-pFaceRect->height*1/3);
- pFaceRect->height = ((pFaceRect->height*19/12+pFaceRect->y)>m_nImgHeight)?(int)(m_nImgHeight-pFaceRect->y):(int)(pFaceRect->height*19/12);
- if ((int)(pFaceRect->x+pFaceRect->width/2-pFaceRect->height*4/6)<0)
- {
- pFaceRect->x = 0;
- }
- else if ((pFaceRect->x+pFaceRect->width/2+pFaceRect->height*4/6)>m_nImgWidth)
- {
- pFaceRect->x = (int)(m_nImgWidth-pFaceRect->height*4/3);
- }
- else
- {
- pFaceRect->x=(int)(pFaceRect->x+pFaceRect->width/2-pFaceRect->height*4/6);
- }
- pFaceRect->width = pFaceRect->height*4/3;
- }
- else
- {
- pFaceRect->x = ((pFaceRect->x-pFaceRect->width*7/24)<0)?0:(int)(pFaceRect->x-pFaceRect->width*7/24);
- pFaceRect->width = ((pFaceRect->width*19/12+pFaceRect->x)>m_nImgWidth)?(int)(m_nImgWidth-pFaceRect->x):(int)(pFaceRect->width*19/12);
- if ((int)(pFaceRect->y+pFaceRect->height/2-pFaceRect->width*3/8)<0)
- {
- pFaceRect->y = 0;
- }
- else if ((pFaceRect->y+pFaceRect->height/2+pFaceRect->width*3/8)>m_nImgHeight)
- {
- pFaceRect->y = (int)(m_nImgHeight-pFaceRect->width*3/8);
- }
- else
- {
- pFaceRect->y = (int)(pFaceRect->y+pFaceRect->height/2-pFaceRect->width*3/8);
- }
- pFaceRect->height = pFaceRect->width*3/4;
- }
- }
- //按指定尺寸对图像进行全局搜索
- //检测到有人时,返回ture,更新人脸状态,同时发送人脸状态信息,保存检测到的人脸数,最靠近机器那人的人脸位置和大小信息,当前摄像头信息,用于其他分类器做进一步检测
- //没检测到有人时,返回false
- bool FaceSearchWithSpecifiedSize(uint32_t nFaceLimit)
- {
- int nFaceNum = 0;
- int nCurafaceSerial = 0;
- //人脸搜索
- if (NULL == m_pFaceCascade){
- return false;
- }
- cvResetImageROI(m_pProcessImg);
- CvRect* pFaceRect = NULL; //人脸矩形
- //内存初始化
- if (m_pFaceStorage){
- m_pFaceStorage = cvCreateMemStorage(0);
- cvClearMemStorage(m_pFaceStorage);
- }
- else{
- m_pFaceStorage = cvCreateMemStorage(0);
- }
- pfaceSeq = cvHaarDetectObjects(m_pProcessImg, m_pFaceCascade, m_pFaceStorage, 1.2, 3, CV_HAAR_DO_CANNY_PRUNING, cvSize(nFaceLimit, nFaceLimit));
- if (pfaceSeq && pfaceSeq->total)
- {
- for(int i = 0; i < (pfaceSeq?pfaceSeq->total:0); i++)
- {
- nFaceNum++;
- //获取脸部矩形
- CvRect* pFaceRect = (CvRect*)cvGetSeqElem(pfaceSeq, i);
- //如果发现有人脸到达靠近区域,置有人靠近状态
- if((pFaceRect->height >= (int)(m_nImgHeight/m_stFaceConfig.fCloseFaceSize))&&(pFaceRect->height <= (int)(m_nImgHeight/m_stFaceConfig.fOperateFaceSize)))
- {
- if((m_eMonitorState == NoBody) || (m_eMonitorState == SomebodyFar))
- {
- nCurafaceSerial = i;
- m_eMonitorState = SomebodyClose; //进入有人靠近状态
- }
- m_pHostEvent->GenerateMonitorEvent(Close); //产生有人靠近事件
- }
- else if (pFaceRect->height >= (int)(m_nImgHeight/m_stFaceConfig.fOperateFaceSize))
- {
- if(m_eMonitorState != SomebodyOperate)
- {
- nCurafaceSerial = i;
- m_eMonitorState = SomebodyOperate; //进入有人操作状态
- }
- m_pHostEvent->GenerateMonitorEvent(EnterOperate); //产生有人进入操作距离事件
- }
- else
- {
- if(m_eMonitorState == NoBody)
- {
- nCurafaceSerial = i;
- m_eMonitorState = SomebodyFar; //进入远距离有人状态
- }
- else
- {
- m_eMonitorState = SomebodyFar; //进入远距离有人状态
- }
- m_pHostEvent->GenerateMonitorEvent(Appear); //产生有人出现事件
- }
- }
- CvRect* pFaceRect = (CvRect*)cvGetSeqElem(pfaceSeq, nCurafaceSerial);
- //截取人脸图像,放大截取区域,截取半身头像
- CalcUpbodyRegion(pFaceRect);
- //保存半身头像坐标
- m_stAllFaceInfo.astFaceInfo[0].stRegion.stUpperBodyRect = *pFaceRect;
- m_stAllFaceInfo.astFaceInfo[0].eCamera = m_eCamera;
- }
- else {
- #ifdef DEVOPS_ON_PRD
- #else
- if (EnvironCamera == m_eCamera) {
- m_pHostEvent->GenerateMonitorEvent(video_monitor_event_type::NoDetectBody, "上摄像头未检测到人脸"); //上摄像头未检测到人脸
- }
- else if(OperatorCamera == m_eCamera){
- m_pHostEvent->GenerateMonitorEvent(video_monitor_event_type::NoDetectBody, "下摄像头未检测到人脸"); //下摄像头未检测到人脸
- }
- #endif
- }
-
- if (pfaceSeq != NULL){
- cvReleaseMemStorage(&pfaceSeq->storage);
- pfaceSeq = NULL;
- }
- cvResetImageROI(m_pProcessImg);
-
- if(nFaceNum > 0){
- //发现有人
- m_stAllFaceInfo.nTatolFaceNum = nFaceNum;
- return true;
- }
- else{
- m_eMonitorState = NoBody;
- return false;
- }
- }
- //运动检测
- bool MotionTrack(CameraEnum eCamera, int diff_threshold = 10)
- {
- if (!GetSpecifiedCameraImage(eCamera))
- {
- m_pHostApi->Debug(FACECAP_DEBUG, "运动跟踪获取图像失败");
- return false;
- }
- cvResetImageROI(m_pProcessImg);
- memset(&m_stObjTrackRslt,0,sizeof(CMotionTrackRslt));
- const double MHI_DURATION = 0.5;
- const double MAX_TIME_DELTA = 0.5;
- const double MIN_TIME_DELTA = 0.05;
- const int N = 3;
- //ring image buffer
- // temporary images
- IplImage*dst = cvCreateImage( cvSize(m_pProcessImg->width,m_pProcessImg->height), 8, 1 );
- cvZero( dst);
- dst->origin = m_pProcessImg->origin;
- //get current time in seconds
- double timestamp = clock()/100.;
- CvSize size = cvSize(m_pProcessImg->width,m_pProcessImg->height);
- int i, idx1, idx2;
- IplImage* silh;
- IplImage* pyr = cvCreateImage( cvSize((size.width & -2)/2, (size.height & -2)/2), 8, 1 );
- CvMemStorage *stor;
- CvSeq *cont;
- if( !m_pMhImg || m_pMhImg->width != size.width || m_pMhImg->height != size.height )
- {
- if( m_pMhBuf == 0 )
- {
- m_pMhBuf = (IplImage**)malloc(N*sizeof(m_pMhBuf[0]));
- memset( m_pMhBuf, 0, N*sizeof(m_pMhBuf[0]));
- }
-
- for( i = 0; i < N; i++ )
- {
- cvReleaseImage( &m_pMhBuf[i] );
- m_pMhBuf[i] = cvCreateImage( size, IPL_DEPTH_8U, 1 );
- cvZero(m_pMhBuf[i]);
- }
- cvReleaseImage( &m_pMhImg );
- m_pMhImg = cvCreateImage( size, IPL_DEPTH_32F, 1 );
- //clear MHI at the beginning
- cvZero( m_pMhImg );
- }
- //convert frame to grayscale
- cvCvtColor( m_pProcessImg, m_pMhBuf[m_nLastBuf], CV_BGR2GRAY );
- //cvSaveImage("0.bmp",m_pProcessImg);
- idx1 = m_nLastBuf;
- //index of (last - (N-1))th frame
- idx2 = (m_nLastBuf + 1) % N;
- m_nLastBuf = idx2;
- // 做帧差
- silh = m_pMhBuf[idx2];
- //get difference between frames
- cvAbsDiff( m_pMhBuf[idx1], m_pMhBuf[idx2], silh );
- //cvSaveImage("Diff.bmp",silh);
- //对差图像做二值化
- cvThreshold( silh, silh, 10, 255, CV_THRESH_BINARY );
- //cvSaveImage("Threshold.bmp",silh);
- //更新运动历史图像
- cvUpdateMotionHistory( silh, m_pMhImg, timestamp, MHI_DURATION );
- cvCvtScale( m_pMhImg, dst, 255./MHI_DURATION, (MHI_DURATION - timestamp)*255./MHI_DURATION );
- //cvCvtScale( m_pMhImg, dst, 255./MHI_DURATION, 0 );
- // 中值滤波,消除小的噪声
- cvSmooth( dst, dst, CV_MEDIAN, 3, 0, 0, 0 );
- // 向下采样,去掉噪声
- cvPyrDown( dst, pyr, 7 );
- //闭运算,消除目标的不连续空洞
- //进行闭运算
- //IplConvKernel* element = cvCreateStructuringElementEx(20,20,1,1,CV_SHAPE_ELLIPSE);
- //cvMorphologyEx(pyr,pyr,NULL,element,CV_MOP_CLOSE,1);
- //膨胀
- cvDilate( pyr, pyr, 0, 2 ); // 做膨胀操作,消除目标的不连续空洞
- cvPyrUp( pyr, dst, 7 );
- // 下面的程序段用来找到轮廓
- stor = cvCreateMemStorage(0);
- cont = cvCreateSeq(CV_SEQ_ELTYPE_POINT, sizeof(CvSeq), sizeof(CvPoint) , stor);
- // 找到所有轮廓
- cvFindContours( dst, stor, &cont, sizeof(CvContour), CV_RETR_LIST , CV_LINK_RUNS, cvPoint(0,0));
- cvReleaseImage(&dst);
- //double fArea = 0.0;
- // 直接使用CONTOUR中的矩形来画轮廓
- for(;cont;cont = cont->h_next)
- {
- CvRect r = ((CvContour*)cont)->rect;
- if((r.height * r.width > m_stFaceConfig.nContourMinAera)&&((r.height * r.width) != (m_nImgWidth*m_nImgHeight))) // 面积小的方形抛弃掉
- //{
- //fArea = fabs(cvContourArea( cont, CV_WHOLE_SEQ )); //获取当前轮廓面积
- //if ((fArea > CONTOUR_MAX_AERA)&&(r.height * r.width != m_nImgWidth*m_nImgHeight))
- {
- m_stObjTrackRslt.ObjRect[m_stObjTrackRslt.nObjNum] = r;
- m_stObjTrackRslt.nObjNum++;
- }
- //}
- }
- // free memory
- cvReleaseMemStorage(&stor);
- cvReleaseImage( &pyr );
- cvResetImageROI(m_pProcessImg);
- if (m_stObjTrackRslt.nObjNum >0)
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- //计算监控线程下一步
- void VideoMonitorThreadNextStep()
- {
- if(m_stAllFaceInfo.astFaceInfo[0].eDistance == OperateDistance)
- {
- if (m_eMonitorState != SomebodyOperate)
- {
- m_eMonitorState = SomebodyOperate;
- m_stAllFaceInfo.astFaceInfo[0].eScene = ForwardScened;
- m_pHostEvent->GenerateMonitorEvent(EnterOperate); //产生有人进入操作距离事件
- m_pHostApi->Debug(FACECAP_DEBUG, "有人进入操作距离!");
- //获取UUID
- if (m_stAllFaceInfo.astFaceInfo[0].FaceID == 0)
- {
- m_stAllFaceInfo.astFaceInfo[0].FaceID = m_pHostApi->GenerateUUID();
- }
- }
- else
- {
- if(m_stAllFaceInfo.astFaceInfo[0].eScene != LockScene)
- {
- m_eMonitorState = SomebodyOperate;
- m_stAllFaceInfo.astFaceInfo[0].eScene = LockScene;
- }
- m_pHostEvent->GenerateMonitorEvent(CaptureFace); //发送捕获人脸事件
- m_pHostApi->Debug(FACECAP_DEBUG, "锁定人脸!");
- }
- }
- else if(m_stAllFaceInfo.astFaceInfo[0].eDistance == FarDistance)
- {
- if((m_eMonitorState == SomebodyOperate)||(m_eMonitorState == SomebodyClose))
- {
- m_stAllFaceInfo.astFaceInfo[0].eScene = UnLockScene;
- m_eMonitorState = SomebodyFar;
- memset(&m_stAllFaceInfo,0,sizeof(CAllFaceInfo));
- m_stAllFaceInfo.astFaceInfo[0].stRegion.stUpperBodyRect.height = m_nImgHeight/2;
- m_stAllFaceInfo.astFaceInfo[0].stRegion.stUpperBodyRect.width = m_nImgWidth/2;
- m_stAllFaceInfo.astFaceInfo[0].stRegion.stUpperBodyRect.x = m_nImgHeight/4;
- m_stAllFaceInfo.astFaceInfo[0].stRegion.stUpperBodyRect.y = m_nImgWidth/4;
- m_pHostEvent->GenerateMonitorEvent(Leave); //产生客户离开事件
- m_pHostApi->Debug(FACECAP_DEBUG, "客户离开!");
- //清除UUID
- m_stAllFaceInfo.astFaceInfo[0].FaceID = 0;
- }
- }
- else if (m_stAllFaceInfo.astFaceInfo[0].eDistance == CloseDistance)
- {
- if (SomebodyOperate == m_eMonitorState)
- {
- m_stAllFaceInfo.astFaceInfo[0].eScene = BackwardScened;
- m_eMonitorState = SomebodyClose;
- m_pHostEvent->GenerateMonitorEvent(BackToClose); //产生客户退回到接近距离事件
- m_pHostApi->Debug(FACECAP_DEBUG, "客户退回到接近距离!");
- }
- else if(SomebodyFar == m_eMonitorState)
- {
- m_stAllFaceInfo.astFaceInfo[0].eScene = ForwardScened;
- m_eMonitorState = SomebodyClose;
- m_pHostApi->Debug(FACECAP_DEBUG, "有人靠近!");
- //获取UUID
- if (m_stAllFaceInfo.astFaceInfo[0].FaceID == 0)
- {
- m_stAllFaceInfo.astFaceInfo[0].FaceID = m_pHostApi->GenerateUUID();
- }
- }
- m_pHostEvent->GenerateMonitorEvent(Close); //产生有人靠近事件
- }
- }
- // 计算当前人脸是否进入另外一个相机的最佳视野中
- bool IsFacePosOverStep(CameraEnum eCamera,CvRect FaceRect)
- {
- if(m_pOperatorVideoQueue == NULL)
- {
- return false;
- }
- if(EnvironCamera == eCamera)
- {
- if(((FaceRect.x > (m_nImgWidth/2-m_nImgHeight/2+m_nImgHeight/m_stFaceConfig.fDetectFaceSize/2))|| (FaceRect.x < (m_nImgWidth/2+m_nImgHeight/2-m_nImgHeight/m_stFaceConfig.fDetectFaceSize/2)))&&
- (FaceRect.y > (m_nImgHeight-m_nImgHeight/m_stFaceConfig.fDetectFaceSize*4/m_stFaceConfig.nUpCameraEdgeLimit)))
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- else if(OperatorCamera == eCamera)
- {
- if(FaceRect.y < ((m_nImgHeight/m_stFaceConfig.fDetectFaceSize)*1/m_stFaceConfig.nDownCameraEdgeLimit))
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- else
- {
- return false;
- }
- }
- //根据主用户设置人脸剪辑区域
- void SetUpperbodyToCenter()
- {
- if(OperatorCamera == m_stFaceConfig.nPrimCamera)
- {
- if (m_pOperatorVideoQueue == NULL){
- m_stAllFaceInfo.astFaceInfo[0].eCamera = EnvironCamera;
- }
- else{
- m_stAllFaceInfo.astFaceInfo[0].eCamera = OperatorCamera;
- }
- }
- else{
- m_stAllFaceInfo.astFaceInfo[0].eCamera = EnvironCamera;
- }
- int nImgWidth = 0, nImgHeight = 0;
- if (EnvironCamera == m_stAllFaceInfo.astFaceInfo[0].eCamera){
- if (m_pEnvironVideoQueue == NULL){
- return;
- }
- if (m_pEnvironVideoQueue->GetVideoLens() <= 0){
- m_pHostApi->Debug(FACECAP_DEBUG, "环境相机图像队列为空");
- return;
- }
- int isize = m_pEnvironVideoQueue->GetFrameSize(nImgWidth, nImgHeight);
- if (0 == isize) {
- return;
- }
- }
- else if(OperatorCamera == m_stAllFaceInfo.astFaceInfo[0].eCamera){
- if (m_pOperatorVideoQueue == NULL){
- return;
- }
- if (m_pOperatorVideoQueue->GetVideoLens() <= 0){
- m_pHostApi->Debug(FACECAP_DEBUG, "操作相机图像队列为空");
- return ;
- }
- int isize = m_pOperatorVideoQueue->GetFrameSize(nImgWidth, nImgHeight);
- if (0 == isize) {
- return;
- }
- }
- m_stAllFaceInfo.astFaceInfo[0].stRegion.stUpperBodyRect.height = nImgHeight/2;
- m_stAllFaceInfo.astFaceInfo[0].stRegion.stUpperBodyRect.width = nImgWidth/2;
- m_stAllFaceInfo.astFaceInfo[0].stRegion.stUpperBodyRect.x = nImgWidth/4;
- m_stAllFaceInfo.astFaceInfo[0].stRegion.stUpperBodyRect.y = nImgHeight/4;
- WriteAllFaceInfo(m_stAllFaceInfo);
- }
- bool RvcTimeout(int ims)
- {
- bool btimeout = true;
- #ifdef _WIN32
- DWORD dwRet = WaitForSingleObject(m_hStopEventWait, ims);
- if (WAIT_TIMEOUT == dwRet) {
- }
- else if (WAIT_OBJECT_0 == dwRet) {
- btimeout = false;
- }
- #else
- struct timespec ts;
- clock_gettime(CLOCK_REALTIME, &ts);
- long unsec = ts.tv_nsec + (1000 * 1000 * ims);
- ts.tv_sec += (unsec / 1000000000);
- ts.tv_nsec = (unsec % 1000000000);
- int itimeout = sem_timedwait(&m_semt, &ts);
- if (0 != itimeout && (ETIMEDOUT == errno)) {
- }
- else if (0 == itimeout) {
- btimeout = false;
- }
- #endif
- return btimeout;
- }
- void ReleaseMotionTrackRst()
- {
- if (m_pMhImg)
- {
- cvReleaseImage(&m_pMhImg);
- m_pMhImg = NULL;
- }
- if(m_pMhBuf)
- {
- for (int i=0;i<3;i++)
- {
- if (m_pMhBuf[i] != NULL)
- {
- cvReleaseImage(&m_pMhBuf[i]);
- m_pMhBuf[i] = NULL;
- }
- }
- free(m_pMhBuf);
- m_pMhBuf = NULL;
- }
- m_nLastBuf=0;
- }
- CameraEnum GetInitPrimCamera()
- {
- CameraEnum eCamera = (CameraEnum)m_stFaceConfig.nPrimCamera;
-
- if (NULL == m_pOperatorVideoQueue)
- {
- if ((m_nCameraState == 0) || (m_nCameraState == 2))
- {
- eCamera = EnvironCamera;
- }
- else if (m_nCameraState == 1)
- {
- eCamera = OperatorCamera;
- }
- else if (m_nCameraState == 3)
- {
- eCamera = ErrorCamera;
- }
- }
- return eCamera;
- }
- int VideoMonitor()
- {
- bool bRst = false;
- uint32_t nSearchFaceFailNum = 0; //搜索人脸失败次数
- uint32_t nDetectFailNum = 0; //检测人脸失败的次数
- //select camera
- m_eCamera = GetInitPrimCamera();
- uint32_t iwaittime = m_stFaceConfig.nSleepShort;
- while (!m_bStopVieoMonitor)
- {
- if(RvcTimeout(iwaittime))
- {
- //如果摄像头没启动或故障,停止扫描,休眠2s
- if (3 == m_nCameraState){
- iwaittime = 2000;
- m_pHostApi->Debug(FACECAP_DEBUG, "camera stop or all camera error!");
- continue;
- }
- //灯光变化时,清空历史记录,防止误判
- if (m_bLightChange){
- ReleaseMotionTrackRst();
- m_bLightChange = false;
- }
- //if no people,start motion tracker
- if(NoBody == m_eMonitorState){
- m_pHostApi->Debug(FACECAP_DEBUG, "NoBody");
- bRst = GetSpecifiedCameraImage(m_eCamera);
- if (bRst){
- int size = (int)m_nImgHeight/m_stFaceConfig.fSearchFaceSize;
- bRst = FaceSearchWithSpecifiedSize(size);
- if (!bRst){
- SetUpperbodyToCenter();
- iwaittime = m_stFaceConfig.nSleepLong;
- SwitchDetectCamera();
- }
- else{
- WriteAllFaceInfo(m_stAllFaceInfo); //保存人脸坐标信息
- iwaittime = m_stFaceConfig.nSleepMiddle;
- }
- }
- else{
- iwaittime = m_stFaceConfig.nSleepMiddle;
- SwitchDetectCamera();
- }
- }
- else if (SomebodyFar == m_eMonitorState) //if somebody space 2.5m
- {
- m_pHostApi->Debug(FACECAP_DEBUG, "SomebodyFar");
- bRst = GetSpecifiedCameraImage(m_eCamera);
- if (bRst){
- int size = (int)m_nImgHeight/m_stFaceConfig.fSearchFaceSize;
- bRst = FaceSearchWithSpecifiedSize(size);
- if (!bRst){
- SetUpperbodyToCenter();
- iwaittime = m_stFaceConfig.nSleepLong;
- SwitchDetectCamera();
- }
- else{
- WriteAllFaceInfo(m_stAllFaceInfo);
- iwaittime = m_stFaceConfig.nSleepShort;
- }
- }
- else{
- iwaittime = m_stFaceConfig.nSleepMiddle;
- SwitchDetectCamera();
- }
- }
- else if (SomebodyClose == m_eMonitorState) //close distance,1.5m
- {
- m_pHostApi->Debug(FACECAP_DEBUG, "SomebodyClose");
- bRst = FaceDetectWithSpecifiedCamera(m_eCamera);
- if(!bRst){
- if(NULL != m_pOperatorVideoQueue){
- SwitchDetectCamera();
- bRst = FaceDetectWithSpecifiedCamera(m_eCamera);
- if (!bRst){
- nSearchFaceFailNum++;
- //if search face fail, return motiontracker
- if(nSearchFaceFailNum > 2){
- SetUpperbodyToCenter();
- m_eMonitorState = NoBody;
- m_pHostEvent->GenerateMonitorEvent(Leave);
- m_pHostApi->Debug(FACECAP_DEBUG, "客户离开!");
- nSearchFaceFailNum = 0;
- iwaittime = m_stFaceConfig.nSleepLong;
- }
- else{
- iwaittime = m_stFaceConfig.nSleepMiddle;
- }
- }
- else{
- nSearchFaceFailNum = 0;
- VideoMonitorThreadNextStep();
- WriteAllFaceInfo(m_stAllFaceInfo);
- iwaittime = m_stFaceConfig.nSleepShort;
- }
- }
- else //single camera mod
- {
- nSearchFaceFailNum++;
- //if search face fail,return motiontracker
- if(nSearchFaceFailNum > 2){
- SetUpperbodyToCenter();
- m_eMonitorState = NoBody;
- m_pHostEvent->GenerateMonitorEvent(Leave);
- m_pHostApi->Debug(FACECAP_DEBUG, "客户离开!");
- nSearchFaceFailNum = 0;
- iwaittime = m_stFaceConfig.nSleepLong;
- }
- else{
- iwaittime = m_stFaceConfig.nSleepMiddle;
- }
- }
- }
- else
- {
- //if curcamera search face success, judge which camera result is the best
- m_pHostApi->Debug(FACECAP_DEBUG, "Close distance, %s Search face Success", (m_eCamera == EnvironCamera) ? "EnvironCamera" : "OperatorCamera");
- if((m_pOperatorVideoQueue != NULL)&&(m_pEnvironVideoQueue != NULL))
- {
- SwitchDetectCamera();
- CAllFaceInfo stFaceInfoTmp = m_stAllFaceInfo;
- if (FaceDetectWithSpecifiedCamera(m_eCamera))
- {
- int CurFaceArea = m_stAllFaceInfo.astFaceInfo[0].stRegion.stFaceRect.width*m_stAllFaceInfo.astFaceInfo[0].stRegion.stFaceRect.height;
- int FrontFaceArea = stFaceInfoTmp.astFaceInfo[0].stRegion.stFaceRect.width*stFaceInfoTmp.astFaceInfo[0].stRegion.stFaceRect.height;
- //if cur face area less than front face,select front Face
- if (FrontFaceArea > CurFaceArea){
- SwitchDetectCamera();
- m_stAllFaceInfo = stFaceInfoTmp;
- }
- }
- else{
- SwitchDetectCamera();
- m_stAllFaceInfo = stFaceInfoTmp;
- }
- }
- nSearchFaceFailNum = 0;
- VideoMonitorThreadNextStep();
- WriteAllFaceInfo(m_stAllFaceInfo);
- iwaittime = m_stFaceConfig.nSleepShort;
- }
- }
- else if (SomebodyOperate == m_eMonitorState) //当有人进入操作距离时
- {
- m_pHostApi->Debug(FACECAP_DEBUG, "SomebodyOperate");
- //如果是双相机模式
- if (m_pOperatorVideoQueue != NULL){
- m_eCamera = m_stAllFaceInfo.astFaceInfo[0].eCamera;
- //先搜索上次搜索到人脸的区域
- if(m_stAllFaceInfo.nTatolFaceNum > 0){
- m_pHostApi->Debug(FACECAP_DEBUG, "Operator distance,CurCamera search last face Region");
- bRst = FaceDetectWithSpecifiedCameraRegion(m_eCamera, m_stAllFaceInfo.astFaceInfo[0].stRegion.stUpperBodyRect);
- }
- else{
- bRst = false;
- }
- if(!bRst){
- m_pHostApi->Debug(FACECAP_DEBUG, "Operator distance,search Face by CurCamera");
- bRst = FaceDetectWithSpecifiedCamera(m_eCamera);
- }
- }
- else //如果单相机模式
- {
- //先搜索上次搜索到人脸的区域
- if(m_stAllFaceInfo.nTatolFaceNum > 0){
- m_pHostApi->Debug(FACECAP_DEBUG, "Operator distance, %s Search Last face Region", (m_eCamera == EnvironCamera) ? "EnvironCamera" : "OperatorCamera");
- bRst = FaceDetectWithSpecifiedCameraRegion(m_eCamera, m_stAllFaceInfo.astFaceInfo[0].stRegion.stUpperBodyRect);
- }
- else{
- bRst = false;
- }
- if(!bRst){
- bRst = FaceDetectWithSpecifiedCamera(m_eCamera);
- }
- }
- if(bRst) //如果在当前相机中找到人脸
- {
- nDetectFailNum = 0;
- //如果是双相机模式,
- if(m_pOperatorVideoQueue!=NULL)
- {
- //找到人脸后,检测另一个相机中是否有更大的人脸
- SwitchDetectCamera();
- CAllFaceInfo stFaceInfoTmp = m_stAllFaceInfo;
- if (FaceDetectWithSpecifiedCamera(m_eCamera))
- {
- int CurFaceArea = m_stAllFaceInfo.astFaceInfo[0].stRegion.stFaceRect.width*m_stAllFaceInfo.astFaceInfo[0].stRegion.stFaceRect.height;
- int FrontFaceArea = stFaceInfoTmp.astFaceInfo[0].stRegion.stFaceRect.width*stFaceInfoTmp.astFaceInfo[0].stRegion.stFaceRect.height;
- //if cur face area less than front face,select front Face
- if (FrontFaceArea > CurFaceArea){
- SwitchDetectCamera();
- m_stAllFaceInfo = stFaceInfoTmp;
- }
- }
- else{
- SwitchDetectCamera();
- m_stAllFaceInfo = stFaceInfoTmp;
- }
- //判断用户是否进入另外一个相机的视野,如果进入另一个相机的最佳视野
- if((m_pEnvironVideoQueue!=NULL)&&IsFacePosOverStep(m_eCamera,m_stAllFaceInfo.astFaceInfo[0].stRegion.stFaceRect))
- {
- stFaceInfoTmp = m_stAllFaceInfo; //暂存当前结果
- memset(&m_stAllFaceInfo,0,sizeof(CAllFaceInfo));
- SwitchDetectCamera();
- //在另一个相机中重新搜索
- m_pHostApi->Debug(FACECAP_DEBUG, "Operator distance, Change camera to:%s search Face", (m_eCamera == EnvironCamera) ? "EnvironCamera" : "OperatorCamera");
- bRst = FaceDetectWithSpecifiedCamera(m_eCamera);
- if(!bRst)
- {
- SwitchDetectCamera();
- m_stAllFaceInfo = stFaceInfoTmp;
- }
- }
- }
- VideoMonitorThreadNextStep();
- WriteAllFaceInfo(m_stAllFaceInfo);
- iwaittime = m_stFaceConfig.nSleepLong;
- }
- else //如果在当前相机中未找到用户
- {
- //如果双相机模式
- if(m_pOperatorVideoQueue!=NULL)
- {
- SwitchDetectCamera();
- m_pHostApi->Debug(FACECAP_DEBUG, "Operator distance, Change camera to:%s search Face", (m_eCamera == EnvironCamera) ? "EnvironCamera" : "OperatorCamera");
- bRst = FaceDetectWithSpecifiedCamera(m_eCamera);
- if(bRst)
- {
- nDetectFailNum = 0;
- VideoMonitorThreadNextStep();
- WriteAllFaceInfo(m_stAllFaceInfo);
- m_pHostApi->Debug(FACECAP_DEBUG, "Write Face info Success");
- iwaittime = m_stFaceConfig.nSleepLong;
- }
- else
- {
- nDetectFailNum++;
- if(nDetectFailNum >2) //如果连续2次未找到人脸,回到有人靠近状态
- {
- m_eMonitorState = SomebodyClose;
- m_stAllFaceInfo.astFaceInfo[0].eScene = UnLockScene;
- m_pHostEvent->GenerateMonitorEvent(LoseFace); //发送失去人脸事件
- m_pHostApi->Debug(FACECAP_DEBUG, "人脸失去锁定!");
- nDetectFailNum = 0;
- }
- iwaittime = m_stFaceConfig.nSleepShort;
- }
- }
- else //如果单相机模式
- {
- nDetectFailNum++;
- if(nDetectFailNum > 3) //如果连续3次未找到人脸,回到有人靠近状态
- {
- m_eMonitorState = SomebodyClose;
- m_stAllFaceInfo.astFaceInfo[0].eScene = UnLockScene;
- m_pHostEvent->GenerateMonitorEvent(LoseFace); //发送失去人脸事件
- m_pHostApi->Debug(FACECAP_DEBUG, "人脸失去锁定!");
- nDetectFailNum = 0;
- }
- iwaittime = m_stFaceConfig.nSleepShort;
- }
- }
- }
- }
- else
- {
- //清空存储区
- if (pfaceSeq != NULL){
- cvReleaseMemStorage(&pfaceSeq->storage);
- pfaceSeq = NULL;
- }
- if (NULL != m_pProcessImg){
- cvResetImageROI(m_pProcessImg);
- }
- m_pHostApi->Debug(FACECAP_DEBUG, "stop face tracking..");
- break;
- }
- }
- return 0;
- }
- #ifdef _WIN32
- static unsigned int __stdcall VideoMonitorThread(void* pParam)
- {
- Clibfacecapture_impl* VideoFaceMonitor = (Clibfacecapture_impl*)pParam;
- return VideoFaceMonitor->VideoMonitor();
- }
- #else
- static void* videomonitorfunc(void* pParam)
- {
- Clibfacecapture_impl* VideoFaceMonitor = (Clibfacecapture_impl*)pParam;
- VideoFaceMonitor->VideoMonitor();
- return ((void*)0);
- }
- #endif
- public:
- //开始视频监控,pHost:事件,nMonitorFreq:监控频率,单位ms,MonitorType:监控类型,有三种模式可供选择
- bool StartVideoMonitor(CHostApi *pHostAPI, CVideoMonitorEvent*pHost, MonitorEnum eMonitorType)
- {
- #ifdef _WIN32
- ResetEvent(m_hStopEventWait);
- if (NULL == m_hVieoMonitorThread){
- m_hVieoMonitorThread = (HANDLE)_beginthreadex(NULL, 0, VideoMonitorThread, this, 0, (unsigned int*)&m_nVieoMonitorThreadId);
- if (m_hVieoMonitorThread) {
- m_bStopVieoMonitor = false;
- m_eMonitorState = MonitorStateEnum::NoBody;
- m_pHostApi->Debug(FACECAP_DEBUG, "create video monitor thread success.");
- }
- else {
- m_pHostApi->Debug(FACECAP_INFO, "create video monitor thread failed!");
- }
- }
- #else
- if (0 == pthread_create(&m_videomonitorthreadid, NULL, videomonitorfunc, (void*)this)){
- m_bStopVieoMonitor = false;
- m_eMonitorState = MonitorStateEnum::NoBody;
- m_pHostApi->Debug(FACECAP_DEBUG, "create video monitor thread success and thread id is %u.", m_videomonitorthreadid);
- }
- else {
- m_pHostApi->Debug(FACECAP_INFO, "create video monitor thread failed.");
- }
- #endif
- return true;
- }
- //停止视频监控
- bool StopVideoMonitor()
- {
- m_bStopVieoMonitor = true;
- #ifdef _WIN32
- SetEvent(m_hStopEventWait);
- DWORD ret = WaitForSingleObject(m_hVieoMonitorThread, INFINITE);
- if (WAIT_OBJECT_0 == ret) {
- m_pHostApi->Debug(FACECAP_DEBUG, "normal ....");
- }
- else if (WAIT_ABANDONED == ret) {
- m_pHostApi->Debug(FACECAP_DEBUG, "abandoned ....");
- }
- CloseHandle(m_hVieoMonitorThread);
- m_hVieoMonitorThread = NULL;
- #else
- sem_post(&m_semt);
- if (0 == pthread_join(m_videomonitorthreadid, NULL)) {
- m_pHostApi->Debug(FACECAP_DEBUG, "thread join video monitor thread %u success!", m_videomonitorthreadid);
- m_videomonitorthreadid = 0;
- }
- else{
- m_pHostApi->Debug(FACECAP_INFO, "thread join video monitor thread failed!");
- }
- #endif
- return true;
- }
- //有多少其他用户
- bool GetCustomerNum(uint32_t& num)
- {
- #ifdef _WIN32
- EnterCriticalSection(&CS);
- #else
- pthread_mutex_lock(&cs_mutex);
- #endif
- num = m_stFaceRstStorage.nTatolFaceNum;
- #ifdef _WIN32
- LeaveCriticalSection(&CS);
- #else
- pthread_mutex_unlock(&cs_mutex);
- #endif
- return true;
- }
- //获取主用户的常规属性
- bool GetMainCustomerStatus(uint64_t &FaceID, CCustomerStatus &Property)
- {
- #ifdef _WIN32
- EnterCriticalSection(&CS);
- #else
- pthread_mutex_lock(&cs_mutex);
- #endif
- //Property.eBrightness = m_stFaceRstStorage.astFaceInfo[0].eBrightness;
- Property.stCustomerCover = m_stFaceRstStorage.astFaceInfo[0].stCustomerCover;
- Property.stCustomerPos.eCamera = m_stFaceRstStorage.astFaceInfo[0].eCamera;//1
- Property.stCustomerPos.eDistance = m_stFaceRstStorage.astFaceInfo[0].eDistance;
- Property.stCustomerPos.ePose = m_stFaceRstStorage.astFaceInfo[0].ePose;
- Property.stCustomerPos.eScene = m_stFaceRstStorage.astFaceInfo[0].eScene;
- Property.stCustomerPos.stRange.sX = m_stFaceRstStorage.astFaceInfo[0].stRegion.stUpperBodyRect.x + (short)m_stFaceRstStorage.astFaceInfo[0].stRegion.stUpperBodyRect.width/2 - (short)m_nImgWidth/2;
- Property.stCustomerPos.stRange.sY = m_stFaceRstStorage.astFaceInfo[0].stRegion.stUpperBodyRect.y + (short)m_stFaceRstStorage.astFaceInfo[0].stRegion.stUpperBodyRect.height/2 - (short)m_nImgHeight/2;
- Property.stCustomerPos.stRange.sH = (short)m_stFaceRstStorage.astFaceInfo[0].stRegion.stUpperBodyRect.height/2;
- FaceID = m_stFaceRstStorage.astFaceInfo[0].FaceID;
- #ifdef _WIN32
- LeaveCriticalSection(&CS);
- #else
- pthread_mutex_unlock(&cs_mutex);
- #endif
- return true;
- }
- //获取用户的常规属性
- bool GetCustomerStatus(uint64_t FaceID, CCustomerStatus &Property)
- {
- #ifdef _WIN32
- EnterCriticalSection(&CS);
- #else
- pthread_mutex_lock(&cs_mutex);
- #endif
- bool bSearch = false;
- for (int i =0;i<m_stFaceRstStorage.nTatolFaceNum&&!bSearch;i++)
- {
- if(m_stFaceRstStorage.astFaceInfo[i].FaceID == FaceID)
- {
- Property.eBrightness = m_stFaceRstStorage.astFaceInfo[i].eBrightness;
- Property.stCustomerCover = m_stFaceRstStorage.astFaceInfo[i].stCustomerCover;
- Property.stCustomerPos.eCamera = m_stFaceRstStorage.astFaceInfo[i].eCamera;
- Property.stCustomerPos.eDistance = m_stFaceRstStorage.astFaceInfo[i].eDistance;
- Property.stCustomerPos.ePose = m_stFaceRstStorage.astFaceInfo[i].ePose;
- Property.stCustomerPos.eScene = m_stFaceRstStorage.astFaceInfo[i].eScene;
- Property.stCustomerPos.stRange.sX = m_stFaceRstStorage.astFaceInfo[i].stRegion.stUpperBodyRect.x
- +(short)m_stFaceRstStorage.astFaceInfo[i].stRegion.stUpperBodyRect.width/2-(short)m_nImgWidth/2;
- Property.stCustomerPos.stRange.sY = m_stFaceRstStorage.astFaceInfo[i].stRegion.stUpperBodyRect.y
- +(short)m_stFaceRstStorage.astFaceInfo[i].stRegion.stUpperBodyRect.height/2-(short)m_nImgHeight/2;
- Property.stCustomerPos.stRange.sH = (short)m_stFaceRstStorage.astFaceInfo[i].stRegion.stUpperBodyRect.height/2;
- bSearch = true;
- }
- }
- #ifdef _WIN32
- LeaveCriticalSection(&CS);
- #else
- pthread_mutex_unlock(&cs_mutex);
- #endif
- return true;
- }
- //获取所有用户FACEID
- bool GetTrackFace(uint64_t*arrFaceIDs, int *size)
- {
- #ifdef _WIN32
- EnterCriticalSection(&CS);
- #else
- pthread_mutex_lock(&cs_mutex);
- #endif
- for (int i = 0;i<m_stFaceRstStorage.nTatolFaceNum && i < *size;i++)
- {
- arrFaceIDs[i] = m_stFaceRstStorage.astFaceInfo[i].FaceID;
- }
- #ifdef _WIN32
- LeaveCriticalSection(&CS);
- #else
- pthread_mutex_unlock(&cs_mutex);
- #endif
- return true;
- }
- //获取用户的交互属性
- bool GetCustomerAppearance(uint64_t FaceID,CCustomerAppearance &Property)
- {
- #ifdef _WIN32
- EnterCriticalSection(&CS);
- #else
- pthread_mutex_lock(&cs_mutex);
- #endif
- bool bSearch = false;
- for (int i =0;i<m_stFaceRstStorage.nTatolFaceNum&&!bSearch;i++)
- {
- if(m_stFaceRstStorage.astFaceInfo[i].FaceID == FaceID)
- {
- Property.eHeight =m_stFaceRstStorage.astFaceInfo[i].eHeight;
- Property.eSex = m_stFaceRstStorage.astFaceInfo[i].eSex;
- Property.eYoungOld = m_stFaceRstStorage.astFaceInfo[i].eYoungOld;
- bSearch = true;
- }
- }
- #ifdef _WIN32
- LeaveCriticalSection(&CS);
- #else
- pthread_mutex_unlock(&cs_mutex);
- #endif
-
- return true;
- }
- };
- // 这是已导出类的构造函数。
- // 有关类定义的信息,请参阅 libfacecapture.h
- Clibfacecapture::Clibfacecapture(bool *pResult, CHostApi *pHostAPI, CVideoMonitorEvent*pHost, const char* EnvironVideoName, const char* OperateVideoName, MonitorEnum eMonitorType)
- {
- m_pImpl = new Clibfacecapture_impl(pResult, pHostAPI, pHost, EnvironVideoName, OperateVideoName, eMonitorType);
- }
- Clibfacecapture::~Clibfacecapture(void)
- {
- delete m_pImpl;
- }
- //有多少其他用户
- bool Clibfacecapture::GetCustomerNum(uint32_t& num)
- {
- return m_pImpl->GetCustomerNum(num);
- }
- //获取主用户的常规属性
- bool Clibfacecapture::GetMainCustomerStatus(uint64_t &FaceID,CCustomerStatus &Property)
- {
- return m_pImpl->GetMainCustomerStatus(FaceID,Property);
- }
- //获取其他用户的常规属性
- bool Clibfacecapture::GetCustomerStatus (uint64_t FaceID,CCustomerStatus &Property)
- {
- return m_pImpl->GetCustomerStatus(FaceID,Property);
- }
- //获取主用户的交互属性
- bool Clibfacecapture::GetCustomerAppearance(uint64_t FaceID,CCustomerAppearance &Property)
- {
- return m_pImpl->GetCustomerAppearance(FaceID,Property);
- }
- //获取所有用户FACEID
- bool Clibfacecapture::GetTrackFace(uint64_t*arrFaceIDs, int *size)
- {
- return m_pImpl->GetTrackFace(arrFaceIDs, size);
- }
- //灯光变化
- void Clibfacecapture::SetLightChange()
- {
- m_pImpl->m_bLightChange = true;
- }
- //相机状态
- void Clibfacecapture::SetCameraState(int nState)
- {
- m_pImpl->m_nCameraState = nState;
- }
- bool Clibfacecapture::StartFaceCapture()
- {
- return m_pImpl->StartFaceCapture();
- }
- bool Clibfacecapture::StopFaceCapture()
- {
- return m_pImpl->StopFaceCapture();
- }
- bool SnapShot(CImageFrame*img)
- {
- if(img == NULL){
- return false;
- }
- IplImage*cvimgtmp = cvCreateImage(cvSize(img->width,img->height),8,3);
- IplImage*cvimg = cvCreateImage(cvSize(img->width,img->height),8,3);
- char m_FileName[MAX_PATH] = {0};
- #ifdef _WIN32
- SYSTEMTIME nowTime; // 系统时间结构体
- GetLocalTime(&nowTime);
- _snprintf(m_FileName, MAX_PATH, "%4d%02d%02d%02d%02d%02d", nowTime.wYear, nowTime.wMonth, nowTime.wDay, nowTime.wHour, nowTime.wMinute, nowTime.wSecond);
- #else
- struct tm* pst = NULL;
- time_t t = time(NULL);
- pst = localtime(&t);
- snprintf(m_FileName, MAX_PATH, "%4d%02d%02d%02d%02d%02d", pst->tm_year + 1900, pst->tm_mon + 1, pst->tm_mday, pst->tm_hour, pst->tm_min, pst->tm_sec);
- #endif // _WIN32
- CvFont fontEvent = cvFont(2,2);
- memcpy(cvimg->imageData,img->data,img->framesize);
- int nstartx = 0;
- int nstarty = 0;
- cvCopy(cvimg,cvimgtmp);
- cvPutText(cvimgtmp, m_FileName,cvPoint(img->width-280,img->height-10), &fontEvent, CV_RGB( 255, 0, 0));
- memcpy(img->data,cvimgtmp->imageData,img->framesize);
- cvReleaseImage(&cvimg);
- cvReleaseImage(&cvimgtmp);
- return true;
- }
|