#define _WIN32_DCOM #include <SDKDDKVer.h> #include <direct.h> #include <thr/threads.h> #include <stdlib.h> #include <assert.h> #include <stdio.h> #include <tchar.h> #include <io.h> #include <time.h> #include <sys/types.h> #include <sys/stat.h> #include "..\..\lib\libcii\cii11\include\libcii.h" #include "algo.h" extern TCHAR tcLogFile[56]; // #ifdef UNICODE #define __FILET__ __FILEW__ #define __FUNCTIONT__ __FUNCTIONW__ #else #define __FILET__ __FILE__ #define __FUNCTIONT__ __FUNCTION__ #endif #define TRACE_OUT(out ,fmt,...) do{TCHAR tcDate[24],tcTime[24];_tstrdate_s(tcDate),_tstrtime_s(tcTime);\ _ftprintf_s(out, _T(" %s %s - FILE:%s - FUN:%s - LINE:%d \r\n MESSAGE: ") fmt _T("\r\n")\ ,tcDate,tcTime,__FILET__,__FUNCTIONT__,__LINE__, ##__VA_ARGS__); } while (0) // #define TRACE_LOG(fmt,...) do{ FILE* stream ; TRACE_OUT(stderr, fmt , ##__VA_ARGS__); \ if( 0 != _tfopen_s(&stream,tcLogFile,_T("a"))) break; \ TRACE_OUT(stream, fmt , ##__VA_ARGS__); \ fclose(stream); \ } while(0) #import <IsVision_9007\ISCFaceRecognize.dll> no_namespace #import <IsVision_9007\ISCFaceDetect.dll> no_namespace #import <IsVision_9007\ISCFaceRectify.dll> no_namespace #import <IsVision_9007\ISCFaceTools.dll> no_namespace #import <IsVision_9007\ISCFaceTracking.dll> no_namespace #import <IsVision_9007\ISCImageProc.dll> no_namespace #import <IsVision_9007\ISCImageQuality.dll> no_namespace #import <IsVision_9007\ISXImage.dll> no_namespace #import <IsVision_9007\ISCFaceMedia.dll> no_namespace #ifdef __cplusplus typedef struct Algo_T * LpAlgo_T; typedef struct Args_T * LpArgs_T; typedef struct Pipe_T * LpPipe_T; typedef struct Item_T * LpItem_T; #define T LpAlgo_T #define R LpArgs_T #define P LpPipe_T #define I LpItem_T #else #define T Arena_T #define R Args_T #define P Pipe_T typedef struct Algo_T *Algo_T; typedef struct Args_T *Args_T; typedef struct Pipe_T *Pipe_T; #endif #define _CT_FileName_ 0x01 #define _CT_FileData_ 0x02 #define _CT_ImageRgb_ 0x03 #define _IRecognize 0x0001 #define _ITransImage 0x0002 #define _IFaceDetect 0x0004 #define _IFaceRectify 0x0008 #define _IFaceTool 0x0010 #define _IFaceTrack 0x0020 #define _IImageProc 0x0040 #define _IImageQuality 0x0080 #define _IVisionImage 0x0100 #define _IPosition 0x0200 #define _IComImageAll 0x01FF #ifndef _THR_THREADS_H #define mtx_init(mtx, typ) InitializeSRWLock(mtx) #define mtx_destroy(mtx) __noop #define mtx_lock(mtx) AcquireSRWLockExclusive (mtx) #define mtx_unlock(mtx) ReleaseSRWLockExclusive (mtx); #define cnd_init(cnd) InitializeConditionVariable(cnd); #define cnd_destroy(cnd) __noop #define cnd_signal(cnd) WakeConditionVariable(cnd) #define cnd_wait(cnd, mtx) SleepConditionVariableSRW(cnd, mtx, INFINITE, 0) #define mtx_t_ SRWLOCK #define cnd_t_ CONDITION_VARIABLE #else #define mtx_t_ mtx_t #define cnd_t_ cnd_t #endif #define NUMBER_ALGO 7 #define NUMBER_ITEM 7 struct Global_T { long nNumberCpu; }; static volatile struct Global_T _global; TCHAR tcLogFile[56]; struct Args_T { enumTemplateType eTemplateType; PTP_WORK pwkNewTemplate; _TCHAR tcIniFile[56]; _TCHAR tcSN[56]; _TCHAR tcLicense[56]; long lTemplateSize; int iNetLogin; int used; int total; T* algo; SRWLOCK srw_; static mtx_t_ mtx_; static long once; static long count_ref; }; mtx_t_ Args_T::mtx_; long Args_T::once = 0L; long Args_T::count_ref = 0L; // struct Algo_T { IRecognizePtr m_IRecognize; ITransImagePtr m_ITransImage; IDetectPtr m_pIDetect; IFaceRectifyPtr m_pFaceRectify; IFaceToolsPtr m_pIFaceTool; IFaceTrackingPtr m_pIFaceTrack; IImageProcPtr m_pIImageProc; IImageQualityPtr m_pIImageQuality; IVisionImagePtr m_pIVisionImage; IPositionPtr m_pIPosition; unsigned long nIptrFlag; R m_lpArgs; }; typedef struct Data_T *LpData_T; typedef struct Pipe_T { LpData_T* ptr; size_t length; size_t used; size_t iget; size_t iput; mtx_t_ _mtx; cnd_t_ _cndr; cnd_t_ _cndw; }* LpPipe_T; enum eOptType{ eNewTemplate, eNewTemplate2, eCmprTemplate ,eNullOpt }; struct Item_T { T cl; eOptType opt; HANDLE event; LpPipe_T pipe; LpPipe_T pipe2; long ref_count; long ref_signal; long num_thread; long seq; bool result; static long ref_selfbuf; static I selfbuf[NUMBER_ITEM]; // union { struct { const char* srcpath; const char* wildcard; const char* dstfile; }ready; struct { unsigned char** img; long* length; long size; long size2; const char* imgtype; unsigned char** tmp; }ready2; }; void* pvResult; LpList_T list; SRWLOCK mtx_; }; long Item_T::ref_selfbuf; I Item_T::selfbuf[NUMBER_ITEM]; struct Data_T { union { struct { char* file; }result; struct { unsigned char** img; long* length; long size; const char* imgtype; long pos; }result2; }; void* pvResult; struct { double simi; long seq; long size; }vTemplate; eOptType opt; }; static P Pipe_new(size_t length) { P pi = (P)malloc(sizeof *pi); assert(pi); mtx_init(&pi->_mtx, _Mtx_plain); cnd_init(&pi->_cndr); cnd_init(&pi->_cndw); pi->ptr = (LpData_T*)calloc(length, sizeof LpData_T ); assert(pi->ptr); pi->length = length; pi->used = 0; pi->iget = 0; pi->iput = 0; return pi; } static void Pipe_put(P pi, LpData_T ptr) { assert(pi); mtx_lock(&pi->_mtx); while (pi->used >= pi->length) { cnd_wait(&pi->_cndr, &pi->_mtx); } pi->ptr[pi->iput++] = ptr; ++pi->used; if (pi->iput >= pi->length) { pi->iput = 0; } cnd_signal(&pi->_cndw); mtx_unlock(&pi->_mtx); } static void Pipe_get(P pi, LpData_T* ptr) { assert(pi); mtx_lock(&pi->_mtx); while (pi->used <= 0) { cnd_wait(&pi->_cndw, &pi->_mtx); } --pi->used; *ptr = pi->ptr[pi->iget++]; if (pi->iget >= pi->length) { pi->iget = 0; } cnd_signal(&pi->_cndr); mtx_unlock(&pi->_mtx); } static void Pipe_free(P* pi) { assert(pi && *pi); assert((*pi)->ptr); free((*pi)->ptr); mtx_destroy(&(*pi)->_mtx); cnd_destroy(&(*pi)->_cndr); cnd_destroy(&(*pi)->_cndw); free(*pi); (*pi) = nullptr; } static R Args_new() { static R ag = nullptr; if (0 == InterlockedCompareExchange(&ag->once, 1L, 0L)) { ag = (R)malloc( sizeof *ag ); ag->count_ref = 0L; ag->pwkNewTemplate = nullptr;// CreateThreadpoolWork(__ThreadCreateTemplate, ag, NULL); InitializeSRWLock(&ag->srw_); mtx_init(&ag->mtx_, _Mtx_plain); { TCHAR tcFileName[56], tcModuleFile[MAX_PATH]; SYSTEM_INFO _syInfo; GetSystemInfo(&_syInfo); _global.nNumberCpu = _syInfo.dwNumberOfProcessors; GetModuleFileName(NULL, tcModuleFile, MAX_PATH); _tsplitpath_s(tcModuleFile, NULL, 0, NULL, 0, tcFileName, 56, NULL, 0); _tmakepath_s(ag->tcIniFile, 56, NULL, NULL, tcFileName, _T("ini")); _tmakepath_s(tcLogFile, 56, NULL, NULL, tcFileName, _T("log")); if (_taccess_s(ag->tcIniFile, 0x04) == 0) { GetPrivateProfileString(_T("Register"), _T("sn"), _T(""), ag->tcSN, _countof(ag->tcSN), ag->tcIniFile); GetPrivateProfileString(_T("Register"), _T("license"), _T(""), ag->tcLicense, _countof(ag->tcLicense), ag->tcIniFile); ag->iNetLogin = GetPrivateProfileInt(_T("Register"), _T("netlogin"), 1, ag->tcIniFile); ag->eTemplateType = (enumTemplateType)GetPrivateProfileInt(_T("Parameters"), _T("TemplateType"), 2, ag->tcIniFile); } else { ag->iNetLogin = 1; ag->eTemplateType = (enumTemplateType)2; _tcscpy_s(ag->tcSN, _T("")); _tcscpy_s(ag->tcLicense, _T("")); } } ag->total = _global.nNumberCpu; ag->used = 0; ag->algo = (T*)malloc(ag->total * sizeof T); _tprintf(_T("+++++++++++++++++++++++++++++++++++++++++++++++++++++++Args_new.\r\n")); } InterlockedIncrement(&ag->count_ref); return ag; } static T Algo_get(R ag) { T al; mtx_lock(&ag->mtx_); if (ag->used > 0) al = ag->algo[--ag->used]; else al = nullptr; mtx_unlock(&ag->mtx_); return al; } static bool Algo_put(T al) { R ag = al->m_lpArgs; mtx_lock(&ag->mtx_); if (ag->used < ag->total && ag->count_ref > 0 ) ag->algo[ag->used++] = al; else al = nullptr; mtx_unlock(&ag->mtx_); return al != nullptr; } static I Item_get() { I im = nullptr; mtx_lock(&Args_T::mtx_); if (Item_T::ref_selfbuf > 0) { im = Item_T::selfbuf[--Item_T::ref_selfbuf]; im->ref_count = 0; im->seq = 0; im->cl = nullptr; im->result = false; im->pipe->used = 0; im->pipe->iget = 0; im->pipe->iput = 0; im->pipe2->used = 0; im->pipe2->iget = 0; im->pipe2->iput = 0; } else im = nullptr; mtx_unlock(&Args_T::mtx_); return im; } static bool Item_put(I im) { mtx_lock(&Args_T::mtx_); if (Item_T::ref_selfbuf < NUMBER_ITEM && Args_T::count_ref > 0) Item_T::selfbuf[Item_T::ref_selfbuf++] = im; else im = nullptr; mtx_unlock(&Args_T::mtx_); return im != nullptr; } static void Item_free(I *im) { assert(im && *im); if (!Item_put(*im)) { CloseHandle((*im)->event); Pipe_free(&(*im)->pipe); Pipe_free(&(*im)->pipe2); free(*im); (*im) = nullptr; } } static I Item_new() { I im = Item_get(); if (nullptr == im) { im = (I)malloc(sizeof *im); im->ref_count = 0; im->seq = 0; im->cl = nullptr; im->result = false; InitializeSRWLock(&im->mtx_); im->pipe = Pipe_new(3702); im->pipe2 = Pipe_new(3702); im->event = CreateEvent(NULL, FALSE, FALSE, NULL); } return im; } static void Args_free(R* ag) { long ref; assert(ag && *ag); ref = InterlockedDecrement(&(*ag)->count_ref); if (ref == 0) { T al;// this code is not excute I im; assert(ref == 0); InterlockedExchange(&(*ag)->once, 0L); while (al = Algo_get(*ag)) { Algo_free(&al); } while (im = Item_get()) { Item_free(&im); } mtx_destroy(&(*ag)->mtx_); free((*ag)->algo); free(*ag); (*ag) = nullptr; _tprintf(_T("-------------------------------------------------------Args_free.\r\n")); } } T Algo_new() { R ag = Args_new(); T al = Algo_get(ag); if (!al) { CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_SPEED_OVER_MEMORY); al = new Algo_T; al->nIptrFlag = 0UL; al->m_lpArgs = ag; } assert(al); return al; } static bool NewTemplateFile( const char* filename) { size_t len; if (0 == _access(filename, 0x06)) { return true; } if ( 0 < (len = strlen(filename))) { char* tmpbuf, *p, c; tmpbuf = (char*)malloc(len + 1); strcpy_s(tmpbuf, len + 1, filename); for (p = tmpbuf; *p; ++p) { if ('\\' != *p && '/' != *p) { continue; } c = *++p; *p = '\0'; if ((_access(tmpbuf, 0)) != 0) { if (0 != _mkdir(tmpbuf)) { break; } } *p = c; } { bool bret; FILE* file; bret = (0 == _tfopen_s(&file, tmpbuf, _T("a"))); free(tmpbuf); fclose(file); return bret; } } else return false; } static bool IsMatched(CONST TCHAR* p, CONST TCHAR* q) { CONST TCHAR *r, *z, *x = _T(""); for (r = p; *p; ++p) if (*p == '\\') r = p + 1; else if (*p == '.') x = p; z = r; while (*q) { while (*q == '|')q++; if (*q == '*') { r = x; while (*++q != '.' && *q); } while (tolower(*q) == tolower(*r) && *r) r++, q++; if (*q == '*' || !*r && (!*q || *q == '|')) { return true; } while (*q != '|' && *q)++q; r = z; } return false; } static void FetchFile(TCHAR* tcFile, size_t nChars, CONST TCHAR* tcWard, P pi) { _tfinddata_t _tfddt; intptr_t intptr = _tfindfirst(tcFile, &_tfddt); if (-1 == intptr) { return; } do { tcFile[nChars] = '\0'; if (_tfddt.attrib & _A_SUBDIR ) { if (_tfddt.name[0] != '.') { _tcscat_s(tcFile, MAX_PATH, _tfddt.name); _tcscat_s(tcFile, MAX_PATH, _T("\\")); _tcscat_s(tcFile, MAX_PATH, _T("*.*")); FetchFile(tcFile, nChars + 1 + _tcslen(_tfddt.name), tcWard, pi); } } else if (IsMatched(_tfddt.name, tcWard)) { LpData_T ptr = (LpData_T)malloc(sizeof(*ptr)); size_t length = nChars + _tcslen(_tfddt.name) + 1; ptr->result.file = new char[length];// (_TCHAR*)malloc( length * sizeof _TCHAR); _tcscat_s(tcFile, MAX_PATH, _tfddt.name); _tcscpy_s(ptr->result.file, length, tcFile); ptr->opt = eNewTemplate; Pipe_put(pi, ptr); } } while (0 == _tfindnext(intptr, &_tfddt)); _findclose(intptr); } static void GetSubDir(CONST TCHAR* tcFile, CONST TCHAR *tcWard, P pi) { TCHAR tcFileName[MAX_PATH], *pEnd; //if (_taccess_s(ag->tcIniFile, 0x04) == 0) // struct stat s_buf; stat(tcFile, &s_buf); /*判断输入的文件路径是否目录,若是目录,则往下执行,分析目录下的文件*/ if ( s_buf.st_mode&_S_IFDIR) { _tcscpy_s(tcFileName, tcFile); (pEnd = _tcsrchr(tcFileName, '\\'))[1] = '\0'; _tcscat_s(tcFileName, _T("*.*")); FetchFile(tcFileName, pEnd - tcFileName + 1, tcWard, pi); } else if (s_buf.st_mode&_S_IFREG) { TCHAR tcFileExt[24]; _tsplitpath_s(tcFile, NULL, 0, NULL, 0, tcFileName, MAX_PATH, tcFileExt, 24); _tmakepath_s(tcFileName, MAX_PATH, NULL, NULL, tcFileName, tcFileExt); if (IsMatched(tcFileName, tcWard)) { LpData_T ptr = (LpData_T)malloc(sizeof(*ptr)); ptr->result.file = new char[MAX_PATH]; _tcscpy_s(ptr->result.file, MAX_PATH, tcFile); ptr->opt = eNewTemplate; Pipe_put(pi, ptr); } } Pipe_put(pi, nullptr); } static void ComObjectInstance(T al, unsigned long nIptrFlag) { HRESULT hr; assert(al); if ((nIptrFlag & _IRecognize) && !(_IRecognize & al->nIptrFlag)) { al->nIptrFlag &= ~_IRecognize; if (FAILED(hr = al->m_IRecognize.CreateInstance(__uuidof(Recognize)))) { TRACE_LOG(_T("_IRecognize接口创建失败:%#08x"), hr); } else if (FAILED(hr = al->m_IRecognize->SetModelType((enumFrameModelType)al->m_lpArgs->eTemplateType))) { TRACE_LOG(_T("_IRecognize::SetModelType:ErrCode = %d"), al->m_IRecognize->GetLastError()); } else { if (al->m_lpArgs->iNetLogin && al->m_IRecognize->Initialize(VARIANT_TRUE) == VARIANT_TRUE || !al->m_lpArgs->iNetLogin && (((0 == _tcslen(al->m_lpArgs->tcSN) || 0 == _tcslen(al->m_lpArgs->tcLicense)) && al->m_IRecognize->Initialize(VARIANT_FALSE) == VARIANT_TRUE) || al->m_IRecognize->SetRegisteredInfo(_bstr_t(al->m_lpArgs->tcSN), _bstr_t(al->m_lpArgs->tcLicense)) == VARIANT_TRUE)) { al->nIptrFlag |= _IRecognize; al->m_lpArgs->lTemplateSize = al->m_IRecognize->GetTemplateSize(al->m_lpArgs->eTemplateType); TRACE_LOG(_T("_IRecognize:GetVersion() = %s,_IRecognize::GetTemplateSize() = %d"), (const char*)al->m_IRecognize->GetVersion(), al->m_lpArgs->lTemplateSize); } else { TRACE_LOG(_T("_IRecognize接口初始化失败:ErrCode = %d"), al->m_IRecognize->GetLastError()); } } } if ((nIptrFlag & _ITransImage) && !(_ITransImage & al->nIptrFlag)) { if (FAILED(hr = al->m_ITransImage.CreateInstance(__uuidof(TransImage)))) { TRACE_LOG(_T("_ITransImage接口创建失败:%#08x"), hr); al->nIptrFlag &= ~_ITransImage; } else { al->nIptrFlag |= _ITransImage; TRACE_LOG(_T("_ITransImage:CreateInstance Finished.")); } } if ((nIptrFlag & _IFaceDetect) && !(_IFaceDetect & al->nIptrFlag)) { al->nIptrFlag &= ~_IFaceDetect; if (FAILED(hr = al->m_pIDetect.CreateInstance(__uuidof(Detect)))) { TRACE_LOG(_T("_IFaceDetect接口创建失败:%#08x"), hr); } else { if (al->m_lpArgs->iNetLogin && al->m_pIDetect->Initialize(VARIANT_TRUE) == VARIANT_TRUE || !al->m_lpArgs->iNetLogin && (((0 == _tcslen(al->m_lpArgs->tcSN) || 0 == _tcslen(al->m_lpArgs->tcLicense)) && al->m_pIDetect->Initialize(VARIANT_FALSE) == VARIANT_TRUE) || al->m_pIDetect->SetRegisteredInfo(_bstr_t(al->m_lpArgs->tcSN), _bstr_t(al->m_lpArgs->tcLicense)) == VARIANT_TRUE)) { al->nIptrFlag |= _IFaceDetect; TRACE_LOG(_T("_IFaceDetect:GetVersion() = %s"), (const char*)al->m_pIDetect->GetVersion()); } else { TRACE_LOG(_T("_IFaceDetect接口初始化失败:ErrCode = %d"), al->m_pIDetect->GetLastError()); } } } if ((nIptrFlag & _IFaceRectify) && !(_IFaceRectify & al->nIptrFlag)) { if (FAILED(hr = al->m_pFaceRectify.CreateInstance(__uuidof(FaceRectify)))) { TRACE_LOG(_T("_IFaceRectify接口创建失败:%#08x"), hr); al->nIptrFlag &= ~_IFaceRectify; } else { al->nIptrFlag |= _IFaceRectify; TRACE_LOG(_T("_IFaceRectify:CreateInstance Finished.")); } } if ((nIptrFlag & _IFaceTool) && !(_IFaceTool & al->nIptrFlag)) { if (FAILED(hr = al->m_pIFaceTool.CreateInstance(__uuidof(FaceTools)))) { TRACE_LOG(_T("_IFaceTool接口创建失败:%#08x"), hr); al->nIptrFlag &= ~_IFaceTool; } else { al->nIptrFlag |= _IFaceTool; TRACE_LOG(_T("_IFaceTool:CreateInstance Finished.")); } } if ((nIptrFlag & _IFaceTrack) && !(_IFaceTrack & al->nIptrFlag)) { if (FAILED(hr = al->m_pIFaceTrack.CreateInstance(__uuidof(FaceTracking)))) { TRACE_LOG(_T("_IFaceTrack接口创建失败:%#08x"), hr); al->nIptrFlag &= ~_IFaceTrack; } else { al->nIptrFlag |= _IFaceTrack; TRACE_LOG(_T("_IFaceTrack:CreateInstance Finished.")); } } if ((nIptrFlag & _IImageProc) && !(_IImageProc & al->nIptrFlag)) { if (FAILED(hr = al->m_pIImageProc.CreateInstance(__uuidof(ImageProc)))) { TRACE_LOG(_T("_IImageProc接口创建失败:%#08x"), hr); al->nIptrFlag &= ~_IImageProc; } else { al->nIptrFlag |= _IImageProc; TRACE_LOG(_T("_IImageProc:CreateInstance Finished.")); } } if ((nIptrFlag & _IImageQuality) && !(_IImageQuality & al->nIptrFlag)) { if (FAILED(hr = al->m_pIImageQuality.CreateInstance(__uuidof(ImageQuality)))) { TRACE_LOG(_T("_IImageQuality接口创建失败:%#08x"), hr); al->nIptrFlag &= ~_IImageQuality; } else { al->nIptrFlag |= _IImageQuality; TRACE_LOG(_T("_IImageQuality:CreateInstance Finished.")); } } if ((nIptrFlag & _IVisionImage) && !(_IVisionImage & al->nIptrFlag)) { if (FAILED(hr = al->m_pIVisionImage.CreateInstance(__uuidof(VisionImage)))) { TRACE_LOG(_T("_IFaceTrack接口创建失败:%#08x"), hr); al->nIptrFlag &= ~_IVisionImage; } else { al->nIptrFlag |= _IVisionImage; TRACE_LOG(_T("_IFaceTrack:CreateInstance Finished.")); } } if ((nIptrFlag & _IPosition) && !(_IPosition & al->nIptrFlag)) { if (FAILED(hr = al->m_pIPosition.CreateInstance(__uuidof(Position)))) { TRACE_LOG(_T("_IPosition接口创建失败:%#08x"), hr); al->nIptrFlag &= ~_IPosition; } else { al->nIptrFlag |= _IPosition; } } } static void ComObjectRelease(T al, unsigned long nIptrFlag) { if ((nIptrFlag & _IRecognize) && (_IRecognize & al->nIptrFlag)) { al->m_IRecognize->Uninitialize(); al->m_IRecognize.Release(); al->nIptrFlag &= ~_IRecognize; } if ((nIptrFlag & _ITransImage) && (_ITransImage & al->nIptrFlag)) { al->m_ITransImage.Release(); al->nIptrFlag &= ~_ITransImage; } if ((nIptrFlag & _IFaceDetect) && (_ITransImage & al->nIptrFlag)) { al->m_pIDetect->Uninitialize(); al->m_pIDetect.Release(); al->nIptrFlag &= ~_IFaceDetect; } if ((nIptrFlag & _IFaceRectify) && (_ITransImage & al->nIptrFlag)) { al->m_pFaceRectify.Release(); al->nIptrFlag &= ~_IFaceRectify; } if ((nIptrFlag & _IFaceTool) && (_ITransImage & al->nIptrFlag)) { al->m_pIFaceTool->Uninitialize(); al->m_pIFaceTool.Release(); al->nIptrFlag &= ~_IFaceTool; } if ((nIptrFlag & _IFaceTrack) && (_ITransImage & al->nIptrFlag)) { al->m_pIFaceTrack.Release(); al->nIptrFlag &= ~_IFaceTrack; } if ((nIptrFlag & _IImageProc) && (_ITransImage & al->nIptrFlag)) { al->m_pIImageProc.Release(); al->nIptrFlag &= ~_IImageProc; } if ((nIptrFlag & _IImageQuality) && (_ITransImage & al->nIptrFlag)) { al->m_pIImageQuality->Uninitialize(); al->m_pIImageQuality.Release(); al->nIptrFlag &= ~_IImageQuality; } if ((nIptrFlag & _IVisionImage) && (_ITransImage & al->nIptrFlag)) { al->m_pIVisionImage.Release(); al->nIptrFlag &= ~_IVisionImage; } if ((nIptrFlag & _IPosition) && (_IPosition & al->nIptrFlag)) { al->m_pIPosition.Release(); al->nIptrFlag &= ~_IPosition; } } static long Algo_create_template(T al, char* lpData, unsigned char** ppTemplate, int *iTemplateSize, int DataType, long Datalength) { unsigned char* pTemplate; assert(al && lpData && ppTemplate); if (!(al->nIptrFlag & _ITransImage)) { ComObjectInstance(al, _ITransImage); } if (!(al->nIptrFlag & _ITransImage)) { return (-1); } if (!(al->nIptrFlag & _IFaceDetect)) { ComObjectInstance(al, _IFaceDetect); } if (!(al->nIptrFlag & _IFaceDetect)) { return (-1); } if (!(al->nIptrFlag & _IPosition)) { ComObjectInstance(al, _IPosition); } if (!(al->nIptrFlag & _IPosition)) { return (-1); } switch (DataType) { case _CT_FileName_: if (VARIANT_TRUE != al->m_ITransImage->ReadImageFile(_bstr_t(lpData), enumFileType::TRANS_FILE_TYPE_UNKNOWN)) { TRACE_LOG(_T("加载图像文件失败, ErrCode = %d"), GetLastError()); return (-1); } break; case _CT_FileData_: if (VARIANT_TRUE != al->m_ITransImage->ReadImageData((unsigned char*)lpData, Datalength, enumFileType::TRANS_FILE_TYPE_UNKNOWN)) { TRACE_LOG(_T("加载图像文件失败, ErrCode = %d"), GetLastError()); return (-1); } break; case _CT_ImageRgb_: default: TRACE_LOG(_T("建模数据源类型不明确!")); return (-1); } al->m_pIPosition->Clear(); if (VARIANT_TRUE != al->m_pIDetect->FindFace(al->m_ITransImage, al->m_pIPosition)) { TRACE_LOG(_T("检测人脸失败, ErrCode = %d"), al->m_pIDetect->GetLastError()); return (-1); } *iTemplateSize = Algo_template_size(al); if (*iTemplateSize < 0) { return (-1); } pTemplate = new unsigned char[*iTemplateSize * al->m_pIPosition->GetlFaceNum()]; if (VARIANT_TRUE != al->m_IRecognize->CreateTemplate(al->m_ITransImage, al->m_pIPosition , enumTemplateType::TEMPLATE_TYPE_GENERAL, al->m_pIPosition->GetlFaceNum(), pTemplate)) { TRACE_LOG(_T("创建模版失败, ErrCode = %d"), al->m_IRecognize->GetLastError()); delete[] pTemplate; return (-1); } *ppTemplate = pTemplate; return al->m_pIPosition->GetlFaceNum(); } static long Algo_create_template(T al, const char* lpFile, unsigned char** ppTemplate, int *iTemplateSize) { return Algo_create_template(al, const_cast<char*>(lpFile), ppTemplate, iTemplateSize, _CT_FileName_, 0); } //#define _tprintf static void __stdcall __TrySubmitCompareTemplate( PTP_CALLBACK_INSTANCE instance, PVOID pvctx) { I im = (I)pvctx; T al = Algo_new(); R ag = al->m_lpArgs; P in = im->pipe; P out = im->pipe2; LpData_T ptr = nullptr; LpData_T ptr2 = nullptr; eOptType eOpt = im->opt; PSRWLOCK mtx_ = &im->cl->m_lpArgs->srw_; unsigned char *pTemplate = nullptr; unsigned char **tmpbuf, **vtmp, *tmp, **vtmp2; double *simibuf; long i, j, k, size, size2, pos, *length; bool result = im->result; long seq = InterlockedIncrement(&im->seq); CallbackMayRunLong(instance); for (;;) { Pipe_get(in, &ptr); if (ptr == nullptr) { Pipe_put(in, nullptr); //_tprintf(_T("ptr %d == nullptr\r\n"),i); if (result) { Pipe_put(out, nullptr); } break; } vtmp = ptr->result2.img; vtmp2 = im->ready2.tmp; size = ptr->result2.size; size2 = im->ready2.size2; pos = ptr->result2.pos; simibuf = &((double*)im->pvResult)[pos]; for (i = 0, k = 0; i < size; ++i) { tmpbuf = &vtmp[pos + i]; pTemplate = tmpbuf[0]; for (j = 0; j < size2; ++j, ++k) { tmp = vtmp2[j]; simibuf[k] = k; #ifndef _DEBUG al->m_IRecognize->CompareTemplate(pTemplate, tmp, 0); #endif // printf("simibuf[%d]= %f\r\n",k+pos, simibuf[k]); } } if (result) { } else { free(ptr); } } Algo_free(&al); assert(im->ref_signal >= 0); if (InterlockedDecrement(&im->ref_signal) == 0) { SetEventWhenCallbackReturns(instance, im->event); //_tprintf(_T("%s: SetEventWhenCallbackReturns\r\n"), __FUNCTION__); } //_tprintf(_T("%s[%d] - Type[%d] :Exit\r\n"), __FUNCTION__,seq, im->opt); } static void __stdcall __TrySubmitCreateTemplate( PTP_CALLBACK_INSTANCE instance, PVOID pvctx) { I im = (I)pvctx; T al = Algo_new(); R ag = al->m_lpArgs; P in = im->pipe, out = im->pipe2; LpData_T ptr = nullptr; LpData_T ptr2 = nullptr; eOptType eOpt = im->opt; PSRWLOCK mtx_ = &ag->srw_; unsigned char *pTemplate = nullptr; int iTemplateSize = 0; bool result = im->result; long seq = InterlockedIncrement(&im->seq); CallbackMayRunLong(instance); for (;;) { Pipe_get(in, &ptr); if (ptr == nullptr) { Pipe_put(in, nullptr); //_tprintf(_T("ptr %d == nullptr\r\n"),i); if (result) { Pipe_put(out, nullptr); } break; } switch (eOpt) { case eNewTemplate: { LpList_T *list = &im->list; char* file = ptr->result.file; #ifndef _DEBUG Algo_create_template(al,file , &pTemplate, &iTemplateSize); #else _tprintf(_T(" %s iTemplateSize %d\r\n"), file,iTemplateSize); pTemplate = (unsigned char *)ptr->result.file; #endif if (result) { ptr->pvResult = pTemplate; Pipe_put(out, ptr); } else { AcquireSRWLockExclusive(mtx_); *list = List_push(*list, pTemplate); *list = List_push(*list, file); ReleaseSRWLockExclusive(mtx_); free(ptr); } } break; case eNewTemplate2: { unsigned char **r_pvbuf, **pvTemplate, **img = ptr->result2.img; const char* imgtype = ptr->result2.imgtype; long* length = ptr->result2.length, size = ptr->result2.size; long pos = ptr->result2.pos, i = 0; pvTemplate = &((unsigned char **)im->pvResult)[pos]; for (; i < size; ++i) { r_pvbuf = &img[i]; #ifndef _DEBUG Algo_create_template(al, (char *)r_pvbuf[0],&pTemplate, &iTemplateSize, _CT_FileData_, length[i]); #else pTemplate = r_pvbuf[0]; #endif pvTemplate[i] = pTemplate; } if (result) { ptr->vTemplate.seq = pos; ptr->vTemplate.size = size; ptr->pvResult = pvTemplate; Pipe_put(out, ptr); } else { free(ptr); } } default: break; }//switch }// for assert(im->ref_signal >= 0); Algo_free(&al); if (InterlockedDecrement(&im->ref_signal) == 0) { SetEventWhenCallbackReturns(instance, im->event); // _tprintf(_T("______________________ SetEventWhenCallbackReturns[%d]:Exit\r\n"),seq); } // _tprintf(_T("__ThreadCreateTemplate[%d]:Exit\r\n"), seq); } static void __stdcall __TrySubmitResultThread( PTP_CALLBACK_INSTANCE instance, PVOID pvctx) { I im = (I)pvctx; P pi = im->pipe2; T al = im->cl; eOptType eOpt = im->opt; LpData_T ptr = nullptr; PSRWLOCK mtx_ = &al->m_lpArgs->srw_; unsigned char *pTemplate = nullptr; long seq = InterlockedIncrement(&im->seq); CallbackMayRunLong(instance); switch (seq) { case 1: for (;;) { Pipe_get(pi, &ptr); if (ptr == nullptr) { Pipe_put(pi, nullptr); break; } switch (eOpt) { case eNewTemplate: { LpList_T *list = &im->list; AcquireSRWLockExclusive(mtx_); *list = List_push(*list, ptr->pvResult); *list = List_push(*list, ptr->result.file); ReleaseSRWLockExclusive(mtx_); }break; case eNewTemplate2: { unsigned char **pvTemplate = (unsigned char **)im->pvResult; // }break; case eCmprTemplate: { double *vsimi = (double *)im->pvResult; vsimi[ptr->vTemplate.seq] = ptr->vTemplate.simi; } default: break; } // switch free(ptr); } // for default: break; } // switch assert(im->ref_signal >= 0); if (InterlockedDecrement(&im->ref_signal) == 0) { SetEventWhenCallbackReturns(instance, im->event); // _tprintf(_T("+++++++++++++SetEventWhenCallbackReturns[%d]:Exit\r\n"), seq); } //_tprintf(_T("__TrySubmitThread[%d] - Type[%d] :Exit\r\n"), seq, im->opt); } static void ReaySubmitThread(I im, PTP_SIMPLE_CALLBACK __pfTrySubmit) { T al = (T)im->cl; P out = im->pipe; eOptType eOpt = im->opt; long i, block, size, *length = nullptr; long nThrd = 0; im->num_thread = 2; im->ref_signal = im->num_thread; if (im->result) { ++nThrd; TrySubmitThreadpoolCallback(__TrySubmitResultThread, im, NULL); // _tprintf(_T("__TrySubmitResultThread :Start\r\n")); } for (; nThrd < im->ref_signal; ++nThrd) { TrySubmitThreadpoolCallback(__pfTrySubmit, im, NULL); // _tprintf(_T("__TrySubmitCreateTemplate :Start\r\n")); } switch (eOpt) { case eNewTemplate: GetSubDir(im->ready.srcpath, im->ready.wildcard, out); break; case eNewTemplate2: length = im->ready2.length; case eCmprTemplate: { unsigned char** img = im->ready2.img; const char* imgtype = im->ready2.imgtype; size = im->ready2.size; block = size / max(1, nThrd); i = 0; if (block >= nThrd) { for (; i < nThrd; ++i) { LpData_T ptr = (LpData_T)malloc(sizeof(*ptr)); ptr->opt = eOpt; ptr->result2.imgtype = imgtype; ptr->result2.size = block; ptr->result2.length = eCmprTemplate != eOpt ? &length[i] : nullptr; ptr->result2.pos = block * i; ptr->result2.img = &img[block * i]; Pipe_put(out, ptr); } size = im->ready2.size % max(1, nThrd); i = block * i; size += i; img = &img[i]; } for (; i < size; ++i) { LpData_T ptr = (LpData_T)malloc(sizeof(*ptr)); ptr->opt = eOpt; ptr->result2.imgtype = imgtype; ptr->result2.size = 1; ptr->result2.pos = i; ptr->result2.length = length ? &length[i] : nullptr; ptr->result2.img = &img[i]; Pipe_put(out, ptr); } Pipe_put(out, nullptr); } default: break; } WaitForSingleObject(im->event, INFINITE); // _tprintf(_T("ReaySubmitThread :End\r\n")); //_tprintf(_T("CloseHandle()[%d]\r\n"), InterlockedDecrement(&watch_1)); //IdleCpu_put(nThreadNum); } void Algo_free(T *al) { R ag = (*al)->m_lpArgs; if (!Algo_put(*al)) { ComObjectRelease(*al, _IComImageAll); delete (*al); (*al) = nullptr; CoUninitialize(); } Args_free(&ag); } long Algo_template_size(T al) { assert(al); if (!(al->nIptrFlag & _IRecognize)) { ComObjectInstance(al, _IRecognize); } if (!(al->nIptrFlag & _IRecognize)) { return (-1); } return al->m_lpArgs->lTemplateSize; } long Algo_template_type(T al, long type) { R ag; HRESULT hr; enumTemplateType etype; assert(al); if (!(al->nIptrFlag & _IRecognize)) { ComObjectInstance(al, _IRecognize); } if (!(al->nIptrFlag & _IRecognize)) { return (-1); } ag = al->m_lpArgs; assert(ag); switch (type) { case 1: etype = TEMPLATE_TYPE_SIMPLE; break; case 2: etype = TEMPLATE_TYPE_GENERAL; break; case 4: etype = TEMPLATE_TYPE_COMPLEX; break; default: return (-1); } if (FAILED(hr = al->m_IRecognize->SetModelType((enumFrameModelType)etype))) { TRACE_LOG(_T("_IRecognize::SetModelType:ErrCode = %d"), al->m_IRecognize->GetLastError()); } else { enumTemplateType retv = ag->eTemplateType; ag->eTemplateType = etype; switch (retv) { case TEMPLATE_TYPE_SIMPLE : return 1; case TEMPLATE_TYPE_GENERAL : return 2; case TEMPLATE_TYPE_COMPLEX : return 4; default: return (-1); } } } unsigned char** Algo_create_template(T al, const char* path,long* size, const char* file, const char *ward ) { I im = Item_new(); unsigned char** pvTemplate; assert(al); im->ready.srcpath = path;// lpPath; im->ready.wildcard = ward; im->ready.dstfile = file; im->opt = eNewTemplate; im->cl = al; im->list = nullptr; im->result = file && file[0] != '\0'; ReaySubmitThread(im, __TrySubmitCreateTemplate); AcquireSRWLockExclusive(&al->m_lpArgs->srw_); *size = List_length(im->list) / 2 ; pvTemplate = (unsigned char**)List_toArray(im->list, nullptr); List_free(&im->list); ReleaseSRWLockExclusive(&al->m_lpArgs->srw_); Item_free(&im); return pvTemplate; } unsigned char** Algo_create_template(T al, unsigned char* img[], long length[], long size, const char* file, const char* imgtype) { I im = Item_new(); unsigned char** pvTemplate; assert(al); pvTemplate = new unsigned char* [size]; memset(pvTemplate, 0, size * sizeof *pvTemplate); im->ready2.img = img;// lpPath; im->ready2.length = length; im->ready2.size = size; im->ready2.imgtype = imgtype; im->pvResult = pvTemplate; im->opt = eNewTemplate2; im->cl = al; im->result = file && file[0] != '\0' ; ReaySubmitThread(im, __TrySubmitCreateTemplate); Item_free(&im); // _tprintf(_T("free(lpItem)[]\r\n")); return pvTemplate; } double* Algo_compare_template(T al, unsigned char* vtmp[], long size, unsigned char* vtmp2[], long size2) { I im = Item_new(); double * vsimi = nullptr; assert(al && vtmp2 && vtmp); vsimi = new double[size * size2]; memset(vsimi, 0, size * size2 * sizeof *vsimi); im->ready2.img = vtmp;// lpPath; im->ready2.length = nullptr; im->ready2.size = size; im->ready2.size2 = size2; im->ready2.imgtype = ""; im->ready2.tmp = vtmp2; im->pvResult = vsimi; im->opt = eCmprTemplate; im->cl = al; ReaySubmitThread(im, __TrySubmitCompareTemplate); Item_free(&im); //_tprintf(_T("free(lpItem)[]\r\n")); return vsimi; }