Browse Source

Z991239-6069 #comment 优化下摄像故障情况,人脸状态不能切换问题

80274480 7 months ago
parent
commit
8110e7a72b

+ 7 - 2
Module/mod_facetracking/mod_facetracking.cpp

@@ -356,9 +356,14 @@ public:
 
 	////////////////////////////////////////////////////////////////////////////////////
 	// CVideoMonitorEvent
-	void GenerateMonitorEvent(video_monitor_event_type eType)
+	void GenerateMonitorEvent(video_monitor_event_type eType, char* strMsg)
 	{
-		LogEvent(Severity_Middle, monitor_id_evtmsg[eType].evt_code, monitor_id_evtmsg[eType].evt_msg);
+		if (!strMsg) {
+			LogEvent(Severity_Middle, monitor_id_evtmsg[eType].evt_code, monitor_id_evtmsg[eType].evt_msg);
+		}
+		else {
+			LogEvent(Severity_Middle, monitor_id_evtmsg[eType].evt_code, strMsg);
+		}
 	}
 
 private:

+ 0 - 1
Module/mod_mediacontroller/brightnessinfo.h

@@ -74,7 +74,6 @@ struct BrightnessInfoHTTPRet : CHTTPRet {
 	}
 };
 
-
 int post_camera_brightness_info_list(unsigned int& uposttime, CSimpleStringA& errormsg, brightness_info_t* pinfo, int itimeout, bool bprintdbg);
 
 #endif

+ 76 - 85
Other/libfacecapture/libfacecapture.cpp

@@ -175,8 +175,6 @@ public:
 		m_bLightChange = false;
 		m_nCameraState = 0;
 		m_nLastBuf = 0;
-		//m_nCapFaceNum = 0;
-		//m_bCapFaceCompleted = false;
 		m_eMonitorState = NoBody;
 
 		memset(m_envqueuename, 0, MAX_PATH);
@@ -186,7 +184,6 @@ public:
 			strncpy(m_envqueuename, EnvironVideoName, (strlen(EnvironVideoName) > MAX_PATH) ? (MAX_PATH - 1) : strlen(EnvironVideoName));
 		}
 
-
 		if (NULL != OperateVideoName) {
 			strncpy(m_optqueuename, OperateVideoName, (strlen(OperateVideoName) > MAX_PATH) ? (MAX_PATH - 1) : strlen(OperateVideoName));
 		}
@@ -281,18 +278,14 @@ public:
 		pthread_mutex_destroy(&cs_mutex);
 #endif
 
