libfacecapture.cpp 73 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371
  1. // libfacecapture.cpp : 定义 DLL 应用程序的导出函数。
  2. //
  3. #include "libfacecapture.h"
  4. #include <string.h>
  5. #ifdef _WIN32
  6. #include <atlstr.h>
  7. #include <windows.h>
  8. #else
  9. #include <pthread.h>
  10. #include <semaphore.h>
  11. #include <errno.h>
  12. #endif
  13. #include <math.h>
  14. #include <time.h>
  15. #include "cv.h"
  16. #include "highgui.h"
  17. #include "libvideoqueue.h"
  18. #define SLASH '/'
  19. #define BACK_SLASH '\\'
  20. #define MB_SLASH_STR "/"
  21. #define MB_BACK_SLASH_STR "\\"
  22. #define W_SLASH_STR L"/"
  23. #define W_BACK_SLASH_STR L"\\"
  24. #if defined(UNICODE) || defined(_UNICODE)
  25. #define SLASH_STR W_SLASH_STR
  26. #define BACK_SLASH_STR W_BACK_SLASH_STR
  27. #else
  28. #define SLASH_STR MB_SLASH_STR
  29. #define BACK_SLASH_STR MB_BACK_SLASH_STR
  30. #endif
  31. #ifdef _WIN32
  32. #define SPLIT_SLASH BACK_SLASH
  33. #define SPLIT_SLASH_STR BACK_SLASH_STR
  34. #define MB_SPLIT_SLASH_STR MB_BACK_SLASH_STR
  35. #define W_SPLIT_SLASH_STR W_BACK_SLASH_STR
  36. #define LINE_BREAK_STR "\r\n"
  37. #else
  38. #define SPLIT_SLASH SLASH
  39. #define SPLIT_SLASH_STR SLASH_STR
  40. #define MB_SPLIT_SLASH_STR MB_SLASH_STR
  41. #define W_SPLIT_SLASH_STR W_SLASH_STR
  42. #define LINE_BREAK_STR "\n"
  43. #endif
  44. #define CASCADE_FACE "haarcascade_frontalface_alt.xml"
  45. #define CASCADE_EYE "haarcascade_mcs_eyepair_small.xml"
  46. #define CASCADE_NOSE "haarcascade_mcs_nose.xml"
  47. #define CASCADE_MOUTH "haarcascade_mcs_mouth.xml"
  48. #define MAX_FACE_NUM 6 //最多保留6张人脸
  49. #define RGB_IMG 1 //RGB格式的图像
  50. //将图像区域分成9宫格,此枚举用来表示人脸所处9宫格的区域
  51. enum FaceRegionEnum
  52. {
  53. FaceError = 0,
  54. FaceRegionLeftup, //左上角
  55. FaceRegionUp, //正上方
  56. FaceRegionRightUP, //右上角
  57. FaceRegionLeft, //左边
  58. FaceRegionCenter, //中央
  59. FaceRegionRight, //右边
  60. FaceRegionLeftDn, //左下角
  61. FaceRegionDn, //正下方
  62. FaceRegionRightDn, //右下角
  63. };
  64. //运动跟踪结果
  65. struct CMotionTrackRslt
  66. {
  67. int nObjNum; //当前图像中运动物体的数量
  68. CvRect ObjRect[MAX_FACE_NUM]; //存放运动物体
  69. };
  70. //客户位置
  71. struct CCustomerRegion
  72. {
  73. FaceRegionEnum eRegion; //人脸中心点在图像9宮格中属于哪个宮格
  74. CvRect stFaceRect; //脸部矩形,使用crect表示人脸在图像中精确位置
  75. CvRect stUpperBodyRect; //脸部剪辑矩形,使用crect表示人脸剪辑区域
  76. };
  77. //客户信息,程序内部逻辑使用
  78. struct CCustomerInfo
  79. {
  80. uint64_t FaceID; //人脸ID号
  81. CameraEnum eCamera; //1、2号摄像头
  82. CCustomerRegion stRegion; //客户位置,客户脸部的矩形区域
  83. SceneEnum eScene; //0不确定,1开始锁定、2失去锁定、3晃动、4向前、5向后
  84. DistanceEnum eDistance; //0不确定,1操作距离,2近端,3远端
  85. PoseEnum ePose; //0不确定,1-站立,2-坐立
  86. CCover stCustomerCover; //覆盖属性
  87. BrightnessEnum eBrightness; //人脸亮度
  88. SexEnum eSex; //0不知道,1女,2男
  89. YoungOldEnum eYoungOld; //0不知道,1小孩,2年轻人,3中年人,4老人
  90. HeightEnunm eHeight; //0不知道,1矮,2中等,3高
  91. };
  92. //计算过程中用于存储人脸的缓存
  93. struct CAllFaceInfo
  94. {
  95. int nTatolFaceNum; //当前图像帧中人脸数量
  96. CCustomerInfo astFaceInfo[MAX_FACE_NUM]; //所有用户的人脸,astFaceInfo[0]为主用户的人脸
  97. };
  98. //图像亮度调整参数
  99. struct CBrightAdjParam
  100. {
  101. double fLow; //映射前低值
  102. double fHigh; //映射前高值
  103. double fBottom; //映射后低值
  104. double fTop; //映射后高值
  105. double fGamma; //gamma变换值
  106. };
  107. //用于本地保存人脸的结构体
  108. struct CLocalFaceInfo
  109. {
  110. CCover stFaceCover; //人脸覆盖
  111. CCustomerRegion stCustomerRegion; //人脸位置
  112. IplImage*img; //人脸图像
  113. };
  114. enum MonitorStateEnum
  115. {
  116. NoBody = 0, //当前没有人
  117. SomebodyFar, //远距离有人
  118. SomebodyClose, //有人在靠近
  119. SomebodyOperate //客户进入操作区域
  120. };
  121. class Clibfacecapture_impl
  122. {
  123. public:
  124. Clibfacecapture_impl(bool *pResult, CHostApi *pHostAPI, CVideoMonitorEvent*pHost, const char* EnvironVideoName, const char* OperateVideoName = NULL, MonitorEnum eMonitorType = MotionTarckAndFaceDetect)
  125. {
  126. m_pResult = pResult;
  127. m_pHostApi = pHostAPI;
  128. m_pHostEvent = pHost;
  129. m_eType = eMonitorType;
  130. m_pFaceCascade = NULL; //脸部分类器
  131. m_pEyeCascade = NULL; //眼睛分类器
  132. m_pMouthCascade = NULL; //嘴巴分类器
  133. m_pNoseCascade = NULL; //鼻子分类器
  134. m_pFaceStorage = NULL;
  135. pfaceSeq = NULL;
  136. m_pProcessImg = NULL;
  137. #ifdef _WIN32
  138. m_hVieoMonitorThread = NULL;
  139. m_nVieoMonitorThreadId = 0;
  140. #else
  141. m_videomonitorthreadid = 0;
  142. #endif
  143. m_bStopVieoMonitor = true;
  144. m_pEnvironVideoQueue = NULL;
  145. m_pOperatorVideoQueue = NULL;
  146. m_nImgWidth = 0;
  147. m_nImgHeight = 0;
  148. m_pMhImg = NULL;
  149. m_pMhBuf = NULL;
  150. m_bLightChange = false;
  151. m_nCameraState = 0;
  152. m_nLastBuf = 0;
  153. m_eMonitorState = NoBody;
  154. memset(m_envqueuename, 0, MAX_PATH);
  155. memset(m_optqueuename, 0, MAX_PATH);
  156. if (NULL != EnvironVideoName){
  157. strncpy(m_envqueuename, EnvironVideoName, (strlen(EnvironVideoName) > MAX_PATH) ? (MAX_PATH - 1) : strlen(EnvironVideoName));
  158. }
  159. if (NULL != OperateVideoName) {
  160. strncpy(m_optqueuename, OperateVideoName, (strlen(OperateVideoName) > MAX_PATH) ? (MAX_PATH - 1) : strlen(OperateVideoName));
  161. }
  162. #ifdef _WIN32
  163. InitializeCriticalSection(&CS);
  164. m_hStopEventWait= ::CreateEventA(NULL, TRUE, 0, 0);
  165. if (!m_hStopEventWait) {
  166. *pResult = false;
  167. pHostAPI->Debug(FACECAP_INFO, "create hEventWait failed!");
  168. return;
  169. }
  170. #else
  171. pthread_mutex_init(&cs_mutex, NULL);
  172. sem_init(&m_semt, 0, 0);
  173. #endif
  174. memset(&m_stFaceConfig,0,sizeof(CFaceCaptureConfig));
  175. memset(&m_stFaceRstStorage,0,sizeof(CFaceCaptureConfig));
  176. //读取配置文件
  177. *pResult = pHostAPI->LoadConfig(m_stFaceConfig);
  178. if (!*pResult){
  179. pHostAPI->Debug(FACECAP_INFO, "Load Configuration failed!");
  180. return;
  181. }
  182. *pResult = InitFaceCapture(m_stFaceConfig.strFaceDataDirPath);
  183. if (!*pResult){
  184. return;
  185. }
  186. for (int i = 0; i < MAX_FACE_NUM; i++) {
  187. m_PreFaceRect[i] = cvRect(0, 0, 0, 0);
  188. }
  189. memset(&m_stAllFaceInfo, 0, sizeof(CAllFaceInfo));
  190. //初始化剪辑区域为屏幕中央区域
  191. m_stAllFaceInfo.astFaceInfo[0].stRegion.stUpperBodyRect = cvRect(160, 60, 320, 240);
  192. memset(&m_stObjTrackRslt, 0, sizeof(CMotionTrackRslt));
  193. memset(&m_stBrightAdjParam, 0, sizeof(CBrightAdjParam));
  194. *pResult = WriteAllFaceInfo(m_stAllFaceInfo);
  195. if (!*pResult) {
  196. return;
  197. }
  198. }
  199. bool StartFaceCapture()
  200. {
  201. if (!m_bStopVieoMonitor) {
  202. m_pHostApi->Debug(FACECAP_INFO, "facetracking thread is already start.");
  203. return true;
  204. }
  205. m_pEnvironVideoQueue = new Clibvideoqueue(m_envqueuename);
  206. if (strlen(m_optqueuename)) {
  207. m_pOperatorVideoQueue = new Clibvideoqueue(m_optqueuename);
  208. }
  209. else {
  210. m_pOperatorVideoQueue = NULL;
  211. }
  212. //开始视频监控线程
  213. return StartVideoMonitor(m_pHostApi, m_pHostEvent, m_eType);
  214. }
  215. bool StopFaceCapture()
  216. {
  217. if (m_bStopVieoMonitor) {
  218. m_pHostApi->Debug(FACECAP_INFO, "facetracking thread is already stop.");
  219. return true;
  220. }
  221. if (true == StopVideoMonitor()){
  222. m_pHostApi->Debug(FACECAP_DEBUG, "stop video monitor thread success!");
  223. }
  224. if (NULL != m_pEnvironVideoQueue){
  225. delete m_pEnvironVideoQueue;
  226. m_pEnvironVideoQueue = NULL;
  227. }
  228. if (NULL != m_pOperatorVideoQueue){
  229. delete m_pOperatorVideoQueue;
  230. m_pOperatorVideoQueue = NULL;
  231. }
  232. return true;
  233. }
  234. ~Clibfacecapture_impl()
  235. {
  236. #ifdef _WIN32
  237. DeleteCriticalSection(&CS);
  238. if (!m_hStopEventWait) {
  239. CloseHandle(m_hStopEventWait);
  240. m_hStopEventWait = NULL;
  241. }
  242. #else
  243. pthread_mutex_destroy(&cs_mutex);
  244. #endif
  245. if (m_pMhImg){
  246. cvReleaseImage(&m_pMhImg);
  247. m_pMhImg = NULL;
  248. }
  249. if(m_pMhBuf){
  250. for (int i=0;i<3;i++){
  251. if (m_pMhBuf[i] != NULL){
  252. cvReleaseImage(&m_pMhBuf[i]);
  253. m_pMhBuf[i] = NULL;
  254. }
  255. }
  256. free(m_pMhBuf);
  257. }
  258. if (m_pProcessImg){
  259. cvReleaseImage(&m_pProcessImg);
  260. m_pProcessImg = NULL;
  261. }
  262. if (m_pFaceCascade){
  263. cvReleaseHaarClassifierCascade(&m_pFaceCascade);
  264. m_pFaceCascade = NULL;
  265. }
  266. if (m_pEyeCascade){
  267. cvReleaseHaarClassifierCascade(&m_pEyeCascade);
  268. m_pEyeCascade = NULL;
  269. }
  270. if (m_pMouthCascade){
  271. cvReleaseHaarClassifierCascade(&m_pMouthCascade);
  272. m_pMouthCascade = NULL;
  273. }
  274. if (m_pNoseCascade){
  275. cvReleaseHaarClassifierCascade(&m_pNoseCascade);
  276. m_pNoseCascade = NULL;
  277. }
  278. }
  279. public:
  280. bool m_bLightChange;
  281. int m_nCameraState; //0:无故障1:env故障,2:opt故障,3:全部故障
  282. private:
  283. #ifdef _WIN32
  284. HANDLE m_hStopEventWait; // CreateEvent
  285. CRITICAL_SECTION CS;
  286. #else
  287. pthread_mutex_t cs_mutex;
  288. sem_t m_semt;
  289. #endif
  290. bool* m_pResult;
  291. MonitorEnum m_eType;
  292. CvHaarClassifierCascade* m_pFaceCascade; //脸部分类器
  293. CvHaarClassifierCascade* m_pEyeCascade; //眼睛分类器
  294. CvHaarClassifierCascade* m_pMouthCascade; //嘴巴分类器
  295. CvHaarClassifierCascade* m_pNoseCascade; //鼻子分类器
  296. CMotionTrackRslt m_stObjTrackRslt; //运动跟踪的结果
  297. IplImage *m_pMhImg; //MHI: motion history image
  298. IplImage **m_pMhBuf;
  299. int m_nLastBuf;
  300. CFaceCaptureConfig m_stFaceConfig;
  301. int m_nImgWidth; //当前摄像头图像宽
  302. int m_nImgHeight; //当前摄像头图像高
  303. CvSeq* pfaceSeq; //人脸序列
  304. CvMemStorage* m_pFaceStorage; //人脸内部存储空间
  305. IplImage* m_pProcessImg; //用于处理的图像
  306. //存储前一帧的人脸矩形(不包括人脸)
  307. CvRect m_PreFaceRect[MAX_FACE_NUM];
  308. #ifdef _WIN32
  309. HANDLE m_hVieoMonitorThread;
  310. unsigned int m_nVieoMonitorThreadId;
  311. #else
  312. pthread_t m_videomonitorthreadid;
  313. #endif
  314. bool m_bStopVieoMonitor;
  315. Clibvideoqueue* m_pEnvironVideoQueue; //环境摄像头小分辨率视频队列
  316. Clibvideoqueue* m_pOperatorVideoQueue; //操作摄像头视频队列
  317. CAllFaceInfo m_stAllFaceInfo;
  318. CAllFaceInfo m_stFaceRstStorage;
  319. CBrightAdjParam m_stBrightAdjParam; //亮度调节参数
  320. volatile MonitorStateEnum m_eMonitorState;
  321. CVideoMonitorEvent* m_pHostEvent;
  322. CHostApi* m_pHostApi;
  323. CameraEnum m_eCamera;
  324. char m_envqueuename[MAX_PATH];
  325. char m_optqueuename[MAX_PATH];
  326. //初始化
  327. bool InitFaceCapture(const char *base_dir)
  328. {
  329. char dir[MAX_PATH] = {0};
  330. FIGetDir(CASCADE_FACE, base_dir, dir);
  331. m_pFaceCascade=(CvHaarClassifierCascade*)cvLoad(dir,NULL,NULL,NULL);
  332. if (!m_pFaceCascade){
  333. m_pHostApi->Debug(FACECAP_INFO, "加载脸部分类器失败!");
  334. return false;
  335. }
  336. FIGetDir(CASCADE_EYE, base_dir, dir);
  337. m_pEyeCascade=(CvHaarClassifierCascade*)cvLoad(dir,NULL,NULL,NULL);
  338. if (!m_pEyeCascade){
  339. m_pHostApi->Debug(FACECAP_INFO, "加载眼睛分类器失败!");
  340. return false;
  341. }
  342. FIGetDir(CASCADE_MOUTH, base_dir, dir);
  343. m_pMouthCascade=(CvHaarClassifierCascade*)cvLoad(dir,NULL,NULL,NULL);
  344. if (!m_pMouthCascade){
  345. m_pHostApi->Debug(FACECAP_INFO, "加载嘴巴分类器失败!");
  346. return false;
  347. }
  348. FIGetDir(CASCADE_NOSE, base_dir, dir);
  349. m_pNoseCascade=(CvHaarClassifierCascade*)cvLoad(dir,NULL,NULL,NULL);
  350. if (!m_pMouthCascade){
  351. m_pHostApi->Debug(FACECAP_INFO, "加载鼻子分类器失败!");
  352. return false;
  353. }
  354. return true;
  355. }
  356. //获取分类器路径
  357. void FIGetDir(const char*CascadeType,const char *base_dir,char*dir)
  358. {
  359. strcpy(dir, m_stFaceConfig.strFaceDataDirPath);
  360. strcat(dir, SPLIT_SLASH_STR);
  361. strcat(dir,CascadeType);
  362. }
  363. //写人脸检测数据
  364. bool WriteAllFaceInfo(CAllFaceInfo faceInfo)
  365. {
  366. #ifdef _WIN32
  367. EnterCriticalSection(&CS);
  368. #else
  369. pthread_mutex_lock(&cs_mutex);
  370. #endif
  371. m_stFaceRstStorage = faceInfo;
  372. #ifdef _WIN32
  373. LeaveCriticalSection(&CS);
  374. #else
  375. pthread_mutex_unlock(&cs_mutex);
  376. #endif
  377. return true;
  378. }
  379. //计算人脸所处的区域
  380. FaceRegionEnum CalcFaceRegion(CvRect FaceRect, int nImgWidth, int nImgHeight)
  381. {
  382. //计算人脸的中心坐标
  383. CvPoint FaceCenter;
  384. FaceCenter.x = FaceRect.x + (int)FaceRect.width/2;
  385. FaceCenter.y = FaceRect.y + (int)FaceRect.height/2;
  386. if(FaceCenter.y < (int)nImgHeight/3)
  387. {
  388. if(FaceCenter.x < (int)nImgWidth/3)
  389. {
  390. return FaceRegionLeftup;
  391. }
  392. else if((FaceCenter.x > (int)nImgWidth/3)&&(FaceCenter.x < (int)nImgWidth*2/3))
  393. {
  394. return FaceRegionUp;
  395. }
  396. else if (FaceCenter.x > (int)nImgWidth*2/3)
  397. {
  398. return FaceRegionRightUP;
  399. }
  400. }
  401. else if((FaceCenter.y > (int)nImgHeight/3)&&(FaceCenter.y < (int)nImgHeight*2/3))
  402. {
  403. if(FaceCenter.x < (int)nImgWidth/3)
  404. {
  405. return FaceRegionLeft;
  406. }
  407. else if((FaceCenter.x > (int)nImgWidth/3)&&(FaceCenter.x < (int)nImgWidth*2/3))
  408. {
  409. return FaceRegionCenter;
  410. }
  411. else if (FaceCenter.x > (int)nImgWidth*2/3)
  412. {
  413. return FaceRegionRight;
  414. }
  415. }
  416. else if(FaceCenter.y > (int)nImgHeight*2/3)
  417. {
  418. if(FaceCenter.x < (int)nImgWidth/3)
  419. {
  420. return FaceRegionLeftDn;
  421. }
  422. else if((FaceCenter.x > (int)nImgWidth/3)&&(FaceCenter.x < (int)nImgWidth*2/3))
  423. {
  424. return FaceRegionDn;
  425. }
  426. else if (FaceCenter.x > (int)nImgWidth*2/3)
  427. {
  428. return FaceRegionRightDn;
  429. }
  430. }
  431. return FaceError;
  432. }
  433. void SwitchDetectCamera()
  434. {
  435. if (NULL != m_pOperatorVideoQueue) {
  436. (m_eCamera == EnvironCamera) ? (m_eCamera = OperatorCamera) : (m_eCamera = EnvironCamera);
  437. }
  438. }
  439. //计算人脸到机具的距离
  440. DistanceEnum CalcFaceDistance(CvRect FaceRect)
  441. {
  442. if(FaceRect.height>(int)(m_nImgHeight/m_stFaceConfig.fOperateFaceSize))
  443. {
  444. return OperateDistance; //可操作距离0.5m
  445. }
  446. else if((FaceRect.height<(int)(m_nImgHeight/m_stFaceConfig.fOperateFaceSize))&&(FaceRect.height>(int)(m_nImgHeight/m_stFaceConfig.fCloseFaceSize)))
  447. {
  448. return CloseDistance; //近端1.5m
  449. }
  450. else
  451. {
  452. return FarDistance; //远端2.5m
  453. }
  454. }
  455. //从共享队列获取图像
  456. bool GetImgFromVideoQueue(Clibvideoqueue* videoqueue)
  457. {
  458. if (videoqueue->GetVideoLens() <= 0){
  459. if (videoqueue == m_pEnvironVideoQueue){
  460. m_pHostApi->Debug(FACECAP_DEBUG, "环境相机图像队列为空");
  461. }
  462. else if (videoqueue == m_pOperatorVideoQueue){
  463. m_pHostApi->Debug(FACECAP_DEBUG, "操作相机图像队列为空");
  464. }
  465. return false;
  466. }
  467. int iSize = videoqueue->GetFrameSize(m_nImgWidth, m_nImgHeight);
  468. if (0 == iSize) {
  469. return false;
  470. }
  471. videoq_frame* videoframe = new videoq_frame;
  472. if (m_pProcessImg == NULL){
  473. m_pProcessImg = cvCreateImage(cvSize(m_nImgWidth, m_nImgHeight), 8, 3); //创建图像
  474. }
  475. else{
  476. if((m_pProcessImg->height != m_nImgHeight)||(m_pProcessImg->width != m_nImgWidth)){
  477. cvReleaseImage(&m_pProcessImg);
  478. m_pProcessImg = NULL;
  479. m_pProcessImg = cvCreateImage(cvSize(m_nImgWidth,m_nImgHeight), 8, 3); //创建图像
  480. }
  481. }
  482. videoframe->data = (unsigned char*)m_pProcessImg->imageData;
  483. bool bGetvideo = videoqueue->GetVideo(videoframe, 0);
  484. if (!bGetvideo){
  485. delete videoframe;
  486. m_pHostApi->Debug(FACECAP_DEBUG, "从队列获取图像失败");
  487. return false;
  488. }
  489. m_nImgWidth = videoframe->width;
  490. m_nImgHeight = videoframe->height;
  491. delete videoframe;
  492. return true;
  493. }
  494. //从指定摄像头取图像数据
  495. //成功时返回true,图像保存在m_pProcessImg结构,同时保存m_nImgWidth, m_nImgHeight值
  496. //失败时返回false
  497. bool GetSpecifiedCameraImage(CameraEnum eCamera)
  498. {
  499. if (eCamera == EnvironCamera){
  500. if (m_pEnvironVideoQueue == NULL){
  501. return false;
  502. }
  503. bool bRslt = GetImgFromVideoQueue(m_pEnvironVideoQueue);
  504. if (!bRslt){
  505. return false;
  506. }
  507. }
  508. else if(eCamera == OperatorCamera){
  509. if (m_pOperatorVideoQueue == NULL){
  510. return false;
  511. }
  512. bool bRslt = GetImgFromVideoQueue(m_pOperatorVideoQueue);
  513. if (!bRslt){
  514. return false;
  515. }
  516. }
  517. return true;
  518. }
  519. //清空上次检测结果
  520. void ClearInspectResult()
  521. {
  522. //清除上一次的记录
  523. m_stAllFaceInfo.nTatolFaceNum = 0;
  524. m_stAllFaceInfo.astFaceInfo[0].stCustomerCover.bIsClearFace = false;
  525. m_stAllFaceInfo.astFaceInfo[0].stCustomerCover.bShowEyes = false;
  526. m_stAllFaceInfo.astFaceInfo[0].stCustomerCover.bShowMouth = false;
  527. m_stAllFaceInfo.astFaceInfo[0].stCustomerCover.bShowNose = false;
  528. m_stAllFaceInfo.astFaceInfo[0].eDistance = UncertainDistance;
  529. m_stAllFaceInfo.astFaceInfo[0].eHeight = UncertainHeight;
  530. m_stAllFaceInfo.astFaceInfo[0].ePose = UncertainPose;
  531. m_stAllFaceInfo.astFaceInfo[0].eSex = UncertainSex;
  532. m_stAllFaceInfo.astFaceInfo[0].eYoungOld = UncertainAge;
  533. m_stAllFaceInfo.astFaceInfo[0].eCamera = OperatorCamera;
  534. for (int i = 1; i < MAX_FACE_NUM; i++){
  535. memset(&m_stAllFaceInfo.astFaceInfo[i], 0, sizeof(CCustomerInfo));
  536. }
  537. }
  538. //在检测到正方形人脸图像中继续查找眼睛,鼻子,嘴巴
  539. //检测到时返回true
  540. //未检测到时返回false
  541. bool FacialFeatureDetect(CvHaarClassifierCascade *pCascade, CvRect *pFaceRect, CvMemStorage* pFaceStorage)
  542. {
  543. //搜索区域图像
  544. CvRect RegionRect;
  545. if (pCascade == m_pEyeCascade)
  546. {
  547. //眼睛
  548. RegionRect.x = pFaceRect->x;
  549. RegionRect.y = pFaceRect->y;
  550. RegionRect.width = pFaceRect->width;
  551. RegionRect.height = (int)pFaceRect->height*1/2;
  552. }
  553. else if (pCascade == m_pNoseCascade)
  554. {
  555. //鼻子
  556. RegionRect.x = (int)pFaceRect->x+(pFaceRect->width)*1/6;
  557. RegionRect.y = (int)pFaceRect->y+pFaceRect->height*1/6;
  558. RegionRect.width = (int)pFaceRect->width*2/3;
  559. RegionRect.height = (int)pFaceRect->height*2/3;
  560. }
  561. else if (pCascade == m_pMouthCascade)
  562. {
  563. //嘴巴
  564. RegionRect.x = (int)pFaceRect->x;
  565. RegionRect.y = (int)pFaceRect->y+pFaceRect->height*1/2;
  566. RegionRect.width = (int)pFaceRect->width;
  567. RegionRect.height = (int)pFaceRect->height*1/2;
  568. }
  569. CvRect RectTemp = cvRect(0,0,0,0);
  570. bool bSetRio = false;
  571. //设置roi
  572. if(m_pProcessImg->roi){
  573. RectTemp.x = m_pProcessImg->roi->xOffset;
  574. RectTemp.y = m_pProcessImg->roi->yOffset;
  575. RectTemp.width = m_pProcessImg->roi->width;
  576. RectTemp.height = m_pProcessImg->roi->height;
  577. RegionRect.x += RectTemp.x;
  578. RegionRect.y += RectTemp.y;
  579. bSetRio = true;
  580. }
  581. cvResetImageROI(m_pProcessImg);
  582. cvSetImageROI(m_pProcessImg, RegionRect);
  583. //脸部特征搜索
  584. CvSeq* pFacialFeatureSeq = cvHaarDetectObjects(m_pProcessImg, pCascade, pFaceStorage, 1.2, 2, CV_HAAR_DO_CANNY_PRUNING, cvSize(10,10));
  585. cvResetImageROI(m_pProcessImg);
  586. if(bSetRio){
  587. cvSetImageROI(m_pProcessImg,RectTemp);
  588. }
  589. if (pFacialFeatureSeq ? pFacialFeatureSeq->total : 0){
  590. return true;
  591. }
  592. else{
  593. return false;
  594. }
  595. }
  596. //计算两个人脸数据的距离
  597. int CalcTwoFaceDistance(CvRect *pSrcRect,CvRect *pDstRect)
  598. {
  599. CvPoint p1;
  600. CvPoint p2;
  601. p1.x = (int)pSrcRect->x+pSrcRect->width/2;
  602. p1.y = (int)pSrcRect->y+pSrcRect->height/2;
  603. p2.x = (int)pDstRect->x+pDstRect->width/2;
  604. p2.y = (int)pDstRect->y+pDstRect->height/2;
  605. return (int)sqrt((double)(p1.x-p2.x)*(p1.x-p2.x) + (double)(p1.y-p2.y)*(p1.y-p2.y));
  606. }
  607. //计算人脸亮度,同时计算人脸亮度调节参数
  608. BrightnessEnum CalcFaceBrightness(IplImage*img, CvRect* FaceRect)
  609. {
  610. cvResetImageROI(img);
  611. cvSetImageROI(img,*FaceRect);
  612. IplImage* FaceImgTmp = cvCreateImage(cvSize(FaceRect->width,FaceRect->height),IPL_DEPTH_8U,3);
  613. cvCopy(img,FaceImgTmp,NULL);
  614. cvResetImageROI(img);
  615. IplImage* FaceImg = cvCreateImage(cvSize(FaceRect->width,FaceRect->height),IPL_DEPTH_8U,1);
  616. cvCvtColor(FaceImgTmp, FaceImg, CV_BGR2GRAY);
  617. cvReleaseImage(&FaceImgTmp);
  618. int aver=0;
  619. unsigned char *data=(uchar*)FaceImg->imageData;
  620. for(int i=0;i<FaceRect->height;i++)
  621. {
  622. for(int j=0;j<FaceRect->width;j++)
  623. {
  624. aver+=data[i*FaceImg->widthStep+j];
  625. }
  626. }
  627. aver=aver/FaceRect->width/FaceRect->height;
  628. cvReleaseImage(&FaceImg);
  629. if (aver>230)
  630. {
  631. m_stBrightAdjParam.fLow = 0.8;
  632. m_stBrightAdjParam.fHigh = 1.0;
  633. m_stBrightAdjParam.fBottom = 0.45;
  634. m_stBrightAdjParam.fTop = 0.75;
  635. m_stBrightAdjParam.fGamma = 1;
  636. return VeryHigh;
  637. }
  638. else if((aver<230)&&(aver>205))
  639. {
  640. m_stBrightAdjParam.fLow = 0.75;
  641. m_stBrightAdjParam.fHigh = 1.0;
  642. m_stBrightAdjParam.fBottom = 0.5;
  643. m_stBrightAdjParam.fTop = 0.8;
  644. m_stBrightAdjParam.fGamma = 1;
  645. return Higher;
  646. }
  647. else if((aver<205)&&(aver>180))
  648. {
  649. m_stBrightAdjParam.fLow = 0.7;
  650. m_stBrightAdjParam.fHigh = 1.0;
  651. m_stBrightAdjParam.fBottom = 0.5;
  652. m_stBrightAdjParam.fTop = 0.8;
  653. m_stBrightAdjParam.fGamma = 1;
  654. return NorMal;
  655. }
  656. else if((aver<180)&&(aver>70))
  657. {
  658. m_stBrightAdjParam.fLow = 0.0;
  659. m_stBrightAdjParam.fHigh = 0.0;
  660. m_stBrightAdjParam.fBottom = 0.0;
  661. m_stBrightAdjParam.fTop = 0.0;
  662. m_stBrightAdjParam.fGamma = 0.0;
  663. return NorMal;
  664. }
  665. else if((aver<70)&&(aver>50))
  666. {
  667. m_stBrightAdjParam.fLow = 0;
  668. m_stBrightAdjParam.fHigh = 0.3;
  669. m_stBrightAdjParam.fBottom = 0.15;
  670. m_stBrightAdjParam.fTop = 0.55;
  671. m_stBrightAdjParam.fGamma = 1;
  672. return NorMal;
  673. }
  674. else if((aver<50)&&(aver>30))
  675. {
  676. m_stBrightAdjParam.fLow = 0;
  677. m_stBrightAdjParam.fHigh = 0.25;
  678. m_stBrightAdjParam.fBottom = 0.25;
  679. m_stBrightAdjParam.fTop = 0.65;
  680. m_stBrightAdjParam.fGamma = 1;
  681. return Lower;
  682. }
  683. else
  684. {
  685. m_stBrightAdjParam.fLow = 0;
  686. m_stBrightAdjParam.fHigh = 0.2;
  687. m_stBrightAdjParam.fBottom = 0.25;
  688. m_stBrightAdjParam.fTop = 0.65;
  689. m_stBrightAdjParam.fGamma = 1;
  690. return VeryLow;
  691. }
  692. }
  693. //计算人脸亮度调节参数
  694. bool CalcBrightAdjParam(IplImage*img, CvRect* FaceRect)
  695. {
  696. cvResetImageROI(img);
  697. cvSetImageROI(img,*FaceRect);
  698. IplImage* FaceImgTmp = cvCreateImage(cvSize(FaceRect->width,FaceRect->height),IPL_DEPTH_8U,3);
  699. cvCopy(img,FaceImgTmp,NULL);
  700. cvResetImageROI(img);
  701. IplImage* FaceImg = cvCreateImage(cvSize(FaceRect->width,FaceRect->height),IPL_DEPTH_8U,1);
  702. cvCvtColor(FaceImgTmp, FaceImg, CV_BGR2GRAY);
  703. cvReleaseImage(&FaceImgTmp);
  704. int aver=0;
  705. unsigned char *data=(uchar*)FaceImg->imageData;
  706. for(int i=0;i<FaceRect->height;i++)
  707. {
  708. for(int j=0;j<FaceRect->width;j++)
  709. {
  710. aver+=data[i*FaceImg->widthStep+j];
  711. }
  712. }
  713. aver=aver/FaceRect->width/FaceRect->height;
  714. if (aver>230)
  715. {
  716. m_stBrightAdjParam.fLow = 0.8;
  717. m_stBrightAdjParam.fHigh = 1.0;
  718. m_stBrightAdjParam.fBottom = 0.45;
  719. m_stBrightAdjParam.fTop = 0.75;
  720. m_stBrightAdjParam.fGamma = 1;
  721. }
  722. else if((aver<230)&&(aver>205))
  723. {
  724. m_stBrightAdjParam.fLow = 0.75;
  725. m_stBrightAdjParam.fHigh = 1.0;
  726. m_stBrightAdjParam.fBottom = 0.5;
  727. m_stBrightAdjParam.fTop = 0.8;
  728. m_stBrightAdjParam.fGamma = 1;
  729. }
  730. else if((aver<205)&&(aver>180))
  731. {
  732. m_stBrightAdjParam.fLow = 0.7;
  733. m_stBrightAdjParam.fHigh = 1.0;
  734. m_stBrightAdjParam.fBottom = 0.5;
  735. m_stBrightAdjParam.fTop = 0.8;
  736. m_stBrightAdjParam.fGamma = 1;
  737. }
  738. else if((aver<70)&&(aver>60))
  739. {
  740. m_stBrightAdjParam.fLow = 0;
  741. m_stBrightAdjParam.fHigh = 0.3;
  742. m_stBrightAdjParam.fBottom = 0.15;
  743. m_stBrightAdjParam.fTop = 0.55;
  744. m_stBrightAdjParam.fGamma = 1;
  745. }
  746. else if((aver<60)&&(aver>30))
  747. {
  748. m_stBrightAdjParam.fLow = 0;
  749. m_stBrightAdjParam.fHigh = 0.25;
  750. m_stBrightAdjParam.fBottom = 0.25;
  751. m_stBrightAdjParam.fTop = 0.65;
  752. m_stBrightAdjParam.fGamma = 1;
  753. }
  754. else
  755. {
  756. m_stBrightAdjParam.fLow = 0;
  757. m_stBrightAdjParam.fHigh = 0.2;
  758. m_stBrightAdjParam.fBottom = 0.25;
  759. m_stBrightAdjParam.fTop = 0.65;
  760. m_stBrightAdjParam.fGamma = 1;
  761. }
  762. cvReleaseImage(&FaceImg);
  763. return true;
  764. }
  765. //人脸检测,获取指定摄像头的图像进行全局检测,比较当前人脸和主人脸信息,将更居中人脸信息保存为主人脸。
  766. //检测到有人时,返回ture
  767. //没检测到有人时,返回false
  768. bool FaceDetectWithSpecifiedCamera(CameraEnum eCamera)
  769. {
  770. if (!GetSpecifiedCameraImage(eCamera)){
  771. m_pHostApi->Debug(FACECAP_DEBUG, "获取图像失败");
  772. return false;
  773. }
  774. CCustomerInfo UserFaceTemp;
  775. int nFaceSerial = 1;
  776. memset(&UserFaceTemp, 0, sizeof(CCustomerInfo));
  777. CvRect* pFaceRect = NULL; //人脸矩形
  778. int nPreFaceNum = 0;
  779. cvResetImageROI(m_pProcessImg);
  780. //内存初始化
  781. if (m_pFaceStorage){
  782. m_pFaceStorage = cvCreateMemStorage(0);
  783. cvClearMemStorage(m_pFaceStorage);
  784. }
  785. else{
  786. m_pFaceStorage = cvCreateMemStorage(0);
  787. }
  788. //人脸搜索
  789. if (m_pFaceCascade == NULL){
  790. ClearInspectResult();
  791. return false;
  792. }
  793. int isize = (int)(m_nImgHeight/m_stFaceConfig.fDetectFaceSize);
  794. pfaceSeq = cvHaarDetectObjects(m_pProcessImg, m_pFaceCascade, m_pFaceStorage, 1.1, 3, CV_HAAR_DO_CANNY_PRUNING, cvSize(isize, isize));
  795. if (!pfaceSeq || !pfaceSeq->total){
  796. cvReleaseMemStorage(&pfaceSeq->storage);
  797. pfaceSeq = NULL;
  798. ClearInspectResult();
  799. return false;
  800. }
  801. else
  802. {
  803. //保存上次人脸矩形,对当前人脸位置进行微调防止跳动
  804. nPreFaceNum = m_stAllFaceInfo.nTatolFaceNum;
  805. for(int num = 0; num < m_stAllFaceInfo.nTatolFaceNum; num++){
  806. m_PreFaceRect[num] = m_stAllFaceInfo.astFaceInfo[num].stRegion.stFaceRect;
  807. }
  808. //清除上一次的记录
  809. ClearInspectResult();
  810. }
  811. for(int i = 0; i < (pfaceSeq ? pfaceSeq->total : 0)&&(i < MAX_FACE_NUM); i++)
  812. {
  813. m_stAllFaceInfo.nTatolFaceNum++;
  814. //获取脸部矩形
  815. pFaceRect = (CvRect*)cvGetSeqElem(pfaceSeq, i);
  816. //如果是前端检测则需要特征检测,如果是坐席则不需检测
  817. if (m_stFaceConfig.nServersType == 0)
  818. {
  819. //找眼睛
  820. m_stAllFaceInfo.astFaceInfo[nFaceSerial].stCustomerCover.bShowEyes = FacialFeatureDetect(m_pEyeCascade, pFaceRect, m_pFaceStorage);
  821. //找鼻子
  822. m_stAllFaceInfo.astFaceInfo[nFaceSerial].stCustomerCover.bShowNose = FacialFeatureDetect(m_pNoseCascade, pFaceRect, m_pFaceStorage);
  823. //找嘴巴
  824. m_stAllFaceInfo.astFaceInfo[nFaceSerial].stCustomerCover.bShowMouth = FacialFeatureDetect(m_pMouthCascade, pFaceRect, m_pFaceStorage);
  825. }
  826. else
  827. {
  828. //找眼睛
  829. m_stAllFaceInfo.astFaceInfo[nFaceSerial].stCustomerCover.bShowEyes = false;
  830. //找鼻子
  831. m_stAllFaceInfo.astFaceInfo[nFaceSerial].stCustomerCover.bShowNose = false;
  832. //找嘴巴
  833. m_stAllFaceInfo.astFaceInfo[nFaceSerial].stCustomerCover.bShowMouth = false;
  834. }
  835. if(!(m_stAllFaceInfo.astFaceInfo[nFaceSerial].stCustomerCover.bShowEyes||
  836. m_stAllFaceInfo.astFaceInfo[nFaceSerial].stCustomerCover.bShowNose||
  837. m_stAllFaceInfo.astFaceInfo[nFaceSerial].stCustomerCover.bShowMouth))
  838. {
  839. m_stAllFaceInfo.astFaceInfo[nFaceSerial].stCustomerCover.bIsClearFace = false;
  840. }
  841. else
  842. {
  843. m_stAllFaceInfo.astFaceInfo[nFaceSerial].stCustomerCover.bIsClearFace = true;
  844. }
  845. //计算当前人脸位置,如果当前人脸位置与上次人脸位置小于偏移量则取上次人脸位置,防止人脸图像跳变
  846. for (int num = 0; num < nPreFaceNum; num++)
  847. {
  848. if ((abs(pFaceRect->x - m_PreFaceRect[num].x) < m_stFaceConfig.nFaceSizeOffset)
  849. && (abs(pFaceRect->y - m_PreFaceRect[num].y) < m_stFaceConfig.nFaceSizeOffset)
  850. && (abs(pFaceRect->width - m_PreFaceRect[num].width) < (m_stFaceConfig.nFaceSizeOffset*2))
  851. && (abs(pFaceRect->height - m_PreFaceRect[num].height) < (m_stFaceConfig.nFaceSizeOffset*2)))
  852. {
  853. pFaceRect->x = m_PreFaceRect[num].x;
  854. pFaceRect->y = m_PreFaceRect[num].y;
  855. pFaceRect->width = m_PreFaceRect[num].width;
  856. pFaceRect->height = m_PreFaceRect[num].height;
  857. }
  858. }
  859. //搜索到人脸,计算人脸数据
  860. m_stAllFaceInfo.astFaceInfo[nFaceSerial].stRegion.stFaceRect = *pFaceRect;
  861. m_stAllFaceInfo.astFaceInfo[nFaceSerial].stRegion.eRegion = CalcFaceRegion(*pFaceRect,m_nImgWidth,m_nImgHeight);
  862. m_stAllFaceInfo.astFaceInfo[nFaceSerial].eDistance = CalcFaceDistance(*pFaceRect);
  863. m_stAllFaceInfo.astFaceInfo[nFaceSerial].eCamera = eCamera;
  864. //获取UUID
  865. if (m_stAllFaceInfo.astFaceInfo[nFaceSerial].FaceID == 0)
  866. {
  867. m_stAllFaceInfo.astFaceInfo[nFaceSerial].FaceID = m_pHostApi->GenerateUUID();
  868. }
  869. //截取人脸图像,放大截取区域,截取半身头像
  870. CalcUpbodyRegion(pFaceRect);
  871. m_stAllFaceInfo.astFaceInfo[nFaceSerial].stRegion.stUpperBodyRect = *pFaceRect;
  872. //当前数据的区域和距离,temp数据的区域和距离
  873. FaceRegionEnum CurRegion = m_stAllFaceInfo.astFaceInfo[nFaceSerial].stRegion.eRegion;
  874. DistanceEnum CurDistance = m_stAllFaceInfo.astFaceInfo[nFaceSerial].eDistance;
  875. FaceRegionEnum TempRegion = UserFaceTemp.stRegion.eRegion;
  876. DistanceEnum TempDistance = UserFaceTemp.eDistance;
  877. int TempPointDistance = CalcTwoFaceDistance(&UserFaceTemp.stRegion.stFaceRect, &m_stAllFaceInfo.astFaceInfo[0].stRegion.stFaceRect);
  878. int CurPointDistance = CalcTwoFaceDistance(&m_stAllFaceInfo.astFaceInfo[nFaceSerial].stRegion.stFaceRect, &m_stAllFaceInfo.astFaceInfo[0].stRegion.stFaceRect);
  879. //计算当前操作者的人脸区域
  880. if(//如果temp数据为0,则更新temp
  881. ((TempRegion == FaceError)&&(TempDistance == UncertainDistance)) ||
  882. //如果当前数据在中心区域,temp数据也在中心区域,且当前距离比temp数据更近,则更新temp
  883. ((CurRegion == FaceRegionCenter)&&(TempRegion == FaceRegionCenter)&&(CurDistance < TempDistance))||
  884. //如果当前数据不在中心区域,temp数据也不在中心区域,且当前数据比temp数据更近。则更新temp
  885. ((TempRegion != FaceRegionCenter)&&(CurRegion != FaceRegionCenter)&&(CurDistance < TempDistance))||
  886. //如果当前数据在中心区域,temp数据不在中心区域,且当前距离更近,则更新temp
  887. ((CurRegion == FaceRegionCenter)&&(TempRegion != FaceRegionCenter)&&(CurDistance < TempDistance))||
  888. //如果当前数据不在中心区域,temp数据在中心区域,且当前数据距离更近,则更新temp
  889. ((CurRegion != FaceRegionCenter)&&(TempRegion == FaceRegionCenter)&&(CurDistance < TempDistance))||
  890. //如果当前数据不在中心区域,temp数据也不在中心区域,且距离一样,若当前数据更靠近历史数据,则当前数据作为temp
  891. ((TempRegion != FaceRegionCenter)&&(CurRegion != FaceRegionCenter)&&(CurDistance == TempDistance)&&(CurPointDistance < TempPointDistance)))
  892. {
  893. if((TempRegion != FaceError)&&(TempDistance != UncertainDistance))
  894. {
  895. CCustomerInfo Temp = UserFaceTemp;
  896. UserFaceTemp = m_stAllFaceInfo.astFaceInfo[nFaceSerial];
  897. m_stAllFaceInfo.astFaceInfo[nFaceSerial] = Temp;
  898. nFaceSerial++;
  899. }
  900. else
  901. {
  902. UserFaceTemp = m_stAllFaceInfo.astFaceInfo[nFaceSerial];
  903. memset(&m_stAllFaceInfo.astFaceInfo[nFaceSerial],0,sizeof(CCustomerInfo));
  904. }
  905. }
  906. else
  907. {
  908. nFaceSerial++;
  909. }
  910. }
  911. if((UserFaceTemp.stRegion.eRegion != FaceError)&&(UserFaceTemp.eDistance != UncertainDistance))
  912. {
  913. m_stAllFaceInfo.astFaceInfo[0].stRegion.stFaceRect = UserFaceTemp.stRegion.stFaceRect;
  914. m_stAllFaceInfo.astFaceInfo[0].eDistance = UserFaceTemp.eDistance;
  915. m_stAllFaceInfo.astFaceInfo[0].stRegion.eRegion = UserFaceTemp.stRegion.eRegion;
  916. m_stAllFaceInfo.astFaceInfo[0].stRegion.stUpperBodyRect = UserFaceTemp.stRegion.stUpperBodyRect;
  917. m_stAllFaceInfo.astFaceInfo[0].eCamera = UserFaceTemp.eCamera;
  918. m_stAllFaceInfo.astFaceInfo[0].stCustomerCover = UserFaceTemp.stCustomerCover;
  919. //计算人脸亮度
  920. //if (m_stFaceConfig.nServersType == 0)
  921. //{
  922. // m_stAllFaceInfo.astFaceInfo[0].eBrightness = CalcFaceBrightness(m_pProcessImg,&m_stAllFaceInfo.astFaceInfo[0].stRegion.stFaceRect);
  923. //}
  924. }
  925. //清空存储区
  926. cvResetImageROI(m_pProcessImg);
  927. if (pfaceSeq != NULL){
  928. cvReleaseMemStorage(&pfaceSeq->storage);
  929. pfaceSeq = NULL;
  930. }
  931. for(int i = 0; i < MAX_FACE_NUM; i++){
  932. m_PreFaceRect[i] = cvRect(0,0,0,0);
  933. }
  934. if(m_stAllFaceInfo.nTatolFaceNum == 0){
  935. ClearInspectResult();
  936. return false;
  937. }
  938. else{
  939. return true;
  940. }
  941. }
  942. bool bIsRectValid(int iWidth, int iHeight, CvRect rect)
  943. {
  944. bool bRet = false;
  945. if ((0 != rect.width) && (0 != rect.height) && (iWidth >= rect.x + rect.width) && (iHeight >= rect.y + rect.height)) {
  946. bRet = true;
  947. }
  948. return bRet;
  949. }
  950. //人脸检测,对指定摄像头的指定区域进行全局检测,比较当前人脸和主人脸信息,将更居中人脸信息保存为主人脸。
  951. //检测到有人时,返回ture
  952. //没检测到有人时,返回false
  953. bool FaceDetectWithSpecifiedCameraRegion(CameraEnum eCamera, CvRect rect)
  954. {
  955. if (!GetSpecifiedCameraImage(eCamera)){
  956. return false;
  957. }
  958. CvMemStorage* pFaceStorage = NULL;
  959. if (eCamera == EnvironCamera){
  960. pFaceStorage = m_pFaceStorage;
  961. }
  962. else{
  963. pFaceStorage = m_pFaceStorage;
  964. }
  965. CCustomerInfo UserFaceTemp;
  966. CCustomerInfo astFaceTemp;
  967. memset(&astFaceTemp,0,sizeof(CCustomerInfo));
  968. memset(&UserFaceTemp,0,sizeof(CCustomerInfo));
  969. CvRect* pFaceRect = NULL; //人脸矩形
  970. cvResetImageROI(m_pProcessImg);
  971. if (bIsRectValid(m_pProcessImg->width, m_pProcessImg->height, rect)) {
  972. cvSetImageROI(m_pProcessImg, rect);
  973. }
  974. //内存初始化
  975. if (pFaceStorage){
  976. pFaceStorage = cvCreateMemStorage(0);
  977. cvClearMemStorage(pFaceStorage);
  978. }
  979. else{
  980. pFaceStorage = cvCreateMemStorage(0);
  981. }
  982. //人脸搜索
  983. if (m_pFaceCascade == NULL){
  984. return false;
  985. }
  986. int size = (int)m_nImgHeight/m_stFaceConfig.fDetectFaceSize;
  987. pfaceSeq = cvHaarDetectObjects(m_pProcessImg, m_pFaceCascade, pFaceStorage, 1.2, 3, CV_HAAR_DO_CANNY_PRUNING, cvSize(size,size));
  988. if (!pfaceSeq || !pfaceSeq->total)
  989. {
  990. cvReleaseMemStorage(&pfaceSeq->storage);
  991. pfaceSeq = NULL;
  992. return false;
  993. }
  994. for(int i = 0; i < (pfaceSeq?pfaceSeq->total:0)&&(i<MAX_FACE_NUM); i++)
  995. {
  996. //获取脸部矩形
  997. pFaceRect = (CvRect*)cvGetSeqElem(pfaceSeq, i);
  998. //如果是前端检测则需要特征检测,如果是坐席则不需检测
  999. if (m_stFaceConfig.nServersType == 0)
  1000. {
  1001. //找眼睛
  1002. astFaceTemp.stCustomerCover.bShowEyes = FacialFeatureDetect(m_pEyeCascade, pFaceRect, pFaceStorage);
  1003. //找鼻子
  1004. astFaceTemp.stCustomerCover.bShowNose = FacialFeatureDetect(m_pNoseCascade, pFaceRect, pFaceStorage);
  1005. //找嘴巴
  1006. astFaceTemp.stCustomerCover.bShowMouth = FacialFeatureDetect(m_pMouthCascade, pFaceRect, pFaceStorage);
  1007. }
  1008. else
  1009. {
  1010. //找眼睛
  1011. astFaceTemp.stCustomerCover.bShowEyes = false;
  1012. //找鼻子
  1013. astFaceTemp.stCustomerCover.bShowNose = false;
  1014. //找嘴巴
  1015. astFaceTemp.stCustomerCover.bShowMouth = false;
  1016. }
  1017. if(!(astFaceTemp.stCustomerCover.bShowEyes||astFaceTemp.stCustomerCover.bShowNose||astFaceTemp.stCustomerCover.bShowMouth))
  1018. {
  1019. astFaceTemp.stCustomerCover.bIsClearFace = false;
  1020. }
  1021. else
  1022. {
  1023. astFaceTemp.stCustomerCover.bIsClearFace = true;
  1024. }
  1025. //计算当前人脸位置如果当前人脸位置与上次人脸位置小于偏移量则取上次人脸位置,防止人脸图像跳变
  1026. //坐标变换
  1027. pFaceRect->x = pFaceRect->x+rect.x;
  1028. pFaceRect->y = pFaceRect->y+rect.y;
  1029. if ((abs(pFaceRect->x - m_stAllFaceInfo.astFaceInfo[0].stRegion.stFaceRect.x) < m_stFaceConfig.nFaceSizeOffset)
  1030. &&(abs(pFaceRect->y-m_stAllFaceInfo.astFaceInfo[0].stRegion.stFaceRect.y) < m_stFaceConfig.nFaceSizeOffset)
  1031. &&(abs(pFaceRect->width-m_stAllFaceInfo.astFaceInfo[0].stRegion.stFaceRect.width) < (m_stFaceConfig.nFaceSizeOffset*2))
  1032. &&(abs(pFaceRect->height-m_stAllFaceInfo.astFaceInfo[0].stRegion.stFaceRect.height) < (m_stFaceConfig.nFaceSizeOffset*2)))
  1033. {
  1034. pFaceRect->x = m_stAllFaceInfo.astFaceInfo[0].stRegion.stFaceRect.x;
  1035. pFaceRect->y = m_stAllFaceInfo.astFaceInfo[0].stRegion.stFaceRect.y;
  1036. pFaceRect->width = m_stAllFaceInfo.astFaceInfo[0].stRegion.stFaceRect.width;
  1037. pFaceRect->height = m_stAllFaceInfo.astFaceInfo[0].stRegion.stFaceRect.height;
  1038. }
  1039. //搜索到人脸,计算人脸数据
  1040. astFaceTemp.stRegion.stFaceRect = *pFaceRect;
  1041. astFaceTemp.stRegion.eRegion = CalcFaceRegion(*pFaceRect,m_nImgWidth,m_nImgHeight);
  1042. astFaceTemp.eDistance = CalcFaceDistance(*pFaceRect);
  1043. astFaceTemp.eCamera = eCamera;
  1044. //截取人脸图像,放大截取区域,截取半身头像
  1045. CalcUpbodyRegion(pFaceRect);
  1046. astFaceTemp.stRegion.stUpperBodyRect = *pFaceRect;
  1047. //当前数据的区域和距离,temp数据的区域和距离
  1048. FaceRegionEnum CurRegion = astFaceTemp.stRegion.eRegion;
  1049. DistanceEnum CurDistance = astFaceTemp.eDistance;
  1050. FaceRegionEnum TempRegion = UserFaceTemp.stRegion.eRegion;
  1051. DistanceEnum TempDistance = UserFaceTemp.eDistance;
  1052. int TempPointDistance = CalcTwoFaceDistance(&UserFaceTemp.stRegion.stFaceRect, &m_stAllFaceInfo.astFaceInfo[0].stRegion.stFaceRect);
  1053. int CurPointDistance = CalcTwoFaceDistance(&astFaceTemp.stRegion.stFaceRect, &m_stAllFaceInfo.astFaceInfo[0].stRegion.stFaceRect);
  1054. //计算当前操作者的人脸区域
  1055. if(//如果temp数据为0,则更新temp
  1056. ((TempRegion == FaceError)&&(TempDistance == UncertainDistance)) ||
  1057. //如果当前数据在中心区域,temp数据也在中心区域,且当前距离比temp数据更近,则更新temp
  1058. ((CurRegion == FaceRegionCenter)&&(TempRegion == FaceRegionCenter)&&(CurDistance < TempDistance))||
  1059. //如果当前数据不在中心区域,temp数据也不在中心区域,且当前数据比temp数据更近。则更新temp
  1060. ((TempRegion != FaceRegionCenter)&&(CurRegion != FaceRegionCenter)&&(CurDistance < TempDistance))||
  1061. //如果当前数据在中心区域,temp数据不在中心区域,且当前距离更近,则更新temp
  1062. ((CurRegion == FaceRegionCenter)&&(TempRegion != FaceRegionCenter)&&(CurDistance < TempDistance))||
  1063. //如果当前数据不在中心区域,temp数据在中心区域,且当前数据距离更近,则更新temp
  1064. ((CurRegion != FaceRegionCenter)&&(TempRegion == FaceRegionCenter)&&(CurDistance < TempDistance))||
  1065. //如果当前数据不在中心区域,temp数据也不在中心区域,且距离一样,若当前数据更靠近历史数据,则当前数据作为temp
  1066. ((TempRegion != FaceRegionCenter)&&(CurRegion != FaceRegionCenter)&&(CurDistance == TempDistance)&&(CurPointDistance < TempPointDistance)))
  1067. {
  1068. UserFaceTemp = astFaceTemp;
  1069. memset(&astFaceTemp, 0, sizeof(CCustomerInfo));
  1070. }
  1071. }
  1072. if((UserFaceTemp.stRegion.eRegion != FaceError)&&(UserFaceTemp.eDistance != UncertainDistance))
  1073. {
  1074. m_stAllFaceInfo.astFaceInfo[0].stRegion.stFaceRect = UserFaceTemp.stRegion.stFaceRect;
  1075. m_stAllFaceInfo.astFaceInfo[0].eDistance = UserFaceTemp.eDistance;
  1076. m_stAllFaceInfo.astFaceInfo[0].stRegion.eRegion = UserFaceTemp.stRegion.eRegion;
  1077. m_stAllFaceInfo.astFaceInfo[0].stRegion.stUpperBodyRect = UserFaceTemp.stRegion.stUpperBodyRect;
  1078. m_stAllFaceInfo.astFaceInfo[0].eCamera = UserFaceTemp.eCamera;
  1079. m_stAllFaceInfo.astFaceInfo[0].stCustomerCover = UserFaceTemp.stCustomerCover;
  1080. //计算人脸亮度
  1081. //if (m_stFaceConfig.nServersType == 0){
  1082. // m_stAllFaceInfo.astFaceInfo[0].eBrightness = CalcFaceBrightness(m_pProcessImg,&m_stAllFaceInfo.astFaceInfo[0].stRegion.stFaceRect);
  1083. //}
  1084. }
  1085. //清空存储区
  1086. if (pfaceSeq != NULL){
  1087. cvReleaseMemStorage(&pfaceSeq->storage);
  1088. pfaceSeq = NULL;
  1089. }
  1090. cvResetImageROI(m_pProcessImg);
  1091. return true;
  1092. }
  1093. //调整图像亮度
  1094. bool AdjustImgBrightness(char* src,int width,int height,CBrightAdjParam stAdjParam,int ImgColorType = RGB_IMG)
  1095. {
  1096. if(stAdjParam.fLow<0&&stAdjParam.fLow>1&&stAdjParam.fHigh<0&&stAdjParam.fHigh>1
  1097. &&stAdjParam.fBottom<0&&stAdjParam.fBottom>1&&stAdjParam.fTop<0&&stAdjParam.fTop>1&& stAdjParam.fLow>stAdjParam.fHigh)
  1098. return false;
  1099. if (((stAdjParam.fHigh-0.0)<0.001)&&((stAdjParam.fTop-0.0)<0.001))
  1100. return false;
  1101. double low2 = stAdjParam.fLow*255;
  1102. double high2 = stAdjParam.fHigh*255;
  1103. double bottom2 = stAdjParam.fBottom*255;
  1104. double top2 = stAdjParam.fTop*255;
  1105. double err_in = high2 - low2;
  1106. double err_out = top2 - bottom2;
  1107. int x,y;
  1108. double val;
  1109. int nChannels = 0;
  1110. if (ImgColorType = RGB_IMG)
  1111. {
  1112. nChannels = 3;
  1113. }
  1114. else
  1115. {
  1116. nChannels = 1;
  1117. }
  1118. // intensity transform
  1119. for( y = 0; y < height; y++)
  1120. {
  1121. for (x = 0; x < width*3; x++)
  1122. {
  1123. val = ((uchar*)(src + width*nChannels*y))[x];
  1124. val = pow((val - low2)/err_in, stAdjParam.fGamma) * err_out + bottom2;
  1125. if(val>255)
  1126. val=255;
  1127. if(val<0)
  1128. val=0; // Make sure src is in the range [low,high]
  1129. ((uchar*)(src + width*nChannels*y))[x] = (uchar) val;
  1130. }
  1131. }
  1132. return true;
  1133. }
  1134. //形态学结构元素的映射
  1135. IplConvKernel* IpStructuringElementMap(IplConvKernel* se)
  1136. {
  1137. CvMat *mat = cvCreateMat( se->nRows, se->nCols, CV_32SC1);
  1138. memcpy(mat->data.i, se->values, sizeof(int) * se->nRows * se->nCols );
  1139. cvFlip(mat, NULL, -1);
  1140. IplConvKernel* semap = cvCreateStructuringElementEx( se->nCols, se->nRows,
  1141. se->nCols-se->anchorX-1, se->nRows-se->anchorY-1, 0, NULL );
  1142. semap->nShiftR = se->nShiftR;
  1143. memcpy( semap->values, mat->data.i, sizeof(int) * se->nRows * se->nCols );
  1144. cvReleaseMat(&mat);
  1145. return semap;
  1146. }
  1147. //形态学闭运算
  1148. void IpMorpClose(const IplImage*src,IplImage* dst,IplConvKernel* se=NULL, int iterations=1)
  1149. {
  1150. cvDilate(src,dst,se,iterations );
  1151. IplConvKernel* semap = IpStructuringElementMap(se);
  1152. cvErode(src,dst,semap,iterations );
  1153. cvReleaseStructuringElement(&semap);
  1154. }
  1155. //计算半身头像区域,按4:3比例剪辑,防止超出图像界限
  1156. void CalcUpbodyRegion(CvRect* pFaceRect)
  1157. {
  1158. if (m_nImgWidth > m_nImgHeight)
  1159. {
  1160. pFaceRect->y = ((pFaceRect->y-pFaceRect->height*1/3)<0)?0:(int)(pFaceRect->y-pFaceRect->height*1/3);
  1161. pFaceRect->height = ((pFaceRect->height*19/12+pFaceRect->y)>m_nImgHeight)?(int)(m_nImgHeight-pFaceRect->y):(int)(pFaceRect->height*19/12);
  1162. if ((int)(pFaceRect->x+pFaceRect->width/2-pFaceRect->height*4/6)<0)
  1163. {
  1164. pFaceRect->x = 0;
  1165. }
  1166. else if ((pFaceRect->x+pFaceRect->width/2+pFaceRect->height*4/6)>m_nImgWidth)
  1167. {
  1168. pFaceRect->x = (int)(m_nImgWidth-pFaceRect->height*4/3);
  1169. }
  1170. else
  1171. {
  1172. pFaceRect->x=(int)(pFaceRect->x+pFaceRect->width/2-pFaceRect->height*4/6);
  1173. }
  1174. pFaceRect->width = pFaceRect->height*4/3;
  1175. }
  1176. else
  1177. {
  1178. pFaceRect->x = ((pFaceRect->x-pFaceRect->width*7/24)<0)?0:(int)(pFaceRect->x-pFaceRect->width*7/24);
  1179. pFaceRect->width = ((pFaceRect->width*19/12+pFaceRect->x)>m_nImgWidth)?(int)(m_nImgWidth-pFaceRect->x):(int)(pFaceRect->width*19/12);
  1180. if ((int)(pFaceRect->y+pFaceRect->height/2-pFaceRect->width*3/8)<0)
  1181. {
  1182. pFaceRect->y = 0;
  1183. }
  1184. else if ((pFaceRect->y+pFaceRect->height/2+pFaceRect->width*3/8)>m_nImgHeight)
  1185. {
  1186. pFaceRect->y = (int)(m_nImgHeight-pFaceRect->width*3/8);
  1187. }
  1188. else
  1189. {
  1190. pFaceRect->y = (int)(pFaceRect->y+pFaceRect->height/2-pFaceRect->width*3/8);
  1191. }
  1192. pFaceRect->height = pFaceRect->width*3/4;
  1193. }
  1194. }
  1195. //按指定尺寸对图像进行全局搜索
  1196. //检测到有人时,返回ture,更新人脸状态,同时发送人脸状态信息,保存检测到的人脸数,最靠近机器那人的人脸位置和大小信息,当前摄像头信息,用于其他分类器做进一步检测
  1197. //没检测到有人时,返回false
  1198. bool FaceSearchWithSpecifiedSize(uint32_t nFaceLimit)
  1199. {
  1200. int nFaceNum = 0;
  1201. int nCurafaceSerial = 0;
  1202. //人脸搜索
  1203. if (NULL == m_pFaceCascade){
  1204. return false;
  1205. }
  1206. cvResetImageROI(m_pProcessImg);
  1207. CvRect* pFaceRect = NULL; //人脸矩形
  1208. //内存初始化
  1209. if (m_pFaceStorage){
  1210. m_pFaceStorage = cvCreateMemStorage(0);
  1211. cvClearMemStorage(m_pFaceStorage);
  1212. }
  1213. else{
  1214. m_pFaceStorage = cvCreateMemStorage(0);
  1215. }
  1216. pfaceSeq = cvHaarDetectObjects(m_pProcessImg, m_pFaceCascade, m_pFaceStorage, 1.2, 3, CV_HAAR_DO_CANNY_PRUNING, cvSize(nFaceLimit, nFaceLimit));
  1217. if (pfaceSeq && pfaceSeq->total)
  1218. {
  1219. for(int i = 0; i < (pfaceSeq?pfaceSeq->total:0); i++)
  1220. {
  1221. nFaceNum++;
  1222. //获取脸部矩形
  1223. CvRect* pFaceRect = (CvRect*)cvGetSeqElem(pfaceSeq, i);
  1224. //如果发现有人脸到达靠近区域,置有人靠近状态
  1225. if((pFaceRect->height >= (int)(m_nImgHeight/m_stFaceConfig.fCloseFaceSize))&&(pFaceRect->height <= (int)(m_nImgHeight/m_stFaceConfig.fOperateFaceSize)))
  1226. {
  1227. if((m_eMonitorState == NoBody) || (m_eMonitorState == SomebodyFar))
  1228. {
  1229. nCurafaceSerial = i;
  1230. m_eMonitorState = SomebodyClose; //进入有人靠近状态
  1231. }
  1232. m_pHostEvent->GenerateMonitorEvent(Close); //产生有人靠近事件
  1233. }
  1234. else if (pFaceRect->height >= (int)(m_nImgHeight/m_stFaceConfig.fOperateFaceSize))
  1235. {
  1236. if(m_eMonitorState != SomebodyOperate)
  1237. {
  1238. nCurafaceSerial = i;
  1239. m_eMonitorState = SomebodyOperate; //进入有人操作状态
  1240. }
  1241. m_pHostEvent->GenerateMonitorEvent(EnterOperate); //产生有人进入操作距离事件
  1242. }
  1243. else
  1244. {
  1245. if(m_eMonitorState == NoBody)
  1246. {
  1247. nCurafaceSerial = i;
  1248. m_eMonitorState = SomebodyFar; //进入远距离有人状态
  1249. }
  1250. else
  1251. {
  1252. m_eMonitorState = SomebodyFar; //进入远距离有人状态
  1253. }
  1254. m_pHostEvent->GenerateMonitorEvent(Appear); //产生有人出现事件
  1255. }
  1256. }
  1257. CvRect* pFaceRect = (CvRect*)cvGetSeqElem(pfaceSeq, nCurafaceSerial);
  1258. //截取人脸图像,放大截取区域,截取半身头像
  1259. CalcUpbodyRegion(pFaceRect);
  1260. //保存半身头像坐标
  1261. m_stAllFaceInfo.astFaceInfo[0].stRegion.stUpperBodyRect = *pFaceRect;
  1262. m_stAllFaceInfo.astFaceInfo[0].eCamera = m_eCamera;
  1263. }
  1264. else {
  1265. #ifdef DEVOPS_ON_PRD
  1266. #else
  1267. if (EnvironCamera == m_eCamera) {
  1268. m_pHostEvent->GenerateMonitorEvent(video_monitor_event_type::NoDetectBody, "上摄像头未检测到人脸"); //上摄像头未检测到人脸
  1269. }
  1270. else if(OperatorCamera == m_eCamera){
  1271. m_pHostEvent->GenerateMonitorEvent(video_monitor_event_type::NoDetectBody, "下摄像头未检测到人脸"); //下摄像头未检测到人脸
  1272. }
  1273. #endif
  1274. }
  1275. if (pfaceSeq != NULL){
  1276. cvReleaseMemStorage(&pfaceSeq->storage);
  1277. pfaceSeq = NULL;
  1278. }
  1279. cvResetImageROI(m_pProcessImg);
  1280. if(nFaceNum > 0){
  1281. //发现有人
  1282. m_stAllFaceInfo.nTatolFaceNum = nFaceNum;
  1283. return true;
  1284. }
  1285. else{
  1286. m_eMonitorState = NoBody;
  1287. return false;
  1288. }
  1289. }
  1290. //运动检测
  1291. bool MotionTrack(CameraEnum eCamera, int diff_threshold = 10)
  1292. {
  1293. if (!GetSpecifiedCameraImage(eCamera))
  1294. {
  1295. m_pHostApi->Debug(FACECAP_DEBUG, "运动跟踪获取图像失败");
  1296. return false;
  1297. }
  1298. cvResetImageROI(m_pProcessImg);
  1299. memset(&m_stObjTrackRslt,0,sizeof(CMotionTrackRslt));
  1300. const double MHI_DURATION = 0.5;
  1301. const double MAX_TIME_DELTA = 0.5;
  1302. const double MIN_TIME_DELTA = 0.05;
  1303. const int N = 3;
  1304. //ring image buffer
  1305. // temporary images
  1306. IplImage*dst = cvCreateImage( cvSize(m_pProcessImg->width,m_pProcessImg->height), 8, 1 );
  1307. cvZero( dst);
  1308. dst->origin = m_pProcessImg->origin;
  1309. //get current time in seconds
  1310. double timestamp = clock()/100.;
  1311. CvSize size = cvSize(m_pProcessImg->width,m_pProcessImg->height);
  1312. int i, idx1, idx2;
  1313. IplImage* silh;
  1314. IplImage* pyr = cvCreateImage( cvSize((size.width & -2)/2, (size.height & -2)/2), 8, 1 );
  1315. CvMemStorage *stor;
  1316. CvSeq *cont;
  1317. if( !m_pMhImg || m_pMhImg->width != size.width || m_pMhImg->height != size.height )
  1318. {
  1319. if( m_pMhBuf == 0 )
  1320. {
  1321. m_pMhBuf = (IplImage**)malloc(N*sizeof(m_pMhBuf[0]));
  1322. memset( m_pMhBuf, 0, N*sizeof(m_pMhBuf[0]));
  1323. }
  1324. for( i = 0; i < N; i++ )
  1325. {
  1326. cvReleaseImage( &m_pMhBuf[i] );
  1327. m_pMhBuf[i] = cvCreateImage( size, IPL_DEPTH_8U, 1 );
  1328. cvZero(m_pMhBuf[i]);
  1329. }
  1330. cvReleaseImage( &m_pMhImg );
  1331. m_pMhImg = cvCreateImage( size, IPL_DEPTH_32F, 1 );
  1332. //clear MHI at the beginning
  1333. cvZero( m_pMhImg );
  1334. }
  1335. //convert frame to grayscale
  1336. cvCvtColor( m_pProcessImg, m_pMhBuf[m_nLastBuf], CV_BGR2GRAY );
  1337. //cvSaveImage("0.bmp",m_pProcessImg);
  1338. idx1 = m_nLastBuf;
  1339. //index of (last - (N-1))th frame
  1340. idx2 = (m_nLastBuf + 1) % N;
  1341. m_nLastBuf = idx2;
  1342. // 做帧差
  1343. silh = m_pMhBuf[idx2];
  1344. //get difference between frames
  1345. cvAbsDiff( m_pMhBuf[idx1], m_pMhBuf[idx2], silh );
  1346. //cvSaveImage("Diff.bmp",silh);
  1347. //对差图像做二值化
  1348. cvThreshold( silh, silh, 10, 255, CV_THRESH_BINARY );
  1349. //cvSaveImage("Threshold.bmp",silh);
  1350. //更新运动历史图像
  1351. cvUpdateMotionHistory( silh, m_pMhImg, timestamp, MHI_DURATION );
  1352. cvCvtScale( m_pMhImg, dst, 255./MHI_DURATION, (MHI_DURATION - timestamp)*255./MHI_DURATION );
  1353. //cvCvtScale( m_pMhImg, dst, 255./MHI_DURATION, 0 );
  1354. // 中值滤波,消除小的噪声
  1355. cvSmooth( dst, dst, CV_MEDIAN, 3, 0, 0, 0 );
  1356. // 向下采样,去掉噪声
  1357. cvPyrDown( dst, pyr, 7 );
  1358. //闭运算,消除目标的不连续空洞
  1359. //进行闭运算
  1360. //IplConvKernel* element = cvCreateStructuringElementEx(20,20,1,1,CV_SHAPE_ELLIPSE);
  1361. //cvMorphologyEx(pyr,pyr,NULL,element,CV_MOP_CLOSE,1);
  1362. //膨胀
  1363. cvDilate( pyr, pyr, 0, 2 ); // 做膨胀操作,消除目标的不连续空洞
  1364. cvPyrUp( pyr, dst, 7 );
  1365. // 下面的程序段用来找到轮廓
  1366. stor = cvCreateMemStorage(0);
  1367. cont = cvCreateSeq(CV_SEQ_ELTYPE_POINT, sizeof(CvSeq), sizeof(CvPoint) , stor);
  1368. // 找到所有轮廓
  1369. cvFindContours( dst, stor, &cont, sizeof(CvContour), CV_RETR_LIST , CV_LINK_RUNS, cvPoint(0,0));
  1370. cvReleaseImage(&dst);
  1371. //double fArea = 0.0;
  1372. // 直接使用CONTOUR中的矩形来画轮廓
  1373. for(;cont;cont = cont->h_next)
  1374. {
  1375. CvRect r = ((CvContour*)cont)->rect;
  1376. if((r.height * r.width > m_stFaceConfig.nContourMinAera)&&((r.height * r.width) != (m_nImgWidth*m_nImgHeight))) // 面积小的方形抛弃掉
  1377. //{
  1378. //fArea = fabs(cvContourArea( cont, CV_WHOLE_SEQ )); //获取当前轮廓面积
  1379. //if ((fArea > CONTOUR_MAX_AERA)&&(r.height * r.width != m_nImgWidth*m_nImgHeight))
  1380. {
  1381. m_stObjTrackRslt.ObjRect[m_stObjTrackRslt.nObjNum] = r;
  1382. m_stObjTrackRslt.nObjNum++;
  1383. }
  1384. //}
  1385. }
  1386. // free memory
  1387. cvReleaseMemStorage(&stor);
  1388. cvReleaseImage( &pyr );
  1389. cvResetImageROI(m_pProcessImg);
  1390. if (m_stObjTrackRslt.nObjNum >0)
  1391. {
  1392. return true;
  1393. }
  1394. else
  1395. {
  1396. return false;
  1397. }
  1398. }
  1399. //计算监控线程下一步
  1400. void VideoMonitorThreadNextStep()
  1401. {
  1402. if(m_stAllFaceInfo.astFaceInfo[0].eDistance == OperateDistance)
  1403. {
  1404. if (m_eMonitorState != SomebodyOperate)
  1405. {
  1406. m_eMonitorState = SomebodyOperate;
  1407. m_stAllFaceInfo.astFaceInfo[0].eScene = ForwardScened;
  1408. m_pHostEvent->GenerateMonitorEvent(EnterOperate); //产生有人进入操作距离事件
  1409. m_pHostApi->Debug(FACECAP_DEBUG, "有人进入操作距离!");
  1410. //获取UUID
  1411. if (m_stAllFaceInfo.astFaceInfo[0].FaceID == 0)
  1412. {
  1413. m_stAllFaceInfo.astFaceInfo[0].FaceID = m_pHostApi->GenerateUUID();
  1414. }
  1415. }
  1416. else
  1417. {
  1418. if(m_stAllFaceInfo.astFaceInfo[0].eScene != LockScene)
  1419. {
  1420. m_eMonitorState = SomebodyOperate;
  1421. m_stAllFaceInfo.astFaceInfo[0].eScene = LockScene;
  1422. }
  1423. m_pHostEvent->GenerateMonitorEvent(CaptureFace); //发送捕获人脸事件
  1424. m_pHostApi->Debug(FACECAP_DEBUG, "锁定人脸!");
  1425. }
  1426. }
  1427. else if(m_stAllFaceInfo.astFaceInfo[0].eDistance == FarDistance)
  1428. {
  1429. if((m_eMonitorState == SomebodyOperate)||(m_eMonitorState == SomebodyClose))
  1430. {
  1431. m_stAllFaceInfo.astFaceInfo[0].eScene = UnLockScene;
  1432. m_eMonitorState = SomebodyFar;
  1433. memset(&m_stAllFaceInfo,0,sizeof(CAllFaceInfo));
  1434. m_stAllFaceInfo.astFaceInfo[0].stRegion.stUpperBodyRect.height = m_nImgHeight/2;
  1435. m_stAllFaceInfo.astFaceInfo[0].stRegion.stUpperBodyRect.width = m_nImgWidth/2;
  1436. m_stAllFaceInfo.astFaceInfo[0].stRegion.stUpperBodyRect.x = m_nImgHeight/4;
  1437. m_stAllFaceInfo.astFaceInfo[0].stRegion.stUpperBodyRect.y = m_nImgWidth/4;
  1438. m_pHostEvent->GenerateMonitorEvent(Leave); //产生客户离开事件
  1439. m_pHostApi->Debug(FACECAP_DEBUG, "客户离开!");
  1440. //清除UUID
  1441. m_stAllFaceInfo.astFaceInfo[0].FaceID = 0;
  1442. }
  1443. }
  1444. else if (m_stAllFaceInfo.astFaceInfo[0].eDistance == CloseDistance)
  1445. {
  1446. if (SomebodyOperate == m_eMonitorState)
  1447. {
  1448. m_stAllFaceInfo.astFaceInfo[0].eScene = BackwardScened;
  1449. m_eMonitorState = SomebodyClose;
  1450. m_pHostEvent->GenerateMonitorEvent(BackToClose); //产生客户退回到接近距离事件
  1451. m_pHostApi->Debug(FACECAP_DEBUG, "客户退回到接近距离!");
  1452. }
  1453. else if(SomebodyFar == m_eMonitorState)
  1454. {
  1455. m_stAllFaceInfo.astFaceInfo[0].eScene = ForwardScened;
  1456. m_eMonitorState = SomebodyClose;
  1457. m_pHostApi->Debug(FACECAP_DEBUG, "有人靠近!");
  1458. //获取UUID
  1459. if (m_stAllFaceInfo.astFaceInfo[0].FaceID == 0)
  1460. {
  1461. m_stAllFaceInfo.astFaceInfo[0].FaceID = m_pHostApi->GenerateUUID();
  1462. }
  1463. }
  1464. m_pHostEvent->GenerateMonitorEvent(Close); //产生有人靠近事件
  1465. }
  1466. }
  1467. // 计算当前人脸是否进入另外一个相机的最佳视野中
  1468. bool IsFacePosOverStep(CameraEnum eCamera,CvRect FaceRect)
  1469. {
  1470. if(m_pOperatorVideoQueue == NULL)
  1471. {
  1472. return false;
  1473. }
  1474. if(EnvironCamera == eCamera)
  1475. {
  1476. 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)))&&
  1477. (FaceRect.y > (m_nImgHeight-m_nImgHeight/m_stFaceConfig.fDetectFaceSize*4/m_stFaceConfig.nUpCameraEdgeLimit)))
  1478. {
  1479. return true;
  1480. }
  1481. else
  1482. {
  1483. return false;
  1484. }
  1485. }
  1486. else if(OperatorCamera == eCamera)
  1487. {
  1488. if(FaceRect.y < ((m_nImgHeight/m_stFaceConfig.fDetectFaceSize)*1/m_stFaceConfig.nDownCameraEdgeLimit))
  1489. {
  1490. return true;
  1491. }
  1492. else
  1493. {
  1494. return false;
  1495. }
  1496. }
  1497. else
  1498. {
  1499. return false;
  1500. }
  1501. }
  1502. //根据主用户设置人脸剪辑区域
  1503. void SetUpperbodyToCenter()
  1504. {
  1505. if(OperatorCamera == m_stFaceConfig.nPrimCamera)
  1506. {
  1507. if (m_pOperatorVideoQueue == NULL){
  1508. m_stAllFaceInfo.astFaceInfo[0].eCamera = EnvironCamera;
  1509. }
  1510. else{
  1511. m_stAllFaceInfo.astFaceInfo[0].eCamera = OperatorCamera;
  1512. }
  1513. }
  1514. else{
  1515. m_stAllFaceInfo.astFaceInfo[0].eCamera = EnvironCamera;
  1516. }
  1517. int nImgWidth = 0, nImgHeight = 0;
  1518. if (EnvironCamera == m_stAllFaceInfo.astFaceInfo[0].eCamera){
  1519. if (m_pEnvironVideoQueue == NULL){
  1520. return;
  1521. }
  1522. if (m_pEnvironVideoQueue->GetVideoLens() <= 0){
  1523. m_pHostApi->Debug(FACECAP_DEBUG, "环境相机图像队列为空");
  1524. return;
  1525. }
  1526. int isize = m_pEnvironVideoQueue->GetFrameSize(nImgWidth, nImgHeight);
  1527. if (0 == isize) {
  1528. return;
  1529. }
  1530. }
  1531. else if(OperatorCamera == m_stAllFaceInfo.astFaceInfo[0].eCamera){
  1532. if (m_pOperatorVideoQueue == NULL){
  1533. return;
  1534. }
  1535. if (m_pOperatorVideoQueue->GetVideoLens() <= 0){
  1536. m_pHostApi->Debug(FACECAP_DEBUG, "操作相机图像队列为空");
  1537. return ;
  1538. }
  1539. int isize = m_pOperatorVideoQueue->GetFrameSize(nImgWidth, nImgHeight);
  1540. if (0 == isize) {
  1541. return;
  1542. }
  1543. }
  1544. m_stAllFaceInfo.astFaceInfo[0].stRegion.stUpperBodyRect.height = nImgHeight/2;
  1545. m_stAllFaceInfo.astFaceInfo[0].stRegion.stUpperBodyRect.width = nImgWidth/2;
  1546. m_stAllFaceInfo.astFaceInfo[0].stRegion.stUpperBodyRect.x = nImgWidth/4;
  1547. m_stAllFaceInfo.astFaceInfo[0].stRegion.stUpperBodyRect.y = nImgHeight/4;
  1548. WriteAllFaceInfo(m_stAllFaceInfo);
  1549. }
  1550. bool RvcTimeout(int ims)
  1551. {
  1552. bool btimeout = true;
  1553. #ifdef _WIN32
  1554. DWORD dwRet = WaitForSingleObject(m_hStopEventWait, ims);
  1555. if (WAIT_TIMEOUT == dwRet) {
  1556. }
  1557. else if (WAIT_OBJECT_0 == dwRet) {
  1558. btimeout = false;
  1559. }
  1560. #else
  1561. struct timespec ts;
  1562. clock_gettime(CLOCK_REALTIME, &ts);
  1563. long unsec = ts.tv_nsec + (1000 * 1000 * ims);
  1564. ts.tv_sec += (unsec / 1000000000);
  1565. ts.tv_nsec = (unsec % 1000000000);
  1566. int itimeout = sem_timedwait(&m_semt, &ts);
  1567. if (0 != itimeout && (ETIMEDOUT == errno)) {
  1568. }
  1569. else if (0 == itimeout) {
  1570. btimeout = false;
  1571. }
  1572. #endif
  1573. return btimeout;
  1574. }
  1575. void ReleaseMotionTrackRst()
  1576. {
  1577. if (m_pMhImg)
  1578. {
  1579. cvReleaseImage(&m_pMhImg);
  1580. m_pMhImg = NULL;
  1581. }
  1582. if(m_pMhBuf)
  1583. {
  1584. for (int i=0;i<3;i++)
  1585. {
  1586. if (m_pMhBuf[i] != NULL)
  1587. {
  1588. cvReleaseImage(&m_pMhBuf[i]);
  1589. m_pMhBuf[i] = NULL;
  1590. }
  1591. }
  1592. free(m_pMhBuf);
  1593. m_pMhBuf = NULL;
  1594. }
  1595. m_nLastBuf=0;
  1596. }
  1597. CameraEnum GetInitPrimCamera()
  1598. {
  1599. CameraEnum eCamera = (CameraEnum)m_stFaceConfig.nPrimCamera;
  1600. if (NULL == m_pOperatorVideoQueue)
  1601. {
  1602. if ((m_nCameraState == 0) || (m_nCameraState == 2))
  1603. {
  1604. eCamera = EnvironCamera;
  1605. }
  1606. else if (m_nCameraState == 1)
  1607. {
  1608. eCamera = OperatorCamera;
  1609. }
  1610. else if (m_nCameraState == 3)
  1611. {
  1612. eCamera = ErrorCamera;
  1613. }
  1614. }
  1615. return eCamera;
  1616. }
  1617. int VideoMonitor()
  1618. {
  1619. bool bRst = false;
  1620. uint32_t nSearchFaceFailNum = 0; //搜索人脸失败次数
  1621. uint32_t nDetectFailNum = 0; //检测人脸失败的次数
  1622. //select camera
  1623. m_eCamera = GetInitPrimCamera();
  1624. uint32_t iwaittime = m_stFaceConfig.nSleepShort;
  1625. while (!m_bStopVieoMonitor)
  1626. {
  1627. if(RvcTimeout(iwaittime))
  1628. {
  1629. //如果摄像头没启动或故障,停止扫描,休眠2s
  1630. if (3 == m_nCameraState){
  1631. iwaittime = 2000;
  1632. m_pHostApi->Debug(FACECAP_DEBUG, "camera stop or all camera error!");
  1633. continue;
  1634. }
  1635. //灯光变化时,清空历史记录,防止误判
  1636. if (m_bLightChange){
  1637. ReleaseMotionTrackRst();
  1638. m_bLightChange = false;
  1639. }
  1640. //if no people,start motion tracker
  1641. if(NoBody == m_eMonitorState){
  1642. m_pHostApi->Debug(FACECAP_DEBUG, "NoBody");
  1643. bRst = GetSpecifiedCameraImage(m_eCamera);
  1644. if (bRst){
  1645. int size = (int)m_nImgHeight/m_stFaceConfig.fSearchFaceSize;
  1646. bRst = FaceSearchWithSpecifiedSize(size);
  1647. if (!bRst){
  1648. SetUpperbodyToCenter();
  1649. iwaittime = m_stFaceConfig.nSleepLong;
  1650. SwitchDetectCamera();
  1651. }
  1652. else{
  1653. WriteAllFaceInfo(m_stAllFaceInfo); //保存人脸坐标信息
  1654. iwaittime = m_stFaceConfig.nSleepMiddle;
  1655. }
  1656. }
  1657. else{
  1658. iwaittime = m_stFaceConfig.nSleepMiddle;
  1659. SwitchDetectCamera();
  1660. }
  1661. }
  1662. else if (SomebodyFar == m_eMonitorState) //if somebody space 2.5m
  1663. {
  1664. m_pHostApi->Debug(FACECAP_DEBUG, "SomebodyFar");
  1665. bRst = GetSpecifiedCameraImage(m_eCamera);
  1666. if (bRst){
  1667. int size = (int)m_nImgHeight/m_stFaceConfig.fSearchFaceSize;
  1668. bRst = FaceSearchWithSpecifiedSize(size);
  1669. if (!bRst){
  1670. SetUpperbodyToCenter();
  1671. iwaittime = m_stFaceConfig.nSleepLong;
  1672. SwitchDetectCamera();
  1673. }
  1674. else{
  1675. WriteAllFaceInfo(m_stAllFaceInfo);
  1676. iwaittime = m_stFaceConfig.nSleepShort;
  1677. }
  1678. }
  1679. else{
  1680. iwaittime = m_stFaceConfig.nSleepMiddle;
  1681. SwitchDetectCamera();
  1682. }
  1683. }
  1684. else if (SomebodyClose == m_eMonitorState) //close distance,1.5m
  1685. {
  1686. m_pHostApi->Debug(FACECAP_DEBUG, "SomebodyClose");
  1687. bRst = FaceDetectWithSpecifiedCamera(m_eCamera);
  1688. if(!bRst){
  1689. if(NULL != m_pOperatorVideoQueue){
  1690. SwitchDetectCamera();
  1691. bRst = FaceDetectWithSpecifiedCamera(m_eCamera);
  1692. if (!bRst){
  1693. nSearchFaceFailNum++;
  1694. //if search face fail, return motiontracker
  1695. if(nSearchFaceFailNum > 2){
  1696. SetUpperbodyToCenter();
  1697. m_eMonitorState = NoBody;
  1698. m_pHostEvent->GenerateMonitorEvent(Leave);
  1699. m_pHostApi->Debug(FACECAP_DEBUG, "客户离开!");
  1700. nSearchFaceFailNum = 0;
  1701. iwaittime = m_stFaceConfig.nSleepLong;
  1702. }
  1703. else{
  1704. iwaittime = m_stFaceConfig.nSleepMiddle;
  1705. }
  1706. }
  1707. else{
  1708. nSearchFaceFailNum = 0;
  1709. VideoMonitorThreadNextStep();
  1710. WriteAllFaceInfo(m_stAllFaceInfo);
  1711. iwaittime = m_stFaceConfig.nSleepShort;
  1712. }
  1713. }
  1714. else //single camera mod
  1715. {
  1716. nSearchFaceFailNum++;
  1717. //if search face fail,return motiontracker
  1718. if(nSearchFaceFailNum > 2){
  1719. SetUpperbodyToCenter();
  1720. m_eMonitorState = NoBody;
  1721. m_pHostEvent->GenerateMonitorEvent(Leave);
  1722. m_pHostApi->Debug(FACECAP_DEBUG, "客户离开!");
  1723. nSearchFaceFailNum = 0;
  1724. iwaittime = m_stFaceConfig.nSleepLong;
  1725. }
  1726. else{
  1727. iwaittime = m_stFaceConfig.nSleepMiddle;
  1728. }
  1729. }
  1730. }
  1731. else
  1732. {
  1733. //if curcamera search face success, judge which camera result is the best
  1734. m_pHostApi->Debug(FACECAP_DEBUG, "Close distance, %s Search face Success", (m_eCamera == EnvironCamera) ? "EnvironCamera" : "OperatorCamera");
  1735. if((m_pOperatorVideoQueue != NULL)&&(m_pEnvironVideoQueue != NULL))
  1736. {
  1737. SwitchDetectCamera();
  1738. CAllFaceInfo stFaceInfoTmp = m_stAllFaceInfo;
  1739. if (FaceDetectWithSpecifiedCamera(m_eCamera))
  1740. {
  1741. int CurFaceArea = m_stAllFaceInfo.astFaceInfo[0].stRegion.stFaceRect.width*m_stAllFaceInfo.astFaceInfo[0].stRegion.stFaceRect.height;
  1742. int FrontFaceArea = stFaceInfoTmp.astFaceInfo[0].stRegion.stFaceRect.width*stFaceInfoTmp.astFaceInfo[0].stRegion.stFaceRect.height;
  1743. //if cur face area less than front face,select front Face
  1744. if (FrontFaceArea > CurFaceArea){
  1745. SwitchDetectCamera();
  1746. m_stAllFaceInfo = stFaceInfoTmp;
  1747. }
  1748. }
  1749. else{
  1750. SwitchDetectCamera();
  1751. m_stAllFaceInfo = stFaceInfoTmp;
  1752. }
  1753. }
  1754. nSearchFaceFailNum = 0;
  1755. VideoMonitorThreadNextStep();
  1756. WriteAllFaceInfo(m_stAllFaceInfo);
  1757. iwaittime = m_stFaceConfig.nSleepShort;
  1758. }
  1759. }
  1760. else if (SomebodyOperate == m_eMonitorState) //当有人进入操作距离时
  1761. {
  1762. m_pHostApi->Debug(FACECAP_DEBUG, "SomebodyOperate");
  1763. //如果是双相机模式
  1764. if (m_pOperatorVideoQueue != NULL){
  1765. m_eCamera = m_stAllFaceInfo.astFaceInfo[0].eCamera;
  1766. //先搜索上次搜索到人脸的区域
  1767. if(m_stAllFaceInfo.nTatolFaceNum > 0){
  1768. m_pHostApi->Debug(FACECAP_DEBUG, "Operator distance,CurCamera search last face Region");
  1769. bRst = FaceDetectWithSpecifiedCameraRegion(m_eCamera, m_stAllFaceInfo.astFaceInfo[0].stRegion.stUpperBodyRect);
  1770. }
  1771. else{
  1772. bRst = false;
  1773. }
  1774. if(!bRst){
  1775. m_pHostApi->Debug(FACECAP_DEBUG, "Operator distance,search Face by CurCamera");
  1776. bRst = FaceDetectWithSpecifiedCamera(m_eCamera);
  1777. }
  1778. }
  1779. else //如果单相机模式
  1780. {
  1781. //先搜索上次搜索到人脸的区域
  1782. if(m_stAllFaceInfo.nTatolFaceNum > 0){
  1783. m_pHostApi->Debug(FACECAP_DEBUG, "Operator distance, %s Search Last face Region", (m_eCamera == EnvironCamera) ? "EnvironCamera" : "OperatorCamera");
  1784. bRst = FaceDetectWithSpecifiedCameraRegion(m_eCamera, m_stAllFaceInfo.astFaceInfo[0].stRegion.stUpperBodyRect);
  1785. }
  1786. else{
  1787. bRst = false;
  1788. }
  1789. if(!bRst){
  1790. bRst = FaceDetectWithSpecifiedCamera(m_eCamera);
  1791. }
  1792. }
  1793. if(bRst) //如果在当前相机中找到人脸
  1794. {
  1795. nDetectFailNum = 0;
  1796. //如果是双相机模式,
  1797. if(m_pOperatorVideoQueue!=NULL)
  1798. {
  1799. //找到人脸后,检测另一个相机中是否有更大的人脸
  1800. SwitchDetectCamera();
  1801. CAllFaceInfo stFaceInfoTmp = m_stAllFaceInfo;
  1802. if (FaceDetectWithSpecifiedCamera(m_eCamera))
  1803. {
  1804. int CurFaceArea = m_stAllFaceInfo.astFaceInfo[0].stRegion.stFaceRect.width*m_stAllFaceInfo.astFaceInfo[0].stRegion.stFaceRect.height;
  1805. int FrontFaceArea = stFaceInfoTmp.astFaceInfo[0].stRegion.stFaceRect.width*stFaceInfoTmp.astFaceInfo[0].stRegion.stFaceRect.height;
  1806. //if cur face area less than front face,select front Face
  1807. if (FrontFaceArea > CurFaceArea){
  1808. SwitchDetectCamera();
  1809. m_stAllFaceInfo = stFaceInfoTmp;
  1810. }
  1811. }
  1812. else{
  1813. SwitchDetectCamera();
  1814. m_stAllFaceInfo = stFaceInfoTmp;
  1815. }
  1816. //判断用户是否进入另外一个相机的视野,如果进入另一个相机的最佳视野
  1817. if((m_pEnvironVideoQueue!=NULL)&&IsFacePosOverStep(m_eCamera,m_stAllFaceInfo.astFaceInfo[0].stRegion.stFaceRect))
  1818. {
  1819. stFaceInfoTmp = m_stAllFaceInfo; //暂存当前结果
  1820. memset(&m_stAllFaceInfo,0,sizeof(CAllFaceInfo));
  1821. SwitchDetectCamera();
  1822. //在另一个相机中重新搜索
  1823. m_pHostApi->Debug(FACECAP_DEBUG, "Operator distance, Change camera to:%s search Face", (m_eCamera == EnvironCamera) ? "EnvironCamera" : "OperatorCamera");
  1824. bRst = FaceDetectWithSpecifiedCamera(m_eCamera);
  1825. if(!bRst)
  1826. {
  1827. SwitchDetectCamera();
  1828. m_stAllFaceInfo = stFaceInfoTmp;
  1829. }
  1830. }
  1831. }
  1832. VideoMonitorThreadNextStep();
  1833. WriteAllFaceInfo(m_stAllFaceInfo);
  1834. iwaittime = m_stFaceConfig.nSleepLong;
  1835. }
  1836. else //如果在当前相机中未找到用户
  1837. {
  1838. //如果双相机模式
  1839. if(m_pOperatorVideoQueue!=NULL)
  1840. {
  1841. SwitchDetectCamera();
  1842. m_pHostApi->Debug(FACECAP_DEBUG, "Operator distance, Change camera to:%s search Face", (m_eCamera == EnvironCamera) ? "EnvironCamera" : "OperatorCamera");
  1843. bRst = FaceDetectWithSpecifiedCamera(m_eCamera);
  1844. if(bRst)
  1845. {
  1846. nDetectFailNum = 0;
  1847. VideoMonitorThreadNextStep();
  1848. WriteAllFaceInfo(m_stAllFaceInfo);
  1849. m_pHostApi->Debug(FACECAP_DEBUG, "Write Face info Success");
  1850. iwaittime = m_stFaceConfig.nSleepLong;
  1851. }
  1852. else
  1853. {
  1854. nDetectFailNum++;
  1855. if(nDetectFailNum >2) //如果连续2次未找到人脸,回到有人靠近状态
  1856. {
  1857. m_eMonitorState = SomebodyClose;
  1858. m_stAllFaceInfo.astFaceInfo[0].eScene = UnLockScene;
  1859. m_pHostEvent->GenerateMonitorEvent(LoseFace); //发送失去人脸事件
  1860. m_pHostApi->Debug(FACECAP_DEBUG, "人脸失去锁定!");
  1861. nDetectFailNum = 0;
  1862. }
  1863. iwaittime = m_stFaceConfig.nSleepShort;
  1864. }
  1865. }
  1866. else //如果单相机模式
  1867. {
  1868. nDetectFailNum++;
  1869. if(nDetectFailNum > 3) //如果连续3次未找到人脸,回到有人靠近状态
  1870. {
  1871. m_eMonitorState = SomebodyClose;
  1872. m_stAllFaceInfo.astFaceInfo[0].eScene = UnLockScene;
  1873. m_pHostEvent->GenerateMonitorEvent(LoseFace); //发送失去人脸事件
  1874. m_pHostApi->Debug(FACECAP_DEBUG, "人脸失去锁定!");
  1875. nDetectFailNum = 0;
  1876. }
  1877. iwaittime = m_stFaceConfig.nSleepShort;
  1878. }
  1879. }
  1880. }
  1881. }
  1882. else
  1883. {
  1884. //清空存储区
  1885. if (pfaceSeq != NULL){
  1886. cvReleaseMemStorage(&pfaceSeq->storage);
  1887. pfaceSeq = NULL;
  1888. }
  1889. if (NULL != m_pProcessImg){
  1890. cvResetImageROI(m_pProcessImg);
  1891. }
  1892. m_pHostApi->Debug(FACECAP_DEBUG, "stop face tracking..");
  1893. break;
  1894. }
  1895. }
  1896. return 0;
  1897. }
  1898. #ifdef _WIN32
  1899. static unsigned int __stdcall VideoMonitorThread(void* pParam)
  1900. {
  1901. Clibfacecapture_impl* VideoFaceMonitor = (Clibfacecapture_impl*)pParam;
  1902. return VideoFaceMonitor->VideoMonitor();
  1903. }
  1904. #else
  1905. static void* videomonitorfunc(void* pParam)
  1906. {
  1907. Clibfacecapture_impl* VideoFaceMonitor = (Clibfacecapture_impl*)pParam;
  1908. VideoFaceMonitor->VideoMonitor();
  1909. return ((void*)0);
  1910. }
  1911. #endif
  1912. public:
  1913. //开始视频监控,pHost:事件,nMonitorFreq:监控频率,单位ms,MonitorType:监控类型,有三种模式可供选择
  1914. bool StartVideoMonitor(CHostApi *pHostAPI, CVideoMonitorEvent*pHost, MonitorEnum eMonitorType)
  1915. {
  1916. #ifdef _WIN32
  1917. ResetEvent(m_hStopEventWait);
  1918. if (NULL == m_hVieoMonitorThread){
  1919. m_hVieoMonitorThread = (HANDLE)_beginthreadex(NULL, 0, VideoMonitorThread, this, 0, (unsigned int*)&m_nVieoMonitorThreadId);
  1920. if (m_hVieoMonitorThread) {
  1921. m_bStopVieoMonitor = false;
  1922. m_eMonitorState = MonitorStateEnum::NoBody;
  1923. m_pHostApi->Debug(FACECAP_DEBUG, "create video monitor thread success.");
  1924. }
  1925. else {
  1926. m_pHostApi->Debug(FACECAP_INFO, "create video monitor thread failed!");
  1927. }
  1928. }
  1929. #else
  1930. if (0 == pthread_create(&m_videomonitorthreadid, NULL, videomonitorfunc, (void*)this)){
  1931. m_bStopVieoMonitor = false;
  1932. m_eMonitorState = MonitorStateEnum::NoBody;
  1933. m_pHostApi->Debug(FACECAP_DEBUG, "create video monitor thread success and thread id is %u.", m_videomonitorthreadid);
  1934. }
  1935. else {
  1936. m_pHostApi->Debug(FACECAP_INFO, "create video monitor thread failed.");
  1937. }
  1938. #endif
  1939. return true;
  1940. }
  1941. //停止视频监控
  1942. bool StopVideoMonitor()
  1943. {
  1944. m_bStopVieoMonitor = true;
  1945. #ifdef _WIN32
  1946. SetEvent(m_hStopEventWait);
  1947. DWORD ret = WaitForSingleObject(m_hVieoMonitorThread, INFINITE);
  1948. if (WAIT_OBJECT_0 == ret) {
  1949. m_pHostApi->Debug(FACECAP_DEBUG, "normal ....");
  1950. }
  1951. else if (WAIT_ABANDONED == ret) {
  1952. m_pHostApi->Debug(FACECAP_DEBUG, "abandoned ....");
  1953. }
  1954. CloseHandle(m_hVieoMonitorThread);
  1955. m_hVieoMonitorThread = NULL;
  1956. #else
  1957. sem_post(&m_semt);
  1958. if (0 == pthread_join(m_videomonitorthreadid, NULL)) {
  1959. m_pHostApi->Debug(FACECAP_DEBUG, "thread join video monitor thread %u success!", m_videomonitorthreadid);
  1960. m_videomonitorthreadid = 0;
  1961. }
  1962. else{
  1963. m_pHostApi->Debug(FACECAP_INFO, "thread join video monitor thread failed!");
  1964. }
  1965. #endif
  1966. return true;
  1967. }
  1968. //有多少其他用户
  1969. bool GetCustomerNum(uint32_t& num)
  1970. {
  1971. #ifdef _WIN32
  1972. EnterCriticalSection(&CS);
  1973. #else
  1974. pthread_mutex_lock(&cs_mutex);
  1975. #endif
  1976. num = m_stFaceRstStorage.nTatolFaceNum;
  1977. #ifdef _WIN32
  1978. LeaveCriticalSection(&CS);
  1979. #else
  1980. pthread_mutex_unlock(&cs_mutex);
  1981. #endif
  1982. return true;
  1983. }
  1984. //获取主用户的常规属性
  1985. bool GetMainCustomerStatus(uint64_t &FaceID, CCustomerStatus &Property)
  1986. {
  1987. #ifdef _WIN32
  1988. EnterCriticalSection(&CS);
  1989. #else
  1990. pthread_mutex_lock(&cs_mutex);
  1991. #endif
  1992. //Property.eBrightness = m_stFaceRstStorage.astFaceInfo[0].eBrightness;
  1993. Property.stCustomerCover = m_stFaceRstStorage.astFaceInfo[0].stCustomerCover;
  1994. Property.stCustomerPos.eCamera = m_stFaceRstStorage.astFaceInfo[0].eCamera;//1
  1995. Property.stCustomerPos.eDistance = m_stFaceRstStorage.astFaceInfo[0].eDistance;
  1996. Property.stCustomerPos.ePose = m_stFaceRstStorage.astFaceInfo[0].ePose;
  1997. Property.stCustomerPos.eScene = m_stFaceRstStorage.astFaceInfo[0].eScene;
  1998. Property.stCustomerPos.stRange.sX = m_stFaceRstStorage.astFaceInfo[0].stRegion.stUpperBodyRect.x + (short)m_stFaceRstStorage.astFaceInfo[0].stRegion.stUpperBodyRect.width/2 - (short)m_nImgWidth/2;
  1999. Property.stCustomerPos.stRange.sY = m_stFaceRstStorage.astFaceInfo[0].stRegion.stUpperBodyRect.y + (short)m_stFaceRstStorage.astFaceInfo[0].stRegion.stUpperBodyRect.height/2 - (short)m_nImgHeight/2;
  2000. Property.stCustomerPos.stRange.sH = (short)m_stFaceRstStorage.astFaceInfo[0].stRegion.stUpperBodyRect.height/2;
  2001. FaceID = m_stFaceRstStorage.astFaceInfo[0].FaceID;
  2002. #ifdef _WIN32
  2003. LeaveCriticalSection(&CS);
  2004. #else
  2005. pthread_mutex_unlock(&cs_mutex);
  2006. #endif
  2007. return true;
  2008. }
  2009. //获取用户的常规属性
  2010. bool GetCustomerStatus(uint64_t FaceID, CCustomerStatus &Property)
  2011. {
  2012. #ifdef _WIN32
  2013. EnterCriticalSection(&CS);
  2014. #else
  2015. pthread_mutex_lock(&cs_mutex);
  2016. #endif
  2017. bool bSearch = false;
  2018. for (int i =0;i<m_stFaceRstStorage.nTatolFaceNum&&!bSearch;i++)
  2019. {
  2020. if(m_stFaceRstStorage.astFaceInfo[i].FaceID == FaceID)
  2021. {
  2022. Property.eBrightness = m_stFaceRstStorage.astFaceInfo[i].eBrightness;
  2023. Property.stCustomerCover = m_stFaceRstStorage.astFaceInfo[i].stCustomerCover;
  2024. Property.stCustomerPos.eCamera = m_stFaceRstStorage.astFaceInfo[i].eCamera;
  2025. Property.stCustomerPos.eDistance = m_stFaceRstStorage.astFaceInfo[i].eDistance;
  2026. Property.stCustomerPos.ePose = m_stFaceRstStorage.astFaceInfo[i].ePose;
  2027. Property.stCustomerPos.eScene = m_stFaceRstStorage.astFaceInfo[i].eScene;
  2028. Property.stCustomerPos.stRange.sX = m_stFaceRstStorage.astFaceInfo[i].stRegion.stUpperBodyRect.x
  2029. +(short)m_stFaceRstStorage.astFaceInfo[i].stRegion.stUpperBodyRect.width/2-(short)m_nImgWidth/2;
  2030. Property.stCustomerPos.stRange.sY = m_stFaceRstStorage.astFaceInfo[i].stRegion.stUpperBodyRect.y
  2031. +(short)m_stFaceRstStorage.astFaceInfo[i].stRegion.stUpperBodyRect.height/2-(short)m_nImgHeight/2;
  2032. Property.stCustomerPos.stRange.sH = (short)m_stFaceRstStorage.astFaceInfo[i].stRegion.stUpperBodyRect.height/2;
  2033. bSearch = true;
  2034. }
  2035. }
  2036. #ifdef _WIN32
  2037. LeaveCriticalSection(&CS);
  2038. #else
  2039. pthread_mutex_unlock(&cs_mutex);
  2040. #endif
  2041. return true;
  2042. }
  2043. //获取所有用户FACEID
  2044. bool GetTrackFace(uint64_t*arrFaceIDs, int *size)
  2045. {
  2046. #ifdef _WIN32
  2047. EnterCriticalSection(&CS);
  2048. #else
  2049. pthread_mutex_lock(&cs_mutex);
  2050. #endif
  2051. for (int i = 0;i<m_stFaceRstStorage.nTatolFaceNum && i < *size;i++)
  2052. {
  2053. arrFaceIDs[i] = m_stFaceRstStorage.astFaceInfo[i].FaceID;
  2054. }
  2055. #ifdef _WIN32
  2056. LeaveCriticalSection(&CS);
  2057. #else
  2058. pthread_mutex_unlock(&cs_mutex);
  2059. #endif
  2060. return true;
  2061. }
  2062. //获取用户的交互属性
  2063. bool GetCustomerAppearance(uint64_t FaceID,CCustomerAppearance &Property)
  2064. {
  2065. #ifdef _WIN32
  2066. EnterCriticalSection(&CS);
  2067. #else
  2068. pthread_mutex_lock(&cs_mutex);
  2069. #endif
  2070. bool bSearch = false;
  2071. for (int i =0;i<m_stFaceRstStorage.nTatolFaceNum&&!bSearch;i++)
  2072. {
  2073. if(m_stFaceRstStorage.astFaceInfo[i].FaceID == FaceID)
  2074. {
  2075. Property.eHeight =m_stFaceRstStorage.astFaceInfo[i].eHeight;
  2076. Property.eSex = m_stFaceRstStorage.astFaceInfo[i].eSex;
  2077. Property.eYoungOld = m_stFaceRstStorage.astFaceInfo[i].eYoungOld;
  2078. bSearch = true;
  2079. }
  2080. }
  2081. #ifdef _WIN32
  2082. LeaveCriticalSection(&CS);
  2083. #else
  2084. pthread_mutex_unlock(&cs_mutex);
  2085. #endif
  2086. return true;
  2087. }
  2088. };
  2089. // 这是已导出类的构造函数。
  2090. // 有关类定义的信息,请参阅 libfacecapture.h
  2091. Clibfacecapture::Clibfacecapture(bool *pResult, CHostApi *pHostAPI, CVideoMonitorEvent*pHost, const char* EnvironVideoName, const char* OperateVideoName, MonitorEnum eMonitorType)
  2092. {
  2093. m_pImpl = new Clibfacecapture_impl(pResult, pHostAPI, pHost, EnvironVideoName, OperateVideoName, eMonitorType);
  2094. }
  2095. Clibfacecapture::~Clibfacecapture(void)
  2096. {
  2097. delete m_pImpl;
  2098. }
  2099. //有多少其他用户
  2100. bool Clibfacecapture::GetCustomerNum(uint32_t& num)
  2101. {
  2102. return m_pImpl->GetCustomerNum(num);
  2103. }
  2104. //获取主用户的常规属性
  2105. bool Clibfacecapture::GetMainCustomerStatus(uint64_t &FaceID,CCustomerStatus &Property)
  2106. {
  2107. return m_pImpl->GetMainCustomerStatus(FaceID,Property);
  2108. }
  2109. //获取其他用户的常规属性
  2110. bool Clibfacecapture::GetCustomerStatus (uint64_t FaceID,CCustomerStatus &Property)
  2111. {
  2112. return m_pImpl->GetCustomerStatus(FaceID,Property);
  2113. }
  2114. //获取主用户的交互属性
  2115. bool Clibfacecapture::GetCustomerAppearance(uint64_t FaceID,CCustomerAppearance &Property)
  2116. {
  2117. return m_pImpl->GetCustomerAppearance(FaceID,Property);
  2118. }
  2119. //获取所有用户FACEID
  2120. bool Clibfacecapture::GetTrackFace(uint64_t*arrFaceIDs, int *size)
  2121. {
  2122. return m_pImpl->GetTrackFace(arrFaceIDs, size);
  2123. }
  2124. //灯光变化
  2125. void Clibfacecapture::SetLightChange()
  2126. {
  2127. m_pImpl->m_bLightChange = true;
  2128. }
  2129. //相机状态
  2130. void Clibfacecapture::SetCameraState(int nState)
  2131. {
  2132. m_pImpl->m_nCameraState = nState;
  2133. }
  2134. bool Clibfacecapture::StartFaceCapture()
  2135. {
  2136. return m_pImpl->StartFaceCapture();
  2137. }
  2138. bool Clibfacecapture::StopFaceCapture()
  2139. {
  2140. return m_pImpl->StopFaceCapture();
  2141. }
  2142. bool SnapShot(CImageFrame*img)
  2143. {
  2144. if(img == NULL){
  2145. return false;
  2146. }
  2147. IplImage*cvimgtmp = cvCreateImage(cvSize(img->width,img->height),8,3);
  2148. IplImage*cvimg = cvCreateImage(cvSize(img->width,img->height),8,3);
  2149. char m_FileName[MAX_PATH] = {0};
  2150. #ifdef _WIN32
  2151. SYSTEMTIME nowTime; // 系统时间结构体
  2152. GetLocalTime(&nowTime);
  2153. _snprintf(m_FileName, MAX_PATH, "%4d%02d%02d%02d%02d%02d", nowTime.wYear, nowTime.wMonth, nowTime.wDay, nowTime.wHour, nowTime.wMinute, nowTime.wSecond);
  2154. #else
  2155. struct tm* pst = NULL;
  2156. time_t t = time(NULL);
  2157. pst = localtime(&t);
  2158. 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);
  2159. #endif // _WIN32
  2160. CvFont fontEvent = cvFont(2,2);
  2161. memcpy(cvimg->imageData,img->data,img->framesize);
  2162. int nstartx = 0;
  2163. int nstarty = 0;
  2164. cvCopy(cvimg,cvimgtmp);
  2165. cvPutText(cvimgtmp, m_FileName,cvPoint(img->width-280,img->height-10), &fontEvent, CV_RGB( 255, 0, 0));
  2166. memcpy(img->data,cvimgtmp->imageData,img->framesize);
  2167. cvReleaseImage(&cvimg);
  2168. cvReleaseImage(&cvimgtmp);
  2169. return true;
  2170. }