libfacecapture.cpp 88 KB

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