-		if (m_pMhImg)
-		{
+		if (m_pMhImg){
 			cvReleaseImage(&m_pMhImg);
 			m_pMhImg = NULL;
 		}
 
-		if(m_pMhBuf)
-		{
-			for (int i=0;i<3;i++)
-			{
-				if (m_pMhBuf[i] != NULL)
-				{
+		if(m_pMhBuf){
+			for (int i=0;i<3;i++){
+				if (m_pMhBuf[i] != NULL){
 					cvReleaseImage(&m_pMhBuf[i]);
 					m_pMhBuf[i] = NULL;
 				}
@@ -300,31 +293,27 @@ public:
 			free(m_pMhBuf);
 		}
 
-		if (m_pProcessImg)
-		{
+		if (m_pProcessImg){
 			cvReleaseImage(&m_pProcessImg);
 			m_pProcessImg = NULL;
 		}
 
- 		if (m_pFaceCascade)
-		{
+ 		if (m_pFaceCascade){
 			cvReleaseHaarClassifierCascade(&m_pFaceCascade);
 			m_pFaceCascade = NULL;
 		}
-		if (m_pEyeCascade)
-		{
+
+		if (m_pEyeCascade){
 			cvReleaseHaarClassifierCascade(&m_pEyeCascade);
 			m_pEyeCascade = NULL;
 		}
 
-		if (m_pMouthCascade)
-		{
+		if (m_pMouthCascade){
 			cvReleaseHaarClassifierCascade(&m_pMouthCascade);
 			m_pMouthCascade = NULL;
 		}
 
-		if (m_pNoseCascade)
-		{
+		if (m_pNoseCascade){
 			cvReleaseHaarClassifierCascade(&m_pNoseCascade);
 			m_pNoseCascade = NULL;
 		}
@@ -381,7 +370,7 @@ private:
 	CAllFaceInfo m_stAllFaceInfo;
 	CAllFaceInfo m_stFaceRstStorage;
 	CBrightAdjParam m_stBrightAdjParam;			//亮度调节参数
-	MonitorStateEnum m_eMonitorState;
+	volatile MonitorStateEnum m_eMonitorState;
 	CVideoMonitorEvent* m_pHostEvent;
 	CHostApi* m_pHostApi;
 	CameraEnum m_eCamera;
@@ -526,29 +515,23 @@ private:
 	//从共享队列获取图像
 	bool GetCurImg(Clibvideoqueue* videoqueue)
 	{
-		if (videoqueue->GetVideoLens()<=0)
-		{
-			if (videoqueue == m_pEnvironVideoQueue)
-			{
-				m_pHostApi->Debug(FACECAP_DEBUG, "获取环境相机图像队列长度错误!");
+		if (videoqueue->GetVideoLens() <= 0){
+			if (videoqueue == m_pEnvironVideoQueue){
+				m_pHostApi->Debug(FACECAP_DEBUG, "环境相机图像队列为空");
 			} 
-			else if (videoqueue == m_pOperatorVideoQueue)
-			{
-				m_pHostApi->Debug(FACECAP_DEBUG, "获取操作相机图像队列长度错误!");
+			else if (videoqueue == m_pOperatorVideoQueue){
+				m_pHostApi->Debug(FACECAP_DEBUG, "操作相机图像队列为空");
 			}
 			return false;
 		}
 
-		int iSize = videoqueue->GetFrameSize(m_nImgWidth,m_nImgHeight);
+		int iSize = videoqueue->GetFrameSize(m_nImgWidth, m_nImgHeight);
 		videoq_frame* videoframe = new videoq_frame;
-		if (m_pProcessImg == NULL)
-		{
+		if (m_pProcessImg == NULL){
 			m_pProcessImg = cvCreateImage(cvSize(m_nImgWidth, m_nImgHeight), 8, 3); //创建图像
 		}
-		else
-		{
-			if((m_pProcessImg->height != m_nImgHeight)||(m_pProcessImg->width != m_nImgWidth))
-			{
+		else{
+			if((m_pProcessImg->height != m_nImgHeight)||(m_pProcessImg->width != m_nImgWidth)){
 				cvReleaseImage(&m_pProcessImg);
 				m_pProcessImg = NULL;
 				m_pProcessImg = cvCreateImage(cvSize(m_nImgWidth,m_nImgHeight), 8, 3); //创建图像
@@ -559,7 +542,7 @@ private:
 		bool bGetvideo = videoqueue->GetVideo(videoframe, 0);
 		if (!bGetvideo){
 			delete videoframe;
-			m_pHostApi->Debug(FACECAP_INFO, "从队列获取图像错误!");
+			m_pHostApi->Debug(FACECAP_DEBUG, "从队列获取图像失败");
 			return false;
 		}
 
@@ -656,7 +639,7 @@ private:
 		cvResetImageROI(m_pProcessImg);
 		cvSetImageROI(m_pProcessImg,RegionRect);
 		//特征搜索
-		CvSeq* pEyesSeq = cvHaarDetectObjects(m_pProcessImg,pCascade,pFaceStorage,1.2,2,CV_HAAR_DO_CANNY_PRUNING,cvSize(10,10));
+		CvSeq* pEyesSeq = cvHaarDetectObjects(m_pProcessImg, pCascade, pFaceStorage, 1.2, 2, CV_HAAR_DO_CANNY_PRUNING, cvSize(10,10));
 		cvResetImageROI(m_pProcessImg);
 		if((RectTemp.height!=0)&&RectTemp.width!=0)
 		{
@@ -883,7 +866,7 @@ private:
 		else
 		{
 			//保存上次人脸矩形,对当前人脸位置进行微调防止跳动
-			for(int num=0; num<m_stAllFaceInfo.nTatolFaceNum; num++)
+			for(int num = 0; num < m_stAllFaceInfo.nTatolFaceNum; num++)
 			{
 				nPreFaceNum = m_stAllFaceInfo.nTatolFaceNum;
 				m_PreFaceRect[num] = m_stAllFaceInfo.astFaceInfo[num].stRegion.stFaceRect;
@@ -891,7 +874,7 @@ private:
 			//清除上一次的记录
 			ClearInspectResult();
 		}
-		for(int i=0;i<(pfaceSeq?pfaceSeq->total:0)&&(i<MAX_FACE_NUM);i++)
+		for(int i = 0; i < (pfaceSeq?pfaceSeq->total:0)&&(i < MAX_FACE_NUM); i++)
 		{
 			m_stAllFaceInfo.nTatolFaceNum++;
 			//获取脸部矩形
@@ -926,6 +909,7 @@ private:
 			{
 				m_stAllFaceInfo.astFaceInfo[nFaceSerial].stCustomerCover.bClearFace = true;
 			}
+
 			//计算当前人脸位置,如果当前人脸位置与上次人脸位置小于偏移量则取上次人脸位置,防止人脸图像跳变
 			for (int num=0; num<nPreFaceNum; num++)
 			{
@@ -1024,6 +1008,7 @@ private:
 			return true;
 		}
 	}
+
 	//人脸检测,对上次检测到的人脸区域进行搜索
 	bool FaceDetect(CameraEnum eCamera, CvRect rect)
 	{
@@ -1334,7 +1319,7 @@ private:
 			m_pFaceStorage = cvCreateMemStorage(0);
 		}
 
-		pfaceSeq = cvHaarDetectObjects(m_pProcessImg, m_pFaceCascade, m_pFaceStorage, 1.2, 3, CV_HAAR_DO_CANNY_PRUNING, cvSize(nFaceLimit,nFaceLimit));
+		pfaceSeq = cvHaarDetectObjects(m_pProcessImg, m_pFaceCascade, m_pFaceStorage, 1.2, 3, CV_HAAR_DO_CANNY_PRUNING, cvSize(nFaceLimit, nFaceLimit));
 		if (pfaceSeq && pfaceSeq->total)
 		{
 			for(int i = 0; i < (pfaceSeq?pfaceSeq->total:0); i++)
@@ -1342,13 +1327,13 @@ private:
 				nFaceNum++;
 				//获取脸部矩形
 				CvRect* pFaceRect = (CvRect*)cvGetSeqElem(pfaceSeq, i);
+				m_pHostApi->Debug(FACECAP_DEBUG, "%s, 第%d个人,人脸框位置为:(%d, %d, %d, %d).", m_eCamera == EnvironCamera ? "环境摄像头" : "操作摄像头", nFaceNum, pFaceRect->x, pFaceRect->y, pFaceRect->width, pFaceRect->height);
 				//如果发现有人脸到达靠近区域,置有人靠近状态
 				if((pFaceRect->height >= (int)(m_nImgHeight/m_stFaceConfig.fCloseFaceSize))&&(pFaceRect->height <= (int)(m_nImgHeight/m_stFaceConfig.fOperateFaceSize)))
 				{
 					if((m_eMonitorState == NoBody) || (m_eMonitorState == SomebodyFar))
 					{
 						nCurafaceSerial = nFaceNum;
-						m_pHostApi->Debug(FACECAP_INFO, "有人靠近!");
 						m_eMonitorState = SomebodyClose;		        //进入有人靠近状态
 					}
 					m_pHostEvent->GenerateMonitorEvent(Close);		    //产生有人靠近事件
@@ -1358,7 +1343,6 @@ private:
 					if(m_eMonitorState != SomebodyOperate)
 					{
 						nCurafaceSerial = nFaceNum;
-						m_pHostApi->Debug(FACECAP_INFO, "有人进入操作距离!");
 						m_eMonitorState = SomebodyOperate;				//进入有人靠近状态
 					}
 					m_pHostEvent->GenerateMonitorEvent(EnterOperate);	//产生有人进入操作距离事件
@@ -1368,43 +1352,49 @@ private:
 					if(m_eMonitorState == NoBody)
 					{
 						nCurafaceSerial = nFaceNum;
-						m_pHostApi->Debug(FACECAP_INFO, "有人出现!");
-						m_eMonitorState = SomebodyFar;			//进入远距离有人状态
+						m_eMonitorState = SomebodyFar;					//进入远距离有人状态
 					}
 					else
 					{
-						m_pHostApi->Debug(FACECAP_INFO, "远距离,有人出现!");
-						m_eMonitorState = SomebodyFar;			//进入远距离有人状态
+						m_eMonitorState = SomebodyFar;					//进入远距离有人状态
 					}
-					m_pHostEvent->GenerateMonitorEvent(Appear);	//产生有人出现事件
+					m_pHostEvent->GenerateMonitorEvent(Appear);			//产生有人出现事件
 				}
 			}
 
 			CvRect* pFaceRect = (CvRect*)cvGetSeqElem(pfaceSeq, nCurafaceSerial);
-			m_pHostApi->Debug(FACECAP_DEBUG, "当前人脸框位置为:(%d, %d, %d, %d).", pFaceRect->x, pFaceRect->y, pFaceRect->width, pFaceRect->height);
+			m_pHostApi->Debug(FACECAP_DEBUG, "%s, 当前[序号%d]人脸框位置为:(%d, %d, %d, %d).", m_eCamera == EnvironCamera ? "环境摄像头":"操作摄像头", nCurafaceSerial, pFaceRect->x, pFaceRect->y, pFaceRect->width, pFaceRect->height);
 			//截取人脸图像,放大截取区域,截取半身头像
 			CalcUpbodyRegion(pFaceRect);
-			m_pHostApi->Debug(FACECAP_DEBUG, "截取和放大后的人脸框位置为:(%d, %d, %d, %d).", pFaceRect->x, pFaceRect->y, pFaceRect->width, pFaceRect->height);
+			m_pHostApi->Debug(FACECAP_DEBUG, "截取放大后的人脸框位置为:(%d, %d, %d, %d).", pFaceRect->x, pFaceRect->y, pFaceRect->width, pFaceRect->height);
+			//保存半身头像坐标
 			m_stAllFaceInfo.astFaceInfo[0].stRegion.stUpperBodyRect = *pFaceRect;
 		}
 		else {
-			m_pHostEvent->GenerateMonitorEvent(video_monitor_event_type::NoDetectBody);	//未检测到人脸
+		#ifdef DEVOPS_ON_PRD
+		#else
+			if (EnvironCamera == m_eCamera) {
+				m_pHostEvent->GenerateMonitorEvent(video_monitor_event_type::NoDetectBody, "上摄像头未检测到人脸");	//上摄像头未检测到人脸
+			}
+			else if(OperatorCamera == m_eCamera){
+				m_pHostEvent->GenerateMonitorEvent(video_monitor_event_type::NoDetectBody, "下摄像头未检测到人脸");	//下摄像头未检测到人脸
+			}
+			(m_eCamera == EnvironCamera) ? (m_eCamera = OperatorCamera) : (m_eCamera = EnvironCamera);
+		#endif	
 		}
 		
-		if (pfaceSeq != NULL)
-		{
+		if (pfaceSeq != NULL){
 			cvReleaseMemStorage(&pfaceSeq->storage);
 			pfaceSeq = NULL;	
 		}
 		cvResetImageROI(m_pProcessImg);
-		if(nFaceNum > 0)
-		{
+		
+		if(nFaceNum > 0){
 			//发现有人
 			m_stAllFaceInfo.nTatolFaceNum = nFaceNum;
 			return true;
 		}
-		else
-		{
+		else{
 			m_eMonitorState = NoBody;
 			return false;
 		}
@@ -1667,49 +1657,43 @@ private:
 
 	void SetUpperbodyToCenter()
 	{
-		if(m_stFaceConfig.nPrimCamera == OperatorCamera)
+		if(OperatorCamera == m_stFaceConfig.nPrimCamera)
 		{
-			if (m_pOperatorVideoQueue == NULL)
-			{
-				m_stAllFaceInfo.astFaceInfo[0].eCamera  = EnvironCamera;
+			if (m_pOperatorVideoQueue == NULL){
+				m_stAllFaceInfo.astFaceInfo[0].eCamera = EnvironCamera;
 			} 
-			else
-			{
+			else{
 				m_stAllFaceInfo.astFaceInfo[0].eCamera = OperatorCamera;
 			}
 		}
-		else
-		{
+		else{
 			m_stAllFaceInfo.astFaceInfo[0].eCamera = EnvironCamera;
 		}
 
-		int nImgWidth,nImgHeight;
-		if (m_stAllFaceInfo.astFaceInfo[0].eCamera == EnvironCamera)
-		{
-			if (m_pEnvironVideoQueue == NULL)
-			{
+		int nImgWidth = 0, nImgHeight = 0;
+		if (EnvironCamera == m_stAllFaceInfo.astFaceInfo[0].eCamera){
+			if (m_pEnvironVideoQueue == NULL){
 				return;
 			}
-			if (m_pEnvironVideoQueue->GetVideoLens()<=0)
-			{
-				m_pHostApi->Debug(FACECAP_DEBUG, "获取环境相机图像队列长度错误!");
+
+			if (m_pEnvironVideoQueue->GetVideoLens() <= 0){
+				m_pHostApi->Debug(FACECAP_DEBUG, "环境相机图像队列为空");
 				return ;
 			}
-			int size = m_pEnvironVideoQueue->GetFrameSize(nImgWidth,nImgHeight);
+			int size = m_pEnvironVideoQueue->GetFrameSize(nImgWidth, nImgHeight);
 		}
-		else if(m_stAllFaceInfo.astFaceInfo[0].eCamera == OperatorCamera)
-		{
-			if (m_pOperatorVideoQueue == NULL)
-			{
+		else if(OperatorCamera == m_stAllFaceInfo.astFaceInfo[0].eCamera){
+			if (m_pOperatorVideoQueue == NULL){
 				return;
 			}
-			if (m_pOperatorVideoQueue->GetVideoLens()<=0)
-			{
-				m_pHostApi->Debug(FACECAP_DEBUG, "获取操作相机图像队列长度错误!");
+
+			if (m_pOperatorVideoQueue->GetVideoLens() <= 0){
+				m_pHostApi->Debug(FACECAP_DEBUG, "操作相机图像队列为空");
 				return ;
 			}
-			int size = m_pOperatorVideoQueue->GetFrameSize(nImgWidth,nImgHeight);
+			int size = m_pOperatorVideoQueue->GetFrameSize(nImgWidth, nImgHeight);
 		}
+
 		m_stAllFaceInfo.astFaceInfo[0].stRegion.stUpperBodyRect.height = nImgHeight/2;
 		m_stAllFaceInfo.astFaceInfo[0].stRegion.stUpperBodyRect.width = nImgWidth/2;
 		m_stAllFaceInfo.astFaceInfo[0].stRegion.stUpperBodyRect.x = nImgWidth/4;
@@ -1807,6 +1791,8 @@ private:
 
 		uint32_t iwaittime = m_stFaceConfig.nSleepShort;
 
+		m_pHostApi->Debug(FACECAP_DEBUG, "%s:%d m_eMonitorState = %d, m_bStopVieoMonitor = %s.", __FUNCTION__, __LINE__, m_eMonitorState, m_bStopVieoMonitor? "true" : "false");
+
 		while (!m_bStopVieoMonitor)
 		{			
 			if(RvcTimeout(iwaittime))
@@ -1814,7 +1800,7 @@ private:
 				//如果摄像头没启动或故障,停止扫描,休眠2s
 				if (3 == m_nCameraState){
 					iwaittime = 2000;
-					m_pHostApi->Debug(FACECAP_INFO, "camera stop or all camera error!");
+					m_pHostApi->Debug(FACECAP_DEBUG, "camera stop or all camera error!");
 					continue;
 				}
 				//灯光变化时,清空历史记录,防止误判
@@ -1836,7 +1822,7 @@ private:
 							iwaittime = m_stFaceConfig.nSleepLong;
 						}
 						else{
-							WriteAllFaceInfo(m_stAllFaceInfo);
+							WriteAllFaceInfo(m_stAllFaceInfo);		//保存人脸坐标信息
 							iwaittime = m_stFaceConfig.nSleepMiddle;
 						}
 					}
@@ -2093,6 +2079,9 @@ private:
 				if (NULL != m_pProcessImg){
 					cvResetImageROI(m_pProcessImg);
 				}
+
+				m_pHostApi->Debug(FACECAP_DEBUG, "stop face tracking..");
+				break;
 			}
 		} 
 
@@ -2125,11 +2114,13 @@ public:
 			m_pHostApi->Debug(FACECAP_DEBUG, "create video monitor thread.");
 			m_hVieoMonitorThread = (HANDLE)_beginthreadex(NULL, 0, VideoMonitorThread, this, 0, (unsigned int*)&m_nVieoMonitorThreadId);
 			m_bStopVieoMonitor = false;
+			m_eMonitorState = MonitorStateEnum::NoBody;
 		}
 #else
 		if (0 == pthread_create(&m_videomonitorthreadid, NULL, videomonitorfunc, (void*)this)){
 			m_pHostApi->Debug(FACECAP_DEBUG, "create video monitor thread and thread id is %u.", m_videomonitorthreadid);
 			m_bStopVieoMonitor = false;
+			m_eMonitorState = MonitorStateEnum::NoBody;
 		}
 		else {
 			m_pHostApi->Debug(FACECAP_INFO, "create video monitor thread failed.");

+ 1 - 1
Other/libfacecapture/libfacecapture.h

@@ -190,7 +190,7 @@ enum video_monitor_event_type {
 class CVideoMonitorEvent
 {
 public:
-	virtual void GenerateMonitorEvent(video_monitor_event_type eType) = 0;
+	virtual void GenerateMonitorEvent(video_monitor_event_type eType, char* strMsg = NULL) = 0;
 };
 
 struct CImageFrame

+ 0 - 7
Other/unix/libvideoframework/video_common/videoutil.c

@@ -47,13 +47,6 @@ int video_frame_alloc(int width, int height, int format, video_frame *frame)
         frame->data[1] = frame->data[0] + width * height;
         frame->data[2] = frame->data[1] + width * height / 4;
     }
-	//else {
-	//	frame->linesize[0] = width * 2;
-	//	frame->data[0] = (unsigned char*)malloc(frame->linesize[0] * height);
-	//	if (frame->data[0] == NULL) {
-	//		return -1;
-	//	}
-	//}
 
     return 0;
 }