+
+ 9.4498615586013912e-001 1.0133313172564584e-001
+ 2.7968245980155189e+000 9.1128408462592958e-004
+ 8.6220615318591198e-001 1.7946323882964407e+001
+ -2.3245294578089215e-016 3.8857805861880479e-016
+ 1.0000000000000107e+000
+
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/CWModels/mdl.bin b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/CWModels/mdl.bin
new file mode 100644
index 0000000..17f6fe8
Binary files /dev/null and b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/CWModels/mdl.bin differ
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/CWModels/nirLiveness_model_20181102_pc.bin b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/CWModels/nirLiveness_model_20181102_pc.bin
new file mode 100644
index 0000000..156fd51
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/CWModels/nirLiveness_model_20181102_pc.bin
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:19cbcc650ec721a269e8c832c419ab65613b57bfd6884f9fc153e1f5ae9b3ae5
+size 53360172
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/CWModels/pca_proj.bin b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/CWModels/pca_proj.bin
new file mode 100644
index 0000000..e2c0aef
Binary files /dev/null and b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/CWModels/pca_proj.bin differ
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo/Demo.vcxproj b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo/Demo.vcxproj
new file mode 100644
index 0000000..65c614a
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo/Demo.vcxproj
@@ -0,0 +1,245 @@
+锘
+
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release_Xp
+ Win32
+
+
+ Release_Xp
+ x64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ {C0F38F1A-A697-4F2B-BA4C-37041C2ABBC0}
+ Win32Proj
+ Demo
+
+
+
+ Application
+ true
+ v110
+ Unicode
+
+
+ Application
+ true
+ v110
+ Unicode
+
+
+ Application
+ false
+ v110
+ true
+ Unicode
+
+
+ Application
+ false
+ v110_xp
+ true
+ Unicode
+
+
+ Application
+ false
+ v110
+ true
+ Unicode
+
+
+ Application
+ false
+ v110
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ $(SolutionDir)$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)$(Platform)\$(Configuration)\
+
+
+ false
+ ..\build_32\bin\
+
+
+ false
+ ..\build_xp\bin\
+
+
+ false
+ ..\build_64\bin\
+
+
+ false
+ ..\build_64\bin\
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+ true
+ ../CWFaceSDK;opencv2411/include;opencv2411/include/opencv;opencv2411/include/opencv2;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ ..\build_32\lib.debug;lib32
+ CWFaceSDKd.lib;opencv_core2411d.lib;opencv_highgui2411d.lib;opencv_imgproc2411d.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+ true
+ ../CWFaceSDK;opencv2411/include;opencv2411/include/opencv;opencv2411/include/opencv2;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ ..\build_64\lib.debug;lib64;%(AdditionalLibraryDirectories)
+ CWFaceSDKd.lib;opencv_core2411d.lib;opencv_highgui2411d.lib;opencv_imgproc2411d.lib;%(AdditionalDependencies)
+
+
+
+
+ Level3
+
+
+ Disabled
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;CWFACESDK_EXPORTS;%(PreprocessorDefinitions)
+ true
+ ../CWFaceSDK;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ true
+ true
+ ..\build_32\lib
+ CWFaceSDK.lib;%(AdditionalDependencies)
+
+
+
+
+ Level3
+
+
+ Disabled
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+ true
+ ../CWFaceSDK;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ true
+ true
+ ..\build_xp\lib
+ CWFaceSDK.lib;%(AdditionalDependencies)
+
+
+
+
+ Level3
+
+
+ Disabled
+ true
+ true
+ WIN32;DEMO_X64;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+ true
+ ../CWFaceSDK;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ true
+ true
+ ..\build_64\lib
+ CWFaceSDK.lib;%(AdditionalDependencies)
+
+
+
+
+ Level3
+
+
+ Disabled
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+ true
+ ../CWFaceSDK;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ true
+ true
+ ..\build_64\lib
+ CWFaceSDK.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo/Demo.vcxproj.filters b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo/Demo.vcxproj.filters
new file mode 100644
index 0000000..2cc8cea
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo/Demo.vcxproj.filters
@@ -0,0 +1,22 @@
+锘
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hpp;hxx;hm;inl;inc;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ 婧愭枃浠
+
+
+
\ No newline at end of file
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo/demo.cpp b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo/demo.cpp
new file mode 100644
index 0000000..aadd31b
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo/demo.cpp
@@ -0,0 +1,996 @@
+#include
+#include
+#include
+#include "iostream"
+#include "string.h"
+#include "CWFaceDetection.h"
+#include "CWFaceRecognition.h"
+#include "CWFaceVersion.h"
+#include "CWFaceAttribute.h"
+#include "CWFaceNisLiveness.h"
+
+
+#ifdef WIN32
+#include "io.h"
+#else
+#include
+#endif // WIN32
+
+
+// 授权licence
+#define CW_LICENCE "MjEyNDE0bm9kZXZpY2Vjd2F1dGhvcml6ZZ/l5uXj5+Xq3+bg5efm5Of+5eXj4Obg5Yjm5uvl5ubrkeXm5uvl5uai6+Xm5uvl5uTm6+Xm5uDm1efr5+vn6+er4Ofr5+vn66vn5+Xm5+Xn"
+
+#define MAX_NUM_FACES 20 //最多检测的人脸数
+
+using namespace std;
+
+
+// [8/7/2015 Lit] 功能:将一个全路径名分解为路径和文件名
+bool DivPathAndFileName(const string &sAllName, string &sPath, string &sFileName)
+{
+ int iPos = sAllName.find_last_of('\\');
+ if (-1 == iPos)
+ {
+ iPos = sAllName.find_last_of('/');
+ if (-1 == iPos)
+ {
+ sPath = ".";
+ sFileName = sAllName;
+ return true;
+ }
+ }
+
+ sPath = sAllName.substr(0, iPos);
+ sFileName = sAllName.substr(iPos + 1, sAllName.length() - iPos - 1);
+ return true;
+}
+
+// [8/7/2015 Lit] 功能:提示用户输入图片路径,并获得文件夹路径
+bool GetImageAndPath(string &sPathPic, string &sPathFolder)
+{
+ char picPath[260] = {0};
+ while (true)
+ {
+ cout<<"Please Input Pic Path: ";
+ cin>>picPath;
+
+#ifdef WIN32
+ if (-1 == _access(picPath, 0))
+ {
+ cout<<"Pic Not Found"<> iType;
+
+ switch (iType)
+ {
+ case 1:
+ return DemoDetect();
+ case 2:
+ return DemoQuality();
+ case 3:
+ return DemoVerify();
+ case 4:
+ return DemoVerify2();
+ case 5:
+ return DemoRecog();
+ case 6:
+ return DemoAttribute();
+ case 7:
+ return DemoNisLiveness();
+ case 8:
+ return 0;
+
+ default:
+ cout << "type error" << endl << endl;
+ cin.clear();
+ cin.sync(); // 清空缓冲区
+ main();
+ return 0;
+ }
+}
+
+
+// [6/29/2016 Lit]:人脸检测使用示例
+int DemoDetect()
+{
+ // 程序启动时创建句柄
+ cw_errcode_t errCode = CW_SDKLIT_OK;
+ void *pDetHandle = CreateDetHandle(&errCode);
+ if (NULL == pDetHandle)
+ {
+ std::cout<<"Create detector Error, Code: " << errCode << endl;
+ return RetPause(-1);
+ }
+ cout << endl;
+
+ string sPath, sPathPic;
+ if (!GetImageAndPath(sPathPic, sPath))
+ {
+ return RetPause(-1, pDetHandle);
+ }
+
+ std::ifstream ifs(sPathPic.c_str(), std::ios::binary);
+ ifs.seekg(0, std::ios::end);
+ int iImgLen = ifs.tellg();
+ ifs.seekg(0, std::ios::beg);
+ char *szImg = new char[iImgLen];
+ ifs.read(szImg, iImgLen);
+
+ // 给图像结构体赋值
+ cw_img_t srcImg;
+ srcImg.frameId = 0;
+ srcImg.data = szImg;
+ srcImg.dataLen = iImgLen;
+ srcImg.angle = CW_IMAGE_ANGLE_0;
+ srcImg.format = CW_IMAGE_BINARY;
+
+ cw_face_res_t faceBuffers[MAX_NUM_FACES];
+ int iFaceNum = 0;
+ // 只做人脸检测
+ cw_errcode_t errDet = cwFaceDetection(pDetHandle, &srcImg, faceBuffers, MAX_NUM_FACES, &iFaceNum, CW_OP_DET);
+ delete[] szImg;
+ if (errDet != CW_SDKLIT_OK)
+ {
+ cout<<"Face detect Error, Code: " << errDet << endl;
+ return RetPause(-1, pDetHandle);
+ }
+ if (iFaceNum < 1)
+ {
+ cout<<"No Face Detected" << endl;
+ return RetPause(-1, pDetHandle);
+ }
+
+ cout << "Face Number: " << iFaceNum << endl;
+ for (int i = 0; i < iFaceNum; i++)
+ {
+ cout << "Face " << i + 1 << ": Pos: " << faceBuffers[i].faceRect.x << "," << faceBuffers[i].faceRect.y << "," << faceBuffers[i].faceRect.width << ","
+ << faceBuffers[i].faceRect.height << endl;
+ }
+
+ cout << "Face Detect Completely" << endl;
+
+ return RetPause(0, pDetHandle);
+}
+
+// [9/13/2016 Lit]:人脸质量使用示例
+int DemoQuality()
+{
+ // 程序启动时创建句柄
+ cw_errcode_t errCode = CW_SDKLIT_OK;
+ void *pDetHandle = CreateDetHandle(&errCode);
+ if (NULL == pDetHandle)
+ {
+ std::cout<<"Create detector Error, Code: " << errCode << endl;
+ return RetPause(-1);
+ }
+ cout << endl;
+
+ string sPath, sPathPic;
+ if (!GetImageAndPath(sPathPic, sPath))
+ {
+ return RetPause(-1, pDetHandle);
+ }
+
+ std::ifstream ifs(sPathPic.c_str(), std::ios::binary);
+ ifs.seekg(0, std::ios::end);
+ int iImgLen = ifs.tellg();
+ ifs.seekg(0, std::ios::beg);
+ char *szImg = new char[iImgLen];
+ ifs.read(szImg, iImgLen);
+
+ // 给图像结构体赋值
+ cw_img_t srcImg;
+ srcImg.frameId = 0;
+ srcImg.data = szImg;
+ srcImg.dataLen = iImgLen;
+ srcImg.angle = CW_IMAGE_ANGLE_0;
+ srcImg.format = CW_IMAGE_BINARY;
+
+ cw_face_res_t faceBuffers[MAX_NUM_FACES];
+ int iFaceNum = 0;
+ // 人脸检测和人脸质量操作 CW_OP_DET | CW_OP_QUALITY
+ cw_errcode_t errDet = cwFaceDetection(pDetHandle, &srcImg, faceBuffers, MAX_NUM_FACES, &iFaceNum, CW_OP_DET | CW_OP_QUALITY);
+ delete[] szImg;
+ if (errDet != CW_SDKLIT_OK)
+ {
+ cout<<"Face detect Error, Code: " << errDet << endl;
+ return RetPause(-1, pDetHandle);
+ }
+ if (iFaceNum < 1)
+ {
+ cout<<"No Face Detected" << endl;
+ return RetPause(-1, pDetHandle);
+ }
+
+ cout << "Face Number: " << iFaceNum << endl;
+ for (int i = 0; i < iFaceNum; i++)
+ {
+ cw_quality_errcode errQuality = faceBuffers[i].quality.errcode;
+ if (CW_QUALITY_OK == errQuality)
+ {
+ cout << "Face " << i + 1 << ": Pos: " << faceBuffers[i].faceRect.x << "," << faceBuffers[i].faceRect.y << "," << faceBuffers[i].faceRect.width << ","
+ << faceBuffers[i].faceRect.height << " Quality Score: " << faceBuffers[i].quality.scores[0] << endl;
+ cout << "faceBuffers[i].quality.scores: [ ";
+ for(int m =0; m < (sizeof(faceBuffers[i].quality.scores) / sizeof(faceBuffers[i].quality.scores[0])); m++)
+ {
+ cout << faceBuffers[0].quality.scores[m] << " ";
+ }
+ cout << " ]\n";
+ }
+ else
+ {
+ cout << "Face " << i + 1 << ": Pos: " << faceBuffers[i].faceRect.x << "," << faceBuffers[i].faceRect.y << "," << faceBuffers[i].faceRect.width << ","
+ << faceBuffers[i].faceRect.height << " Quality Err: " << errQuality << endl;
+ }
+ }
+
+ cout << "Face Quality Completely" << endl;
+
+ return RetPause(0, pDetHandle);
+}
+
+// [6/29/2016 Lit]:人脸比对使用示例(1:1)
+int DemoVerify()
+{
+ cw_errcode_t errCode = CW_SDKLIT_OK;
+ void *pDetHandle = CreateDetHandle(&errCode);
+ if (NULL == pDetHandle)
+ {
+ std::cout<<"Create detector Error, Code: " << errCode << std::endl;
+ return RetPause(-1);
+ }
+
+ void *pRecogHandle = CreateRecogHandle(&errCode);
+ if (NULL == pRecogHandle || CW_SDKLIT_OK != errCode)
+ {
+ std::cout<<"Create Recog Handle Error, Code: " << errCode << std::endl;
+ return RetPause(-1, pDetHandle);
+ }
+ cout << endl;
+
+ string sPath, sPathPic1;
+ if (!GetImageAndPath(sPathPic1, sPath))
+ {
+ return RetPause(-1, pDetHandle);
+ }
+
+ string sPathPic2;
+ if (!GetImageAndPath(sPathPic2, sPath))
+ {
+ return RetPause(-1, pDetHandle);
+ }
+
+ int iFeaLen = cwGetFeatureLength(pRecogHandle);
+ char *pFeaFiled = new char[iFeaLen];
+ if (0 != GetFeatureFromPath(pDetHandle, pRecogHandle, sPathPic1, pFeaFiled))
+ {
+ cout << "Pic1 Failed\n";
+ delete[] pFeaFiled;
+ return RetPause(-1, pDetHandle, pRecogHandle,NULL);
+ }
+
+ char *pFeaProbe = new char[iFeaLen];
+ if (0 != GetFeatureFromPath(pDetHandle, pRecogHandle, sPathPic2, pFeaProbe))
+ {
+ cout << "Pic2 Failed\n";
+ delete[] pFeaFiled;
+ delete[] pFeaProbe;
+ return RetPause(-1, pDetHandle, pRecogHandle,NULL);
+ }
+
+ float scores[1] = {0.0};
+ errCode = cwComputeMatchScore(pRecogHandle, pFeaProbe, pFeaFiled, 1, scores);
+ delete[] pFeaFiled;
+ delete[] pFeaProbe;
+ if (errCode != CW_SDKLIT_OK)
+ {
+ cout << "Recog Error: " << errCode;
+ return RetPause(-1, pDetHandle, pRecogHandle,NULL);
+ }
+
+ cout << "Verify Score: " << scores[0] << endl;
+
+ cout << "Face Verify Completely" << endl;
+
+ return RetPause(0, pDetHandle, pRecogHandle,NULL);
+}
+
+// 直接调用比对接口
+int DemoVerify2()
+{
+ cw_errcode_t errCode = CW_SDKLIT_OK;
+ void *pDetHandle = CreateDetHandle(&errCode);
+ if (NULL == pDetHandle)
+ {
+ std::cout<<"Create detector Error, Code: " << errCode << std::endl;
+ return RetPause(-1);
+ }
+
+ void *pRecogHandle = CreateRecogHandle(&errCode);
+ if (NULL == pRecogHandle || CW_SDKLIT_OK != errCode)
+ {
+ std::cout<<"Create Recog Handle Error, Code: " << errCode << std::endl;
+ return RetPause(-1, pDetHandle);
+ }
+ cout << endl;
+
+ string sPath, sPathPic1;
+ if (!GetImageAndPath(sPathPic1, sPath))
+ {
+ return RetPause(-1, pDetHandle);
+ }
+
+ string sPathPic2;
+ if (!GetImageAndPath(sPathPic2, sPath))
+ {
+ return RetPause(-1, pDetHandle);
+ }
+
+ std::ifstream ifs(sPathPic1.c_str(), std::ios::binary);
+ ifs.seekg(0, std::ios::end);
+ int iImgLen = ifs.tellg();
+ ifs.seekg(0, std::ios::beg);
+ char *szImg = new char[iImgLen];
+ ifs.read(szImg, iImgLen);
+
+ cw_img_t srcImg;
+ srcImg.frameId = 0;
+ srcImg.data = szImg;
+ srcImg.dataLen = iImgLen;
+ srcImg.angle = CW_IMAGE_ANGLE_0;
+ srcImg.format = CW_IMAGE_BINARY;
+ srcImg.mirror = CW_IMAGE_MIRROR_NONE;
+
+ std::ifstream ifs2(sPathPic2.c_str(), std::ios::binary);
+ ifs2.seekg(0, std::ios::end);
+ int iImgLen2 = ifs2.tellg();
+ ifs2.seekg(0, std::ios::beg);
+ char *szImg2 = new char[iImgLen2];
+ ifs2.read(szImg2, iImgLen2);
+
+ cw_img_t srcImg2;
+ srcImg2.frameId = 0;
+ srcImg2.data = szImg2;
+ srcImg2.dataLen = iImgLen2;
+ srcImg2.angle = CW_IMAGE_ANGLE_0;
+ srcImg2.format = CW_IMAGE_BINARY;
+ srcImg2.mirror = CW_IMAGE_MIRROR_NONE;
+
+ float fScore = 0.0f;
+ errCode = cwVerifyImageData(pDetHandle, pRecogHandle, &srcImg, &srcImg2, &fScore);
+ delete[] szImg;
+ delete[] szImg2;
+
+ if (errCode != CW_SDKLIT_OK)
+ {
+ cout << "Verify Error: " << errCode;
+ return RetPause(-1, pDetHandle, pRecogHandle);
+ }
+
+ cout << "Verify Score: " << fScore << endl;
+
+ cout << "Face Verify Completely" << endl;
+
+ return RetPause(0, pDetHandle, pRecogHandle);
+}
+
+// [6/29/2016 Lit]:人脸识别使用示例(1:N)
+int DemoRecog()
+{
+ cw_errcode_t errCode = CW_SDKLIT_OK;
+ void *pDetHandle = CreateDetHandle(&errCode);
+ if (NULL == pDetHandle)
+ {
+ std::cout<<"Create detector Error, Code: " << errCode << std::endl;
+ return RetPause(-1);
+ }
+
+ void *pRecogHandle = CreateRecogHandle(&errCode);
+ if (NULL == pRecogHandle || CW_SDKLIT_OK != errCode)
+ {
+ std::cout<<"Create Recog Handle Error, Code: " << errCode << std::endl;
+ return RetPause(-1, pDetHandle);
+ }
+ cout << endl;
+
+ string sPath, sPathPic1;
+ if (!GetImageAndPath(sPathPic1, sPath))
+ {
+ return RetPause(-1, pDetHandle);
+ }
+
+ string sPathPic2;
+ if (!GetImageAndPath(sPathPic2, sPath))
+ {
+ return RetPause(-1, pDetHandle);
+ }
+
+ int iFeaLen = cwGetFeatureLength(pRecogHandle);
+ // 底库为图片1和图片2
+ char *pFeaFiled = new char[iFeaLen * 2];
+ if (0 != GetFeatureFromPath(pDetHandle, pRecogHandle, sPathPic1, pFeaFiled))
+ {
+ cout << "Pic2 Failed\n";
+ delete[] pFeaFiled;
+ return RetPause(-1, pDetHandle, pRecogHandle);
+ }
+ if (0 != GetFeatureFromPath(pDetHandle, pRecogHandle, sPathPic2, pFeaFiled + iFeaLen))
+ {
+ cout << "Pic1 Failed\n";
+ delete[] pFeaFiled;
+ return RetPause(-1, pDetHandle, pRecogHandle);
+ }
+
+ // 用于检索
+ char *pFeaProbe = new char[iFeaLen];
+ if (0 != GetFeatureFromPath(pDetHandle, pRecogHandle, sPathPic2, pFeaProbe))
+ {
+ cout << "Pic2 Failed\n";
+ delete[] pFeaFiled;
+ delete[] pFeaProbe;
+ return RetPause(-1, pDetHandle, pRecogHandle);
+ }
+
+ // 识别图片2,底库为图片1和图片2
+ float scores[2] = {0.0};
+ errCode = cwComputeMatchScore(pRecogHandle, pFeaProbe, pFeaFiled, 2, scores);
+ delete[] pFeaFiled;
+ delete[] pFeaProbe;
+ if (errCode != CW_SDKLIT_OK)
+ {
+ cout << "Recog Error: " << errCode;
+ return RetPause(-1, pDetHandle, pRecogHandle);
+ }
+
+ cout << "Recog Score: " << endl << scores[0] << endl << scores[1] << endl;
+
+ cout << "Face Recognise Completely" << endl;
+
+ return RetPause(0, pDetHandle, pRecogHandle);
+}
+
+
+//[16/10/2018 Lit]: 人脸属性识别检测
+int DemoAttribute()
+{
+ cw_errcode errCode=CW_SDKLIT_OK;
+ void *pDetHandle = CreateDetHandle(&errCode);
+ if (pDetHandle == NULL)
+ {
+ cout << "Create Detector Erroe,Code: "<< errCode << endl;
+ return RetPause(-1);
+ }
+
+
+ const char* AgeModelPath ="../../CWModels/attribute/ageGroup/CWR_Config3.0.xml";
+ void *pAgeHandle=CreateAttributeHandle(&errCode,AgeModelPath);
+ if(NULL==pAgeHandle)
+ {
+ cout<< "Create AgeAttribute Handle Error! ErrCode:"<< errCode << endl;
+ RetPause (-1);
+ }
+
+ const char* GenderModelPath ="../../CWModels/attribute/faceGender/cw_gender_config.xml";
+ void *pGenderHandle=CreateAttributeHandle(&errCode,GenderModelPath);
+ if(NULL==pGenderHandle)
+ {
+ cout<< "Create GenderAttribute Handle Error! ErrCode:"<< errCode << endl;
+ RetPause (-1);
+ }
+
+ const char* RaceModelPath ="../../CWModels/attribute/faceRace/cw_race_config.xml";
+ void *pRaceHandle=CreateAttributeHandle(&errCode,RaceModelPath);
+ if(NULL==pRaceHandle)
+ {
+ cout<< "Create RaceAttribute Handle Error! ErrCode:"<< errCode << endl;
+ RetPause (-1);
+ }
+
+ cout << endl;
+
+ string sPath, sPathPic;
+ if (!GetImageAndPath(sPathPic, sPath))
+ {
+ return RetPause(-1, pDetHandle, NULL);
+ }
+
+ std::ifstream ifs(sPathPic.c_str(), std::ios::binary);
+ ifs.seekg(0, std::ios::end);
+ int iImgLen = ifs.tellg();
+ ifs.seekg(0, std::ios::beg);
+ char *szImg = new char[iImgLen];
+ ifs.read(szImg, iImgLen);
+
+ // 给图像结构体赋值
+ cw_img_t srcImg;
+ srcImg.frameId = 0;
+ srcImg.data = szImg;
+ srcImg.dataLen = iImgLen;
+ srcImg.angle = CW_IMAGE_ANGLE_0;
+ srcImg.format = CW_IMAGE_BINARY;
+ srcImg.mirror = CW_IMAGE_MIRROR_NONE;
+
+ cw_face_res_t faceBuffers[MAX_NUM_FACES];
+ int iFaceNum = 0;
+ // 人脸检测,获取对齐人脸
+ errCode = cwFaceDetection(pDetHandle, &srcImg, faceBuffers, MAX_NUM_FACES, &iFaceNum, CW_OP_DET | CW_OP_ALIGN);
+ delete[] szImg;
+ if (errCode != CW_SDKLIT_OK)
+ {
+ cout << "Face detect Error, Code: " << errCode << endl;
+ return RetPause(-1, pDetHandle, NULL, pAgeHandle,pGenderHandle,pRaceHandle);
+ }
+ if (iFaceNum < 1)
+ {
+ cout<<"No Face Detected" << endl;
+ return RetPause(-1, pDetHandle, NULL, pAgeHandle,pGenderHandle,pRaceHandle);
+ }
+
+ int iAge = 0, iGender = 0, iRace = 0;
+ float fConfidence =0.0;
+ for (int i = 0; i < iFaceNum; i++)
+ {
+ //年龄段
+ errCode = cwGetAgeEval(pAgeHandle, &faceBuffers[i].faceAligned, &iAge);
+ if (CW_SDKLIT_OK == errCode)
+ {
+ printf("Face %d AgeGroup: %d\n", i + 1, iAge);
+ }
+ else
+ {
+ printf("Face %d Age Error: %d\n", i + 1, errCode);
+ }
+
+ //性别
+ errCode = cwGetGenderEval(pGenderHandle, &faceBuffers[i].faceAligned, &iGender, &fConfidence);
+ if (CW_SDKLIT_OK == errCode)
+ {
+ printf("Face %d Gender: %d, Confidence: %.2f\n", i + 1, iGender, fConfidence);
+ }
+ else
+ {
+ printf("Face %d Gender Error: %d\n", i + 1, errCode);
+ }
+
+ //种族
+ errCode = cwGetRaceEval(pRaceHandle, &faceBuffers[i].faceAligned, &iRace, &fConfidence);
+ if (CW_SDKLIT_OK == errCode)
+ {
+ printf("Face %d Race: %d, Confidence: %.2f\n", i + 1, iRace, fConfidence);
+ }
+ else
+ {
+ printf("Face %d Race Error: %d\n", i + 1, errCode);
+ }
+
+ }
+
+ cout << "Face Attribute Completely" << endl;
+ return RetPause(0, pDetHandle, NULL, pAgeHandle,pGenderHandle,pRaceHandle);
+}
+
+// [9/4/2017 Lit]:红外活体检测Demo
+int DemoNisLiveness()
+{
+ cw_errcode_t errCode = CW_SDKLIT_OK;
+ void *pDetHandle = CreateDetHandle(&errCode);
+ if (NULL == pDetHandle)
+ {
+ std::cout<<"Create detector Error, Code: " << errCode << std::endl;
+ return RetPause(-1);
+ }
+
+ cw_nirliveness_err_t errNis = CW_NIRLIV_OK;
+ void *pNisLiveness = CreateNisLivenessHandle(&errNis);
+ if (pNisLiveness == NULL)
+ {
+ std::cout<<"Create NisLiveness Error, Code: " << errNis << std::endl;
+ return RetPause(-1, pDetHandle);
+ }
+ std::cout << endl;
+
+ string sPath, sPathPicVis; // 可见光照片
+ if (!GetImageAndPath(sPathPicVis, sPath))
+ {
+ return RetPause(-1, pDetHandle,NULL, NULL, NULL,NULL, pNisLiveness);
+ }
+
+ string sPathPicNir; // 红外照片
+ if (!GetImageAndPath(sPathPicNir, sPath))
+ {
+ return RetPause(-1, pDetHandle,NULL, NULL, NULL,NULL, pNisLiveness);
+ }
+
+ // 可见光图片
+ std::ifstream ifs(sPathPicVis.c_str(), std::ios::binary);
+ ifs.seekg(0, std::ios::end);
+ int iImgLen = ifs.tellg();
+ if (iImgLen < 1)
+ {
+ std::cout << "可见光图片错误";
+ return RetPause(-1, pDetHandle,NULL, NULL, NULL,NULL, pNisLiveness);
+ }
+ ifs.seekg(0, std::ios::beg);
+ char *szImg = new char[iImgLen];
+ ifs.read(szImg, iImgLen);
+
+ // 红外图片
+ std::ifstream ifsNir(sPathPicNir.c_str(), std::ios::binary);
+ ifsNir.seekg(0, std::ios::end);
+ int iImgLenNir = ifsNir.tellg();
+ if (iImgLenNir < 1)
+ {
+ delete[] szImg;
+ std::cout << "红外图片错误";
+ return RetPause(-1, pDetHandle,NULL, NULL, NULL,NULL, pNisLiveness);
+ }
+ ifsNir.seekg(0, std::ios::beg);
+ char *szImgNir = new char[iImgLenNir];
+ ifsNir.read(szImgNir, iImgLenNir);
+
+#if 0
+
+ // 采用封装红外活体接口
+ cw_img_t srcImgVis;
+ srcImgVis.frameId = 0;
+ srcImgVis.data = szImg;
+ srcImgVis.dataLen = iImgLen;
+ srcImgVis.angle = CW_IMAGE_ANGLE_0;
+ srcImgVis.format = CW_IMAGE_BINARY;
+ srcImgVis.mirror = CW_IMAGE_MIRROR_NONE;
+
+ cw_img_t srcImgNir;
+ srcImgNir.frameId = 0;
+ srcImgNir.data = szImgNir;
+ srcImgNir.dataLen = iImgLenNir;
+ srcImgNir.angle = CW_IMAGE_ANGLE_0;
+ srcImgNir.format = CW_IMAGE_BINARY;
+ srcImgNir.mirror = CW_IMAGE_MIRROR_NONE;
+
+ cw_nirliv_res_t nirLivRes;
+ errNis = cwFaceNirByImageData(pDetHandle, pNisLiveness, &srcImgVis, &srcImgNir, &nirLivRes);
+ if (errNis == CW_NIRLIV_OK)
+ {
+ std::cout << "liveness state: " << nirLivRes.livRst << ", score: " << nirLivRes.score << std::endl;
+ }
+ else
+ {
+ std::cout << "cwFaceNirByImageData Error: " << errNis << std::endl;
+ }
+
+ delete[] szImg;
+ delete[] szImgNir;
+
+ cout << "\nFace NisLiveness Completely" << endl;
+
+ return RetPause(0, pDetHandle, NULL, NULL, pNisLiveness);
+
+#else
+
+ // 采用原始红外活体接口
+ cw_face_res_t *faceBuffersVis = new cw_face_res_t[MAX_NUM_FACES];
+ int iFaceNumVis = GetFaceInfoByImgData(pDetHandle, szImg, iImgLen, faceBuffersVis);
+ if (iFaceNumVis < 1)
+ {
+ cout << "可见光检测失败";
+ delete[] szImg;
+ delete[] szImgNir;
+ delete[] faceBuffersVis;
+ return RetPause(-1, pDetHandle,NULL, NULL, NULL,NULL, pNisLiveness);
+ }
+
+ cw_face_res_t *faceBuffersNis = new cw_face_res_t[MAX_NUM_FACES];
+ int iFaceNumNis = GetFaceInfoByImgData(pDetHandle, szImgNir, iImgLenNir, faceBuffersNis);
+ if (iFaceNumNis < 1)
+ {
+ cout << "红外检测失败";
+ delete[] szImg;
+ delete[] faceBuffersVis;
+ delete[] szImgNir;
+ delete[] faceBuffersNis;
+ return RetPause(-1, pDetHandle,NULL, NULL, NULL,NULL, pNisLiveness);
+ }
+ cout << endl;
+
+
+ // 取红外和可见光图片中的第一个人脸做活体
+ cw_nirliv_detinfo_t detInfo;
+ detInfo.nLandmarks = faceBuffersVis[0].keypt.nkeypt; //关键点个数
+
+ // 红外图片数据
+ detInfo.pNirImg = new cw_nirliv_img_t();
+ detInfo.pNirImg->data = szImgNir;
+ detInfo.pNirImg->dataLen = iImgLenNir;
+ detInfo.pNirImg->format = CW_IMAGE_BINARY; // 这里读取后都是3通道的bgr图
+
+ // 可见光图片数据
+ detInfo.pVisImg = new cw_nirliv_img_t();
+ detInfo.pVisImg->data = szImg;
+ detInfo.pVisImg->dataLen = iImgLen;
+ detInfo.pVisImg->format = CW_IMAGE_BINARY; // 这里读取后都是3通道的bgr图
+
+ detInfo.pVisInfo = new cw_nirliv_face_param_t(); // 可见光人脸信息
+ detInfo.pVisInfo->pKeypoints = faceBuffersVis[0].keypt.points;
+ detInfo.pVisInfo->fKeyScore = faceBuffersVis[0].keypt.keyptScore; // 质量分
+ detInfo.pVisInfo->fSkinScore = faceBuffersVis[0].quality.scores[6]; // 肤色分
+
+ detInfo.pNirInfo = new cw_nirliv_face_param_t(); // 红外人脸信息
+ detInfo.pNirInfo->pKeypoints = faceBuffersNis[0].keypt.points;
+ detInfo.pNirInfo->fKeyScore = faceBuffersNis[0].keypt.keyptScore; // 质量分
+ detInfo.pNirInfo->fSkinScore = faceBuffersNis[0].quality.scores[6]; // 肤色分
+
+ cw_nirliv_res_t nisLivenessRes;
+ errNis = cwFaceNirLivenessDet(pNisLiveness, &detInfo, &nisLivenessRes);
+ if (errNis == CW_NIRLIV_OK)
+ {
+ cout << "state: " << nisLivenessRes.livRst << " score: " << nisLivenessRes.score << endl;
+ }
+ else
+ {
+ cout << "Face NisLiveness Error: " << errNis << endl;
+ }
+
+ delete[] szImg;
+ delete[] szImgNir;
+ delete[] faceBuffersVis;
+ delete[] faceBuffersNis;
+ delete detInfo.pNirImg;
+ delete detInfo.pVisImg;
+ delete detInfo.pVisInfo;
+ delete detInfo.pNirInfo;
+
+ cout << "\nFace NisLiveness Completely" << endl;
+
+ return RetPause(0, pDetHandle, NULL, NULL, pNisLiveness);
+
+#endif
+
+
+}
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp.rar b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp.rar
new file mode 100644
index 0000000..df927f3
Binary files /dev/null and b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp.rar differ
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/App.config b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/App.config
new file mode 100644
index 0000000..821089c
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/App.config
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/App.xaml b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/App.xaml
new file mode 100644
index 0000000..34e7ba6
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/App.xaml
@@ -0,0 +1,8 @@
+锘
+
+
+
+
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/App.xaml.cs b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/App.xaml.cs
new file mode 100644
index 0000000..4919bb9
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/App.xaml.cs
@@ -0,0 +1,54 @@
+锘縰sing DemoUI.Common;
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Data;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows;
+
+namespace DemoUI
+{
+ ///
+ /// App.xaml 鐨勪氦浜掗昏緫
+ ///
+ public partial class App : Application
+ {
+ QMLog log = new QMLog();
+ private void Application_Startup(object sender, StartupEventArgs e)
+ {
+
+ try
+ {
+ log.WriteLogFile("姝e父鍚姩", "start");
+ AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
+ Application.Current.DispatcherUnhandledException += new System.Windows.Threading.DispatcherUnhandledExceptionEventHandler(Current_DispatcherUnhandledException);
+ AppDomain.CurrentDomain.ProcessExit += new EventHandler(CurrentDomain_ProcessExit);
+ MainWindow win = new MainWindow();
+ win.Show();
+ }
+ catch (Exception ex)
+ {
+ log.WriteLogFile(ex.ToString(), "StartupError");
+ MessageBox.Show("绋嬪簭鍚姩澶辫触");
+ }
+ }
+ private void Current_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
+ {
+ log.WriteLogFile(e.Exception.Message + e.Exception.StackTrace, "APPError");
+ }
+
+ private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
+ {
+ Exception ex = (Exception)e.ExceptionObject;
+ log.WriteLogFile(ex.Message + ex.StackTrace, "APPError");
+ }
+
+ private void CurrentDomain_ProcessExit(object sender, EventArgs e)
+ {
+ log.WriteLogFile("绋嬪簭鍏抽棴", "start");
+ }
+ }
+
+
+}
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/Common/ChatWebSocketMiddleware.cs b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/Common/ChatWebSocketMiddleware.cs
new file mode 100644
index 0000000..600520f
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/Common/ChatWebSocketMiddleware.cs
@@ -0,0 +1,218 @@
+锘
+
+using DemoUI.SDK;
+using Emgu.CV;
+using Fleck;
+using Newtonsoft.Json;
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Runtime.InteropServices;
+
+namespace DemoUI.Common
+{
+
+ public class ChatWebSocketMiddleware
+ {
+ public static List allSockets = new List();
+ //public static List allSocketsForTest = new List();
+ public static List allSocketsForLive = new List();
+ public static List faceSockets = new List();
+ public static string CurFaceID = string.Empty;
+ public static Mat CurFaceImage = null;
+ public static cw_face_res_t? CurFaceModel = null;
+ public static object NoFaceModel = new { faceID = "", isValid = false, beautyScore = 0, faceImage = "", genderMale = "" };
+ public static bool isLive = false;
+ //public static bool isTestLive = false;
+ private QMLog log = new QMLog();
+ public void openSocket()
+ {
+ FleckLog.Level = LogLevel.Debug;
+ var ws = ConfigurationManager.AppSettings["websocketUrl"];
+ log.WriteLogFile(ConfigurationManager.AppSettings["websocketUrl"],"222");
+ var server = new WebSocketServer(ws);
+ server.Start(socket =>
+ {
+ socket.OnOpen = () => //褰撳缓绔婼ocket閾炬帴鏃舵墽琛屾鏂规硶
+ {
+ //var data = socket.ConnectionInfo; //閫氳繃data鍙互鑾峰緱杩欎釜閾炬帴浼犻掕繃鏉ョ殑Cookie淇℃伅锛岀敤鏉ュ尯鍒嗗悇涓摼鎺ュ拰鐢ㄦ埛涔嬮棿鐨勫叧绯伙紙濡傛灉闇瑕佸悗鍙颁富鍔ㄦ帹閫佷俊鎭埌鏌愪釜瀹㈡埛鐨勬椂鍊欙紝鍙互浣跨敤Cookie锛
+ allSockets.Add(socket);
+ log.WriteLogFile("======"+ allSockets.Count, "222");
+ if (!string.IsNullOrEmpty(CurFaceID)) {
+ socket.Send(CurFaceID);
+ }
+ };
+
+ socket.OnClose = () =>// 褰撳叧闂璖ocket閾炬帴鍗佹墽琛屾鏂规硶
+ {
+ //Console.WriteLine("Close!");
+ allSockets.Remove(socket);
+ log.WriteLogFile("====11==" + allSockets.Count, "222");
+ };
+
+ socket.OnMessage = message =>// 鎺ユ敹瀹㈡埛绔彂閫佽繃鏉ョ殑淇℃伅
+ {
+ if (message == "face")
+ {
+ if (!string.IsNullOrEmpty(CurFaceID))
+ {
+ Dictionary dicData = JsonConvert.DeserializeObject>(CurFaceID);
+ var faceData = new { faceID = dicData["faceID"], isValid = true, beautyScore = dicData["beautyScore"], faceImage = dicData["faceImage"], genderMale = dicData["genderMale"] };
+ socket.Send(JsonConvert.SerializeObject(faceData));
+ }
+
+ //if (CurFaceImage != null && CurFaceModel.HasValue)
+ // SendFaceForKiosk(CurFaceImage, CurFaceModel.Value, socket);
+ }
+ else if (message == "openlive")
+ {
+ isLive = true;
+ }
+ else if (message == "closelive")
+ {
+ log.WriteLogFile("杩涙潵浜", "2222222222222");
+ ChatWebSocketMiddleware.isLive = false;
+ }
+
+ //Console.WriteLine(message);
+ //socket.Send("Echo: " + message);
+ //allSockets.ToList().ForEach(s => s.Send("Echo: " + message));
+ };
+ });
+
+ }
+
+ //public void openSocketForTest()
+ //{
+ // FleckLog.Level = LogLevel.Debug;
+ // var ws = "ws://192.168.1.128:7189";
+ // var server = new WebSocketServer(ws);
+ // server.Start(socket =>
+ // {
+ // socket.OnOpen = () => //褰撳缓绔婼ocket閾炬帴鏃舵墽琛屾鏂规硶
+ // {
+ // //var data = socket.ConnectionInfo; //閫氳繃data鍙互鑾峰緱杩欎釜閾炬帴浼犻掕繃鏉ョ殑Cookie淇℃伅锛岀敤鏉ュ尯鍒嗗悇涓摼鎺ュ拰鐢ㄦ埛涔嬮棿鐨勫叧绯伙紙濡傛灉闇瑕佸悗鍙颁富鍔ㄦ帹閫佷俊鎭埌鏌愪釜瀹㈡埛鐨勬椂鍊欙紝鍙互浣跨敤Cookie锛
+ // allSocketsForTest.Add(socket);
+ // };
+
+ // socket.OnClose = () =>// 褰撳叧闂璖ocket閾炬帴鍗佹墽琛屾鏂规硶
+ // {
+ // //Console.WriteLine("Close!");
+ // allSocketsForTest.Remove(socket);
+ // };
+
+ // socket.OnMessage = message =>// 鎺ユ敹瀹㈡埛绔彂閫佽繃鏉ョ殑淇℃伅
+ // {
+ // if (message == "openlive")
+ // {
+ // isTestLive = true;
+ // }
+ // else if (message == "closelive")
+ // {
+ // ChatWebSocketMiddleware.isTestLive = false;
+ // }
+
+ // //Console.WriteLine(message);
+ // //socket.Send("Echo: " + message);
+ // //allSockets.ToList().ForEach(s => s.Send("Echo: " + message));
+ // };
+ // });
+
+ //}
+
+ public void openSocketForLive()
+ {
+ FleckLog.Level = LogLevel.Debug;
+ var ws = ConfigurationManager.AppSettings["websocketForLive"];
+ var server = new WebSocketServer(ws);
+ server.Start(socket =>
+ {
+ socket.OnOpen = () => //褰撳缓绔婼ocket閾炬帴鏃舵墽琛屾鏂规硶
+ {
+ ChatWebSocketMiddleware.isLive = true;
+ //var data = socket.ConnectionInfo; //閫氳繃data鍙互鑾峰緱杩欎釜閾炬帴浼犻掕繃鏉ョ殑Cookie淇℃伅锛岀敤鏉ュ尯鍒嗗悇涓摼鎺ュ拰鐢ㄦ埛涔嬮棿鐨勫叧绯伙紙濡傛灉闇瑕佸悗鍙颁富鍔ㄦ帹閫佷俊鎭埌鏌愪釜瀹㈡埛鐨勬椂鍊欙紝鍙互浣跨敤Cookie锛
+ allSocketsForLive.Add(socket);
+ };
+
+ socket.OnClose = () =>// 褰撳叧闂璖ocket閾炬帴鍗佹墽琛屾鏂规硶
+ {
+ ChatWebSocketMiddleware.isLive = false;
+ //Console.WriteLine("Close!");
+ allSocketsForLive.Remove(socket);
+ };
+
+ socket.OnMessage = message =>// 鎺ユ敹瀹㈡埛绔彂閫佽繃鏉ョ殑淇℃伅
+ {
+ //if (message == "openlive")
+ //{
+ // ChatWebSocketMiddleware.isLive = true;
+ //}
+ //else if (message == "closelive")
+ //{
+ // ChatWebSocketMiddleware.isLive = false;
+ //}
+ //Console.WriteLine(message);
+ //socket.Send("Echo: " + message);
+ //allSockets.ToList().ForEach(s => s.Send("Echo: " + message));
+ };
+ });
+
+ }
+
+
+ public void openSocketForFace()
+ {
+ FleckLog.Level = LogLevel.Debug;
+ var ws = ConfigurationManager.AppSettings["websocketForFace"];
+ var server = new WebSocketServer(ws);
+ server.Start(socket =>
+ {
+ socket.OnOpen = () => //褰撳缓绔婼ocket閾炬帴鏃舵墽琛屾鏂规硶
+ {
+ log.WriteLogFile("灞忎繚socket111111","face");
+ var data = socket.ConnectionInfo; //閫氳繃data鍙互鑾峰緱杩欎釜閾炬帴浼犻掕繃鏉ョ殑Cookie淇℃伅锛岀敤鏉ュ尯鍒嗗悇涓摼鎺ュ拰鐢ㄦ埛涔嬮棿鐨勫叧绯伙紙濡傛灉闇瑕佸悗鍙颁富鍔ㄦ帹閫佷俊鎭埌鏌愪釜瀹㈡埛鐨勬椂鍊欙紝鍙互浣跨敤Cookie锛
+ Console.WriteLine("Open!");
+ faceSockets.Add(socket);
+ };
+
+ socket.OnClose = () =>// 褰撳叧闂璖ocket閾炬帴鍗佹墽琛屾鏂规硶
+ {
+
+ Console.WriteLine("Close!");
+ faceSockets.Remove(socket);
+ };
+
+ socket.OnMessage = message =>// 鎺ユ敹瀹㈡埛绔彂閫佽繃鏉ョ殑淇℃伅
+ {
+ log.WriteLogFile(message, "face");
+
+ if (message.IndexOf("瀵艰埅") >= 0)
+ {
+ var faceData = new
+ {
+ faceID = "-1",
+ faceImage = message.Replace("瀵艰埅", "")
+ };
+ faceSockets.ForEach(s => s.Send(JsonConvert.SerializeObject(faceData)));
+ }
+ else if (message.IndexOf("棣栭〉") >= 0)
+ {
+ var faceData = new
+ {
+ faceID = "-1",
+ faceImage = message
+ };
+ faceSockets.ForEach(s => s.Send(JsonConvert.SerializeObject(faceData)));
+ }
+ //log.WriteLogFile(message,"浜鸿劯鐐瑰嚮");
+ //allSockets.ForEach(s => s.Send("Echo: " + message));
+ //Console.WriteLine(message);
+ //socket.Send("Echo: " + message);
+ //allSockets.ToList().ForEach(s => s.Send("Echo: " + message));
+ };
+ });
+
+ }
+ }
+}
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/Common/QMLog.cs b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/Common/QMLog.cs
new file mode 100644
index 0000000..bde1ee1
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/Common/QMLog.cs
@@ -0,0 +1,176 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace DemoUI.Common
+{
+ public class QMLog
+ {
+ /**/
+ ///
+ /// 鍐欏叆鏃ュ織鏂囦欢
+ ///
+ ///
+ public void WriteLogFile(string input, string strfileName = "Errlog")
+ {
+ try
+ {
+ /**/
+ ///鎸囧畾鏃ュ織鏂囦欢鐨勭洰褰
+ strfileName = strfileName + DateTime.Now.ToString("yyyy-MM-dd");
+ string fpath = Directory.GetCurrentDirectory() + "\\log\\" + DateTime.Now.ToString("yyyy-MM-dd") + "\\";
+ if (!Directory.Exists(fpath))
+ {
+ DirectoryInfo directoryInfo = new DirectoryInfo(fpath);
+ directoryInfo.Create();
+ }
+
+ string fname = Directory.GetCurrentDirectory() + "\\log\\" + DateTime.Now.ToString("yyyy-MM-dd") + "\\" + strfileName + ".txt";
+
+ /**/
+ ///瀹氫箟鏂囦欢淇℃伅瀵硅薄
+ ///
+ FileInfo finfo = new FileInfo(fname);
+ if (!finfo.Exists)
+ {
+ FileStream fs = new FileStream(fname, FileMode.Create, FileAccess.Write);
+ //fs = File.Create(fname);
+ fs.Close();
+ finfo = new FileInfo(fname);
+ }
+ /**/
+ ///鍒ゆ柇鏂囦欢鏄惁瀛樺湪浠ュ強鏄惁澶т簬2K
+ if (finfo.Length > 1024 * 1024 * 10)
+ {
+ /**/
+ ///鏂囦欢瓒呰繃10MB鍒欓噸鍛藉悕
+ File.Move(Directory.GetCurrentDirectory() + "\\LogFile.txt", Directory.GetCurrentDirectory() + DateTime.Now.TimeOfDay + "\\LogFile.txt");
+ /**/
+ ///鍒犻櫎璇ユ枃浠
+ //finfo.Delete();
+ }
+ //finfo.AppendText();
+ /**/
+ ///鍒涘缓鍙啓鏂囦欢娴
+
+ using (FileStream fs = finfo.OpenWrite())
+ {
+ /**/
+ ///鏍规嵁涓婇潰鍒涘缓鐨勬枃浠舵祦鍒涘缓鍐欐暟鎹祦
+ StreamWriter w = new StreamWriter(fs);
+
+ /**/
+ ///璁剧疆鍐欐暟鎹祦鐨勮捣濮嬩綅缃负鏂囦欢娴佺殑鏈熬
+ w.BaseStream.Seek(0, SeekOrigin.End);
+ /**/
+ ///鍐欏叆鈥淟og Entry : 鈥
+ w.Write("\n\rLog Entry : ");
+ /**/
+ ///鍐欏叆褰撳墠绯荤粺鏃堕棿骞舵崲琛
+ w.Write("{0} {1} \n\r", DateTime.Now.ToLongTimeString(),
+ DateTime.Now.ToLongDateString());
+ /**/
+ ///鍐欏叆鏃ュ織鍐呭骞舵崲琛
+ w.Write(input + "\n\r");
+ /**/
+ ///鍐欏叆------------------------------------鈥滃苟鎹㈣
+ w.Write("------------------------------------\n\r");
+ /**/
+ ///娓呯┖缂撳啿鍖哄唴瀹癸紝骞舵妸缂撳啿鍖哄唴瀹瑰啓鍏ュ熀纭娴
+ w.Flush();
+ /**/
+ ///鍏抽棴鍐欐暟鎹祦
+ w.Close();
+ }
+ }
+ catch { }
+
+ }
+
+ ///
+ /// 鍒犻櫎 month 涓湀涔嬪墠鐨 strFileName鏃ュ織
+ ///
+ ///
+ ///
+ public static void DeleteLogFile(string strFileName = "ErrLog", int month = 1)
+ {
+ try
+ {
+ string logPath = Directory.GetCurrentDirectory() + "\\log\\" + strFileName;
+ if (!Directory.Exists(logPath))//鑻ユ枃浠跺す涓嶅瓨鍦ㄥ垯杩斿洖
+ return;
+ else
+ logPath += "\\";
+ DirectoryInfo theFolder = new DirectoryInfo(@logPath);
+ FileInfo[] fileInfo = theFolder.GetFiles();
+ foreach (FileInfo NextFile in fileInfo) //閬嶅巻鏂囦欢
+ {
+ DateTime dt1 = Convert.ToDateTime(NextFile.Name.Substring(strFileName.Length, NextFile.Name.Length - strFileName.Length - 4) + " 00:00:00");
+ DateTime dt2 = DateTime.Now.AddMonths(-month);
+ if (dt1 < dt2)
+ {
+ NextFile.Delete();
+ }
+ }
+ }
+ catch
+ {
+ }
+
+
+ }
+
+ public void DeleteFiles(string fileName = "")
+ {
+ try
+ {
+ if (string.IsNullOrEmpty(fileName))
+ fileName = Directory.GetCurrentDirectory() + "\\log";
+ if (!Directory.Exists(fileName))//鑻ユ枃浠跺す涓嶅瓨鍦ㄥ垯杩斿洖
+ return;
+ DirectoryInfo dir = new DirectoryInfo(fileName);//new DirectoryInfo(Directory.GetCurrentDirectory() + "\\log");
+ //涓嶆槸鐩綍
+
+ if (dir == null)
+ return;
+ //DateTime DT = dir.CreationTime;
+
+ FileSystemInfo[] files = dir.GetFileSystemInfos();
+ for (int i = 0; i < files.Length; i++)
+ {
+ FileInfo file = files[i] as FileInfo;
+ //鏄枃浠
+ if (file != null)
+ {
+ DateTime DT = file.CreationTime;
+ if (DateTime.Now.Month - DT.Month >= 1)
+ {
+ file.Delete();
+ }
+ }
+ else
+ {
+ DirectoryInfo dir1 = files[i] as DirectoryInfo;
+ if (dir1 != null)
+ {
+ DateTime DT = dir1.CreationTime;
+ if (DateTime.Now.Month - DT.Month >= 1)
+ {
+ //dir1.Delete();
+ System.IO.Directory.Delete(fileName + "\\" + dir1.Name, true);
+ }
+ }
+ }
+ }
+ }
+ catch
+ {
+ }
+
+ }
+
+
+ }
+}
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/DemoUI.csproj b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/DemoUI.csproj
new file mode 100644
index 0000000..a85c6d1
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/DemoUI.csproj
@@ -0,0 +1,236 @@
+锘
+
+
+
+ Debug
+ AnyCPU
+ {4BE25B21-AF00-4BDC-BC24-3A423FB9C87C}
+ WinExe
+ Properties
+ DemoUI
+ DemoUI
+ v4.6
+ 512
+ {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ 4
+
+ publish\
+ true
+ Disk
+ false
+ Foreground
+ 7
+ Days
+ false
+ false
+ true
+ 0
+ 1.0.0.%2a
+ false
+ false
+ true
+
+
+ x86
+ true
+ full
+ false
+ ..\build_32\bin\
+ DEBUG;TRACE
+ prompt
+ 4
+ false
+
+
+ x86
+ pdbonly
+ true
+ ..\build_32\bin\
+ TRACE
+ prompt
+ 4
+ false
+
+
+ true
+ ..\build_32\bin\
+ DEBUG;TRACE
+ full
+ x86
+ prompt
+ MinimumRecommendedRules.ruleset
+ true
+
+
+ ..\build_32\bin\
+ TRACE
+ true
+ pdbonly
+ x86
+ prompt
+ MinimumRecommendedRules.ruleset
+ true
+
+
+ true
+ ..\build_64\bin\
+ DEBUG;TRACE
+ full
+ x64
+ prompt
+ MinimumRecommendedRules.ruleset
+ true
+
+
+ ..\build_64\bin\
+ TRACE
+ true
+ pdbonly
+ x64
+ prompt
+ MinimumRecommendedRules.ruleset
+ true
+
+
+ bin\Release_XP\
+ TRACE
+ true
+ pdbonly
+ x86
+ prompt
+ MinimumRecommendedRules.ruleset
+ false
+
+
+ ..\build_xp\bin\
+ TRACE
+ pdbonly
+ x86
+ prompt
+ MinimumRecommendedRules.ruleset
+ true
+
+
+ bin\x64\Release_XP\
+ TRACE
+ true
+ pdbonly
+ x64
+ prompt
+ MinimumRecommendedRules.ruleset
+ true
+
+
+
+ emgu\Emgu.CV.dll
+
+
+ emgu\Emgu.Util.dll
+
+
+ packages\Fleck.1.1.0\lib\net40\Fleck.dll
+
+
+ packages\Newtonsoft.Json.12.0.2\lib\net40\Newtonsoft.Json.dll
+
+
+
+
+
+
+
+ packages\System.Net.WebSockets.4.3.0\lib\net46\System.Net.WebSockets.dll
+
+
+
+
+
+
+
+
+ 4.0
+
+
+
+
+
+
+
+
+ MSBuild:Compile
+ Designer
+
+
+
+
+
+
+
+
+
+
+ Window1.xaml
+
+
+ MSBuild:Compile
+ Designer
+
+
+ App.xaml
+ Code
+
+
+ MainWindow.xaml
+ Code
+
+
+ Designer
+ MSBuild:Compile
+
+
+
+
+ Code
+
+
+ True
+ True
+ Resources.resx
+
+
+ True
+ Settings.settings
+ True
+
+
+ ResXFileCodeGenerator
+ Resources.Designer.cs
+
+
+
+ SettingsSingleFileGenerator
+ Settings.Designer.cs
+
+
+
+
+
+ Designer
+
+
+
+
+ False
+ .NET Framework 3.5 SP1
+ false
+
+
+
+
+
\ No newline at end of file
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/DemoUI.sln b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/DemoUI.sln
new file mode 100644
index 0000000..9f85849
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/DemoUI.sln
@@ -0,0 +1,32 @@
+锘
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DemoUI", "DemoUI.csproj", "{4BE25B21-AF00-4BDC-BC24-3A423FB9C87C}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|Any CPU = Release|Any CPU
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {4BE25B21-AF00-4BDC-BC24-3A423FB9C87C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4BE25B21-AF00-4BDC-BC24-3A423FB9C87C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4BE25B21-AF00-4BDC-BC24-3A423FB9C87C}.Debug|x64.ActiveCfg = Debug|x64
+ {4BE25B21-AF00-4BDC-BC24-3A423FB9C87C}.Debug|x64.Build.0 = Debug|x64
+ {4BE25B21-AF00-4BDC-BC24-3A423FB9C87C}.Debug|x86.ActiveCfg = Debug|x86
+ {4BE25B21-AF00-4BDC-BC24-3A423FB9C87C}.Debug|x86.Build.0 = Debug|x86
+ {4BE25B21-AF00-4BDC-BC24-3A423FB9C87C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4BE25B21-AF00-4BDC-BC24-3A423FB9C87C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4BE25B21-AF00-4BDC-BC24-3A423FB9C87C}.Release|x64.ActiveCfg = Release|x64
+ {4BE25B21-AF00-4BDC-BC24-3A423FB9C87C}.Release|x64.Build.0 = Release|x64
+ {4BE25B21-AF00-4BDC-BC24-3A423FB9C87C}.Release|x86.ActiveCfg = Release|x86
+ {4BE25B21-AF00-4BDC-BC24-3A423FB9C87C}.Release|x86.Build.0 = Release|x86
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/MainWindow.xaml b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/MainWindow.xaml
new file mode 100644
index 0000000..4a2d520
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/MainWindow.xaml
@@ -0,0 +1,12 @@
+锘
+
+
+
+
+
+
+
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/MainWindow.xaml.cs b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/MainWindow.xaml.cs
new file mode 100644
index 0000000..d3df95d
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/MainWindow.xaml.cs
@@ -0,0 +1,1487 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+using System.IO;
+using DemoUI.SDK;
+using System.Runtime.InteropServices;
+using System.Threading;
+using Emgu.CV;
+using Emgu.CV.Structure;
+using DemoUI.Common;
+using System.Net;
+using System.Configuration;
+using System.Collections;
+using Newtonsoft.Json;
+using System.Diagnostics;
+
+namespace DemoUI
+{
+ ///
+ /// MainWindow.xaml 鐨勪氦浜掗昏緫
+ ///
+ public partial class MainWindow : Window
+ {
+ private int m_iShrelhod = 70; // 姣斿闃堝
+ private int m_iCameraIndex = 0; // 鎵撳紑鐨勬憚鍍忓ご绱㈠紩
+ private string m_IMG1Path = string.Empty; // 鐓х墖1璺緞
+ private string m_IMG2Path = string.Empty; // 鐓х墖2璺緞
+ private string m_IMGAttrPath = string.Empty;// 灞炴х収鐗囪矾寰
+
+ private string m_sLicence = ""; // 浜戜粠鎺堟潈licence
+ private IntPtr m_pDet = IntPtr.Zero; // 妫娴嬪彞鏌勶紝鐢ㄤ簬妫娴嬬嚎绋
+ private IntPtr m_pDetVerify = IntPtr.Zero; // 妫娴嬪彞鏌勶紝鐢ㄤ簬涓荤嚎绋嬶紝姣斿鏃朵汉鑴告娴
+ private IntPtr m_pDetVerify1 = IntPtr.Zero; // 妫娴嬪彞鏌勶紝鐢ㄤ簬涓荤嚎绋嬶紝姣斿鏃朵汉鑴告娴
+ private IntPtr m_pRecog = IntPtr.Zero; // 璇嗗埆鍙ユ焺锛岀敤浜庝富绾跨▼锛屼汉鑴告瘮瀵
+
+ private IntPtr m_pAgeAttri = IntPtr.Zero; // 骞撮緞灞炴у彞鏌勶紝鐢ㄤ簬涓荤嚎绋
+ private IntPtr m_pGenderAttri = IntPtr.Zero; // 鎬у埆灞炴у彞鏌勶紝鐢ㄤ簬涓荤嚎绋
+ private IntPtr m_pRaceAttri = IntPtr.Zero; // 浜虹灞炴у彞鏌勶紝鐢ㄤ簬涓荤嚎绋
+
+ private IntPtr m_pNirLive = IntPtr.Zero; // 绾㈠娲讳綋鍙ユ焺锛岀敤浜庝富绾跨▼
+
+ private IntPtr m_buffResult = IntPtr.Zero; // 淇濆瓨浜鸿劯妫娴嬬粨鏋滅殑鎸囬拡锛屼繚璇佸唴瀛樺彧鍒嗛厤涓娆
+ private IntPtr m_buffVerify = IntPtr.Zero; // 浜鸿劯姣斿鏃朵繚瀛樼粨鏋滅殑鎸囬拡锛屼繚璇佸唴瀛樺彧鍒嗛厤涓娆
+
+ private Capture m_capture = null; // 鎽勫儚澶存搷浣滃璞
+ //private Capture m_capture1 = null; // 鎽勫儚澶存搷浣滃璞
+ private Thread m_threadFaceDet = null; // 妫娴嬬嚎绋
+ private Object m_lock = null; // 閿
+ private Mat m_matFrame = null; // 褰撳墠甯
+ //private Mat m_matFrame1 = null; // 褰撳墠甯
+
+ private byte[] m_btImgBuff = null; // 鍒嗛厤鍐呭瓨淇濆瓨鍥剧墖data
+ private GCHandle m_gc;
+ private bool m_bStartThread = false;
+ private DateTime dtNows = DateTime.Now;
+ private cw_face_res_t? maxFace = null;
+ private Dictionary faceDic = new Dictionary();
+ private Dictionary faceDicTime = new Dictionary();
+ private Dictionary faceDicStopTime = new Dictionary();
+
+
+ //private Dictionary faceCenterDic = new Dictionary();
+ //private Dictionary faceDicCenteTime = new Dictionary();
+ //private Dictionary faceDicCenteStopTime = new Dictionary();
+
+
+
+ private List matList = new List();
+ private bool isOpenLive = false;
+
+ private List listFaceView = new List();
+ private string AddressIP = string.Empty;
+ private string ServiceUrl = string.Empty;
+
+ private QMLog log = new QMLog();
+
+ public MainWindow()
+ {
+ InitializeComponent();
+
+ Loaded += MainWindow_Loaded;
+ ChatWebSocketMiddleware chatWebSocket = new ChatWebSocketMiddleware();
+ chatWebSocket.openSocket();
+ chatWebSocket.openSocketForFace();
+ chatWebSocket.openSocketForLive();
+ //chatWebSocket.openSocketForTest();
+ }
+
+ private void MainWindow_Loaded(object sender, RoutedEventArgs e)
+ {
+ int.TryParse(System.Configuration.ConfigurationManager.AppSettings["Shrelhod"], out m_iShrelhod);
+ if (m_iShrelhod <= 0)
+ {
+ m_iShrelhod = 70;
+ }
+
+ int.TryParse(System.Configuration.ConfigurationManager.AppSettings["CameraIndex"], out m_iCameraIndex);
+
+ m_lock = new object();
+
+ AddressIP = string.Empty;
+ foreach (IPAddress _IPAddress in Dns.GetHostEntry(Dns.GetHostName()).AddressList)
+ {
+ if (_IPAddress.AddressFamily.ToString() == "InterNetwork")
+ {
+ AddressIP = _IPAddress.ToString();
+ }
+ }
+
+ ServiceUrl = ConfigurationManager.AppSettings["HttpUrl"];
+
+ listFaceView.Clear();
+ bool flag = OnBtnInit();
+ if (flag) {
+ OnBtnOpenUsb();
+ }
+ }
+
+ private void Window_Closed(object sender, EventArgs e)
+ {
+ m_bStartThread = false;
+ try
+ {
+ if (null != m_capture)
+ {
+ m_capture.Stop();
+ m_capture.Dispose();
+ }
+
+ //if (null != m_capture1)
+ //{
+ // m_capture1.Stop();
+ // m_capture1.Dispose();
+ //}
+ }
+ catch (Exception exec)
+ {
+
+ }
+
+ if (IntPtr.Zero != m_pDet)
+ {
+ NativeCWFaceDetection.cwReleaseDetHandle(m_pDet);
+ m_pDet = IntPtr.Zero;
+ }
+
+ if (IntPtr.Zero != m_pDetVerify)
+ {
+ NativeCWFaceDetection.cwReleaseDetHandle(m_pDetVerify);
+ m_pDetVerify = IntPtr.Zero;
+ }
+
+ if (IntPtr.Zero != m_pRecog)
+ {
+ NativeCWFaceRecognition.cwReleaseRecogHandle(m_pRecog);
+ m_pRecog = IntPtr.Zero;
+ }
+
+ DestroyAttributeHandle();
+
+ if (m_buffResult != IntPtr.Zero)
+ {
+ Marshal.FreeHGlobal(m_buffResult);
+ m_buffResult = IntPtr.Zero;
+ }
+ if (m_buffVerify != IntPtr.Zero)
+ {
+ Marshal.FreeHGlobal(m_buffVerify);
+ m_buffVerify = IntPtr.Zero;
+ }
+
+ if (m_gc.IsAllocated)
+ {
+ m_gc.Free();
+ }
+ try
+ {
+ var pendingRemoveList = faceDic.Keys.ToList();
+ foreach (int id in pendingRemoveList)
+ {
+ FaceDataModel model = new FaceDataModel();
+ model.Age = faceDic[id].age.ToString();
+ model.BeginTime = faceDicTime[id];
+ model.EndTime = DateTime.Now;
+ model.GenderMale = faceDic[id].sex == 0 ? "濂" : "鐢";
+ model.StopTime = Convert.ToInt32((DateTime.Now - faceDicTime[id]).TotalSeconds);
+ model.IP = AddressIP;
+ if (model.StopTime > 1)
+ {
+ listFaceView.Add(model);
+ }
+ }
+ //MessageBox.Show(listFaceView.Count.ToString());
+ if (listFaceView.Count > 0)
+ {
+ //var data = new
+ //{
+ // FaceListModel = listFaceView,
+ // IP = AddressIP
+ //};
+ var url = ServiceUrl + "/api/Face/UpLoadFace";
+ var param = JsonConvert.SerializeObject(listFaceView);
+ var _r = PostMoths(url, param);
+ listFaceView.Clear();
+ }
+ //MessageBox.Show(pendingRemoveList.Count.ToString());
+ }
+ catch (Exception ex)
+ {
+ //MessageBox.Show(ex.Message);
+ //throw;
+ }
+ Close();
+ }
+
+ // 鍒濆鍖栦簨浠讹紝鍔犺浇妯″瀷锛屽垱寤哄彞鏌
+ private bool OnBtnInit() {
+ bool flag = false;
+ StringBuilder sbVersion = new StringBuilder(100);
+ NativeCWFaceVersion.cwGetSDKVersion(sbVersion, 100);
+ if (IntPtr.Zero != m_pDet && IntPtr.Zero != m_pRecog)
+ {
+ MessageBox.Show("宸插垵濮嬪寲杩囷紝涓嶅啀鍒濆鍖");
+ return flag;
+ }
+
+ // 32浣嶅拰64浣嶆娴嬫ā鍨嬩笉鑳藉叡鐢紝64浣嶇敤_configs_frontend.xml锛岄潪64浣嶇敤_configs_frontend_x86_arm.xml
+ string sModelXmlPath;
+ if (Environment.Is64BitProcess)
+ {
+ sModelXmlPath = "../../CWModels/_configs_frontend.xml";
+ }
+ else
+ {
+ sModelXmlPath = "../../CWModels/_configs_frontend_x86_arm.xml";
+ }
+
+ SDK.cw_errcode_t errCode = cw_errcode_t.CW_OK;
+ m_pDet = NativeCWFaceDetection.cwCreateDetHandle(out errCode, sModelXmlPath, m_sLicence);
+ if (IntPtr.Zero == m_pDet || errCode != cw_errcode_t.CW_OK)
+ {
+ MessageBox.Show("妫娴嬪彞鏌1鍒涘缓澶辫触锛岄敊璇爜锛" + errCode.ToString());
+ return flag;
+ }
+ cw_det_param_t param;
+ NativeCWFaceDetection.cwGetFaceParam(m_pDet, out param);
+ param.minSize = 48;
+ param.maxSize = 600;
+ param.pConfigFile = sModelXmlPath; // 璁剧疆鎺ュ彛鍔熻兘鍙傛暟
+ NativeCWFaceDetection.cwSetFaceParam(m_pDet, ref param);
+
+ m_pDetVerify = NativeCWFaceDetection.cwCreateDetHandle(out errCode, sModelXmlPath, m_sLicence);
+ if (IntPtr.Zero == m_pDetVerify || errCode != cw_errcode_t.CW_OK)
+ {
+ MessageBox.Show("妫娴嬪彞鏌2鍒涘缓澶辫触锛岄敊璇爜锛" + errCode.ToString());
+ return flag;
+ }
+ NativeCWFaceDetection.cwGetFaceParam(m_pDetVerify, out param);
+ param.minSize = 30;
+ param.maxSize = 600;
+ param.pConfigFile = sModelXmlPath; // 璁剧疆鎺ュ彛鍔熻兘鍙傛暟
+ NativeCWFaceDetection.cwSetFaceParam(m_pDetVerify, ref param);
+
+ m_pDetVerify1 = NativeCWFaceDetection.cwCreateDetHandle(out errCode, sModelXmlPath, m_sLicence);
+ if (IntPtr.Zero == m_pDetVerify1 || errCode != cw_errcode_t.CW_OK)
+ {
+ MessageBox.Show("妫娴嬪彞鏌2鍒涘缓澶辫触锛岄敊璇爜锛" + errCode.ToString());
+ return flag;
+ }
+ NativeCWFaceDetection.cwGetFaceParam(m_pDetVerify1, out param);
+ param.minSize = 30;
+ param.maxSize = 600;
+ param.pConfigFile = sModelXmlPath; // 璁剧疆鎺ュ彛鍔熻兘鍙傛暟
+ NativeCWFaceDetection.cwSetFaceParam(m_pDetVerify1, ref param);
+
+ // NativeCWFaceDetection.cwSetFaceBufOrder(m_pDetVerify, 1);
+
+ //鎻愬彇鐗瑰緛
+ m_pRecog = NativeCWFaceRecognition.cwCreateRecogHandle(out errCode, "../../CWModels/CWR_Config_1_1.xml", m_sLicence, SDK.cw_recog_pattern_t.CW_FEATURE_EXTRACT);
+
+ if (IntPtr.Zero == m_pRecog || errCode != cw_errcode_t.CW_OK)
+ {
+ MessageBox.Show("璇嗗埆鍙ユ焺鍒涘缓澶辫触锛岄敊璇爜锛" + errCode.ToString());
+ return flag;
+ }
+
+ errCode = CreateAttributeHandle();
+ if (errCode != cw_errcode_t.CW_OK)
+ {
+ return flag;
+ }
+
+ cw_nirliveness_err_t errCodeNir = CreateNirLivenessHandle();
+ if (errCodeNir == cw_nirliveness_err_t.CW_NIRLIV_OK)
+ {
+ flag = true;
+
+ }
+ return flag;
+ }
+
+ // 寮鍚疷SB鎽勫儚澶
+ private void OnBtnOpenUsb()
+ {
+ if (IntPtr.Zero == m_pDet)
+ {
+ MessageBox.Show("妫娴嬪彞鏌勪负绌猴紝璇峰厛鍒濆鍖栧垱寤哄彞鏌");
+ return;
+ }
+ if (m_bStartThread)
+ {
+ MessageBox.Show("鎽勫儚澶村凡鎵撳紑");
+ return;
+ }
+
+ try
+ {
+ // 璋冪敤emgu鎵撳紑鎽勫儚澶达紝闇鍏堝皢emgu鏂囦欢澶逛腑鐨"cvextern.dll"鎷疯礉鍒扮紪璇戝ソ鐨凟XE绋嬪簭鐩綍"build_32/bin"涓
+ m_capture = new Capture(0);
+ if (m_capture.Height< 1 || m_capture.Width< 1)
+ {
+ MessageBox.Show("绾㈠鎽勫儚澶存墦寮澶辫触");
+ return;
+ }
+ m_capture.Start();
+
+
+ //m_capture1 = new Capture(1);
+ //if (m_capture1.Height < 1 || m_capture1.Width < 1)
+ //{
+ // MessageBox.Show("鍙鍏夋憚鍍忓ご鎵撳紑澶辫触");
+ // return;
+ //}
+ //m_capture1.Start();
+
+ m_threadFaceDet = new Thread(new ThreadStart(ThreadFaceDet));
+ m_bStartThread = true;
+ m_threadFaceDet.Start();
+ }
+ catch (Exception exec)
+ {
+ MessageBox.Show(exec.Message + "\r\n璇峰皢褰撳墠鐩綍emgu涓嬬殑cvextern.dll鎷疯礉鍒版墽琛岀▼搴忕洰褰");
+ }
+ }
+
+
+ private void ThreadFaceDet()
+ {
+ while (m_bStartThread)
+ {
+ try
+ {
+ Mat mat = null;
+ //Mat matCenter = null;
+ lock (m_lock)
+ {
+ m_matFrame = m_capture.QueryFrame();
+ if (null != m_matFrame)
+ {
+ mat = m_matFrame.Clone();
+ //matCenter = new Mat(mat, new System.Drawing.Rectangle(new System.Drawing.Point(mat.Width / 2 - 150, mat.Height / 2 - 150),
+ // new System.Drawing.Size(300, 300)));
+ }
+
+
+ //m_matFrame1 = m_capture1.QueryFrame();
+ //if (null != m_matFrame1)
+ //{
+ // mat1 = m_matFrame1.Clone();
+ // mat1Center = new Mat(mat1, new System.Drawing.Rectangle(new System.Drawing.Point(mat1.Width / 2 - 150, mat1.Height / 2 - 150),
+ // new System.Drawing.Size(300, 300)));
+ //}
+
+
+
+ /////////鎺ㄩ佹祦鏂囦欢
+ if (ChatWebSocketMiddleware.isLive)
+ {
+ Emgu.CV.Util.VectorOfByte buff = new Emgu.CV.Util.VectorOfByte();
+ CvInvoke.Imencode(".jpg", mat, buff);
+ byte[] encodeBuff = new byte[buff.Size];
+ Marshal.Copy(buff.StartAddress, encodeBuff, 0, buff.Size);
+
+ string base64Str = Convert.ToBase64String(encodeBuff);
+ //ChatWebSocketMiddleware.allSockets.ToList().ForEach(s => s.Send(base64Str));
+ var faceData = new
+ {
+ faceID = "-1",
+ faceImage = base64Str
+ };
+ ChatWebSocketMiddleware.allSocketsForLive.ToList().ForEach(s => s.Send(JsonConvert.SerializeObject(faceData)));
+ }
+ }
+
+ //if (mat != null)
+ //{
+
+
+
+ // var result = FaceDetect(mat);
+ // var pendingRemoveList = faceDic.Keys.ToList();
+ // //var removeList = new ArrayList();
+ // if (result != null && result.Count > 0)
+ // {
+ // SDK.cw_errcode_t errCode = cw_errcode_t.CW_OK;
+ // foreach (cw_face_res_t facepos in result)
+ // {
+ // if (!faceDic.ContainsKey(facepos.trackId))
+ // {
+ // int pAge = 0;
+ // cw_aligned_face_t faceAligned = facepos.faceAligned;
+ // errCode = NativeCWFaceAttribute.cwGetAgeEval(m_pAgeAttri, ref faceAligned, out pAge);
+ // int pGender = 0;
+ // float pGenderConfidence = 0.000F;
+ // errCode = NativeCWFaceAttribute.cwGetGenderEval(m_pGenderAttri, ref faceAligned, out pGender, out pGenderConfidence);
+ // cwFaceAttr cwFaceAttr = new cwFaceAttr();
+ // //0 灏忓 1 鎴愬勾浜 2 鑰佷汉
+ // cwFaceAttr.age = pAge.ToString();
+ // cwFaceAttr.sex = pGender;
+ // cwFaceAttr.faceid = facepos.trackId.ToString();
+ // faceDic.Add(facepos.trackId, cwFaceAttr);
+ // faceDicTime.Add(facepos.trackId, DateTime.Now);
+ // SendHttpForNavigation(mat, facepos);
+ // }
+ // else
+ // {
+ // pendingRemoveList.Remove(facepos.trackId);
+ // }
+ // if (faceDicStopTime.Keys.Contains(facepos.trackId) && faceDicStopTime[facepos.trackId].HasValue)
+ // {
+ // faceDicStopTime[facepos.trackId] = null;
+ // }
+ // }
+
+ // foreach (int id in pendingRemoveList)
+ // {
+ // if (!faceDicStopTime.Keys.Contains(id))
+ // {
+ // faceDicStopTime.Add(id, DateTime.Now);
+ // }
+ // else if (!faceDicStopTime[id].HasValue)
+ // {
+ // faceDicStopTime[id] = DateTime.Now;
+ // }
+ // else if (faceDicStopTime[id].Value.AddSeconds(2) <= DateTime.Now)
+ // {
+ // AddFaceView(faceDic[id], faceDicTime[id]);
+ // faceDic.Remove(id);
+ // faceDicTime.Remove(id);
+ // faceDicStopTime.Remove(id);
+ // }
+ // }
+ // }
+ // else
+ // {
+ // foreach (int id in pendingRemoveList)
+ // {
+ // if (!faceDicStopTime.Keys.Contains(id))
+ // {
+ // faceDicStopTime.Add(id, DateTime.Now);
+ // }
+ // else if (!faceDicStopTime[id].HasValue)
+ // {
+ // faceDicStopTime[id] = DateTime.Now;
+ // }
+ // else if (faceDicStopTime[id].Value.AddSeconds(2) <= DateTime.Now)
+ // {
+ // AddFaceView(faceDic[id], faceDicTime[id]);
+ // faceDic.Remove(id);
+ // faceDicTime.Remove(id);
+ // faceDicStopTime.Remove(id);
+ // }
+ // }
+ // }
+
+ // this.Dispatcher.BeginInvoke(new Action(() =>
+ // {
+ // video.Source = ToBitmapSource(mat); // 鏄剧ず鍒扮晫闈笂
+ // }));
+ //}
+ //if (matCenter != null)
+ //{
+
+
+ // var result = FaceDetect(mat);
+ // var result1 = FaceDetect(matCenter);
+
+ // //int channels = mat.NumberOfChannels;
+ // cw_face_res_t? curMatFace = null;
+ // var pendingRemoveList = faceCenterDic.Keys.ToList();
+ // if (result != null && result.Count > 0)
+ // {
+ // SDK.cw_errcode_t errCode = cw_errcode_t.CW_OK;
+ // //log.WriteLogFile(JsonConvert.SerializeObject(result),"1234");
+ // foreach (cw_face_res_t facepos in result)
+ // {
+
+ // if (facepos.quality.errcode == cw_quality_errcode_t.CW_QUALITY_OK && facepos.quality.scores[0] > 0.8 && facepos.quality.scores[1] > 0.8 && (curMatFace == null || (curMatFace != null && facepos.faceRect.width > curMatFace.Value.faceRect.width)))
+ // {
+ // curMatFace = facepos;
+ // }
+
+ // if (!faceCenterDic.ContainsKey(facepos.trackId))
+ // {
+ // //CvInvoke.Rectangle(mat1, new System.Drawing.Rectangle(facepos.faceRect.x, facepos.faceRect.y, facepos.faceRect.width, facepos.faceRect.height), new MCvScalar(0, 0, 255), 2);
+ // int pAge = 0;
+ // cw_aligned_face_t faceAligned = facepos.faceAligned;
+ // errCode = NativeCWFaceAttribute.cwGetAgeEval(m_pAgeAttri, ref faceAligned, out pAge);
+ // //ShowAgeGroupResult(errCode, pAge, pAgeConfidence);
+
+ // int pGender = 0;
+ // float pGenderConfidence = 0.000F;
+ // errCode = NativeCWFaceAttribute.cwGetGenderEval(m_pGenderAttri, ref faceAligned, out pGender, out pGenderConfidence);
+ // cwFaceAttr cwFaceAttr = new cwFaceAttr();
+ // //0 灏忓 1 鎴愬勾浜 2 鑰佷汉
+ // cwFaceAttr.age = pAge.ToString();
+ // cwFaceAttr.sex = pGender;
+ // cwFaceAttr.faceid = facepos.trackId.ToString();
+ // //ShowGenderResult(errCode, pGender, pGenderConfidence);
+ // faceCenterDic.Add(facepos.trackId, cwFaceAttr);
+ // //dict[face.ID] = faceResult.Item2;
+ // faceDicCenteTime.Add(facepos.trackId, DateTime.Now);
+ // //dictFace[face.ID] = face;
+ // }
+ // else
+ // {
+ // pendingRemoveList.Remove(facepos.trackId);
+ // //dictFace[face.ID] = face;
+ // }
+ // if (faceDicCenteStopTime.Keys.Contains(facepos.trackId) && faceDicCenteStopTime[facepos.trackId].HasValue)
+ // {
+ // faceDicCenteStopTime[facepos.trackId] = null;
+ // }
+ // //if (ChatWebSocketMiddleware.isLive)
+ // //{
+ // // if (maxFace.HasValue && maxFace.Value.trackId == facepos.trackId)
+ // // {
+ // // //CvInvoke.PutText(mat, $"{facepos.trackId}", new System.Drawing.Point(facepos.faceRect.x + (facepos.faceRect.width / 2), facepos.faceRect.y), Emgu.CV.CvEnum.FontFace.HersheyScriptComplex, 1, new MCvScalar(255, 255, 0), 2);
+ // // //CvInvoke.PutText(mat1, $"{facepos.trackId}", new System.Drawing.Point(facepos.faceRect.x + (facepos.faceRect.width / 2), facepos.faceRect.y), Emgu.CV.CvEnum.FontFace.HersheyScriptComplex, 1, new MCvScalar(255, 255, 0), 2);
+ // // ChatWebSocketMiddleware.CurFaceImage = mat;
+ // // ChatWebSocketMiddleware.CurFaceModel = facepos;
+ // // SendHttpForLive(mat, facepos);
+ // // }
+ // //}
+ // //CvInvoke.PutText(mat, $"{facepos.trackId}, {pAge} ,{pGender},{pRace}", new System.Drawing.Point(facepos.faceRect.x + (facepos.faceRect.width / 2), facepos.faceRect.y), Emgu.CV.CvEnum.FontFace.HersheyScriptComplex, 1, new MCvScalar(255, 255, 0), 2);
+ // //CvInvoke.PutText(mat1, $"{facepos.trackId}, {pAge} ,{pGender},{pRace}", new System.Drawing.Point(facepos.faceRect.x + (facepos.faceRect.width / 2), facepos.faceRect.y), Emgu.CV.CvEnum.FontFace.HersheyScriptComplex, 1, new MCvScalar(255, 255, 0), 2);
+ // }
+
+ // foreach (int id in pendingRemoveList)
+ // {
+ // if (!faceDicCenteStopTime.Keys.Contains(id))
+ // {
+ // faceDicCenteStopTime.Add(id, DateTime.Now);
+ // }
+ // else if (!faceDicCenteStopTime[id].HasValue)
+ // {
+ // faceDicCenteStopTime[id] = DateTime.Now;
+ // }
+ // else if (faceDicCenteStopTime[id].Value.AddSeconds(2) <= DateTime.Now)
+ // {
+ // faceCenterDic.Remove(id);
+ // faceDicCenteTime.Remove(id);
+ // //log.WriteLogFile("浜虹寮","face12345");
+ // //log.WriteLogFile(faceDicTime.Keys.Count.ToString(), "face12345");
+ // faceDicCenteStopTime.Remove(id);
+ // if (maxFace.Value.trackId == id)
+ // {
+ // //log.WriteLogFile("涓昏劯绂诲紑", "face12345");
+ // maxFace = null;
+ // ChatWebSocketMiddleware.CurFaceID = "";
+ // ChatWebSocketMiddleware.allSockets.ToList().ForEach(s => s.Send(JsonConvert.SerializeObject(ChatWebSocketMiddleware.NoFaceModel)));
+ // //if (ChatWebSocketMiddleware.isLive)
+ // //{
+ // // var faceData = new
+ // // {
+ // // faceID = "-1",
+ // // faceImage = ""
+ // // };
+ // // ChatWebSocketMiddleware.allSockets.ToList().ForEach(s => s.Send(JsonConvert.SerializeObject(faceData)));
+ // //}
+ // }
+ // }
+ // }
+ // if (maxFace.HasValue && !faceCenterDic.Keys.Contains(maxFace.Value.trackId))
+ // {
+ // maxFace = null;
+ // //if (ChatWebSocketMiddleware.isLive)
+ // //{
+ // // var faceData = new
+ // // {
+ // // faceID = "-1",
+ // // faceImage = ""
+ // // };
+ // // ChatWebSocketMiddleware.allSockets.ToList().ForEach(s => s.Send(JsonConvert.SerializeObject(faceData)));
+ // //}
+ // ChatWebSocketMiddleware.CurFaceID = "";
+ // ChatWebSocketMiddleware.allSockets.ToList().ForEach(s => s.Send(JsonConvert.SerializeObject(ChatWebSocketMiddleware.NoFaceModel)));
+ // }
+ // //log.WriteLogFile("鏄惁鏈夎劯"+maxFace.HasValue, "face12345");
+ // //log.WriteLogFile("褰撳墠鑴" + curMatFace.HasValue, "face12345");
+ // //if (curMatFace.HasValue) {
+ // // log.WriteLogFile("褰撳墠鑴告槸鍚﹁秴鏃" + (faceDicTime[curMatFace.Value.trackId].AddSeconds(2) <= DateTime.Now), "face12345");
+ // //}
+ // if (!isOpenLive && !maxFace.HasValue && curMatFace.HasValue && faceDicCenteTime[curMatFace.Value.trackId].AddSeconds(2) <= DateTime.Now)
+ // {
+ // maxFace = curMatFace;
+ // //CvInvoke.Rectangle(mat, new System.Drawing.Rectangle(maxFace.Value.faceRect.x, maxFace.Value.faceRect.y, maxFace.Value.faceRect.width, maxFace.Value.faceRect.height), new MCvScalar(0, 0, 255), 2);
+ // //CvInvoke.PutText(mat, $"{maxFace.Value.trackId}", new System.Drawing.Point(maxFace.Value.faceRect.x + (maxFace.Value.faceRect.width / 2), maxFace.Value.faceRect.y), Emgu.CV.CvEnum.FontFace.HersheyScriptComplex, 1, new MCvScalar(255, 255, 0), 2);
+ // CvInvoke.Imwrite("./a.jpg", m_matFrame);
+ // SendHttpForKiosk(matCenter, curMatFace.Value);
+ // ChatWebSocketMiddleware.CurFaceImage = matCenter;
+ // ChatWebSocketMiddleware.CurFaceModel = curMatFace.Value;
+ // }
+ // }
+ // else
+ // {
+ // foreach (int id in pendingRemoveList)
+ // {
+ // if (!faceDicCenteStopTime.Keys.Contains(id))
+ // {
+ // faceDicCenteStopTime.Add(id, DateTime.Now);
+ // }
+ // else if (!faceDicCenteStopTime[id].HasValue)
+ // {
+ // faceDicCenteStopTime[id] = DateTime.Now;
+ // }
+ // else if (faceDicCenteStopTime[id].Value.AddSeconds(2) <= DateTime.Now)
+ // {
+ // faceCenterDic.Remove(id);
+ // faceDicCenteTime.Remove(id);
+ // faceDicCenteStopTime.Remove(id);
+ // }
+ // }
+ // if (maxFace.HasValue && !faceCenterDic.Keys.Contains(maxFace.Value.trackId))
+ // {
+ // maxFace = null;
+ // ChatWebSocketMiddleware.CurFaceID = "";
+ // ChatWebSocketMiddleware.allSockets.ToList().ForEach(s => s.Send(JsonConvert.SerializeObject(ChatWebSocketMiddleware.NoFaceModel)));
+ // //if (ChatWebSocketMiddleware.isLive)
+ // //{
+ // // var faceData = new
+ // // {
+ // // faceID = "-1",
+ // // faceImage = ""
+ // // };
+ // // ChatWebSocketMiddleware.allSockets.ToList().ForEach(s => s.Send(JsonConvert.SerializeObject(faceData)));
+ // //}
+ // }
+ // }
+
+ // this.Dispatcher.BeginInvoke(new Action(() =>
+ // {
+ // video.Source = ToBitmapSource(matCenter); // 鏄剧ず鍒扮晫闈笂
+ // }));
+ //}
+
+ if (mat != null)
+ {
+ var result = FaceDetect(mat);
+ //int channels = mat.NumberOfChannels;
+ cw_face_res_t? curMatFace = null;
+ var pendingRemoveList = faceDic.Keys.ToList();
+ var removeList = new ArrayList();
+ if (result != null && result.Count > 0)
+ {
+ SDK.cw_errcode_t errCode = cw_errcode_t.CW_OK;
+ //log.WriteLogFile(JsonConvert.SerializeObject(result),"1234");
+ foreach (cw_face_res_t facepos in result)
+ {
+
+ if (facepos.quality.errcode == cw_quality_errcode_t.CW_QUALITY_OK && facepos.quality.scores[0] > 0.8 && facepos.quality.scores[1] > 0.8 && (curMatFace == null || (curMatFace != null && facepos.faceRect.width > curMatFace.Value.faceRect.width)))
+ {
+ curMatFace = facepos;
+ }
+
+ if (!faceDic.ContainsKey(facepos.trackId))
+ {
+ //CvInvoke.Rectangle(mat1, new System.Drawing.Rectangle(facepos.faceRect.x, facepos.faceRect.y, facepos.faceRect.width, facepos.faceRect.height), new MCvScalar(0, 0, 255), 2);
+ int pAge = 0;
+ cw_aligned_face_t faceAligned = facepos.faceAligned;
+ errCode = NativeCWFaceAttribute.cwGetAgeEval(m_pAgeAttri, ref faceAligned, out pAge);
+ //ShowAgeGroupResult(errCode, pAge, pAgeConfidence);
+
+ int pGender = 0;
+ float pGenderConfidence = 0.000F;
+ errCode = NativeCWFaceAttribute.cwGetGenderEval(m_pGenderAttri, ref faceAligned, out pGender, out pGenderConfidence);
+ cwFaceAttr cwFaceAttr = new cwFaceAttr();
+ //0 灏忓 1 鎴愬勾浜 2 鑰佷汉
+ cwFaceAttr.age = pAge.ToString();
+ cwFaceAttr.sex = pGender;
+ cwFaceAttr.faceid = facepos.trackId.ToString();
+ //ShowGenderResult(errCode, pGender, pGenderConfidence);
+ faceDic.Add(facepos.trackId, cwFaceAttr);
+ //dict[face.ID] = faceResult.Item2;
+ faceDicTime.Add(facepos.trackId, DateTime.Now);
+ SendHttpForNavigation(mat, facepos);
+ //dictFace[face.ID] = face;
+ }
+ else
+ {
+ pendingRemoveList.Remove(facepos.trackId);
+ //dictFace[face.ID] = face;
+ }
+ if (faceDicStopTime.Keys.Contains(facepos.trackId) && faceDicStopTime[facepos.trackId].HasValue)
+ {
+ faceDicStopTime[facepos.trackId] = null;
+ }
+ //if (ChatWebSocketMiddleware.isTestLive)
+ //{
+ // if (maxFace.HasValue && maxFace.Value.trackId == facepos.trackId)
+ // {
+ // //CvInvoke.PutText(mat, $"{facepos.trackId}", new System.Drawing.Point(facepos.faceRect.x + (facepos.faceRect.width / 2), facepos.faceRect.y), Emgu.CV.CvEnum.FontFace.HersheyScriptComplex, 1, new MCvScalar(255, 255, 0), 2);
+ // //CvInvoke.PutText(mat1, $"{facepos.trackId}", new System.Drawing.Point(facepos.faceRect.x + (facepos.faceRect.width / 2), facepos.faceRect.y), Emgu.CV.CvEnum.FontFace.HersheyScriptComplex, 1, new MCvScalar(255, 255, 0), 2);
+ // ChatWebSocketMiddleware.CurFaceImage = mat;
+ // ChatWebSocketMiddleware.CurFaceModel = facepos;
+ // SendHttpForLive(mat, facepos);
+ // }
+ //}
+ //CvInvoke.PutText(mat, $"{facepos.trackId}, {pAge} ,{pGender},{pRace}", new System.Drawing.Point(facepos.faceRect.x + (facepos.faceRect.width / 2), facepos.faceRect.y), Emgu.CV.CvEnum.FontFace.HersheyScriptComplex, 1, new MCvScalar(255, 255, 0), 2);
+ //CvInvoke.PutText(mat1, $"{facepos.trackId}, {pAge} ,{pGender},{pRace}", new System.Drawing.Point(facepos.faceRect.x + (facepos.faceRect.width / 2), facepos.faceRect.y), Emgu.CV.CvEnum.FontFace.HersheyScriptComplex, 1, new MCvScalar(255, 255, 0), 2);
+ }
+
+ foreach (int id in pendingRemoveList)
+ {
+ if (!faceDicStopTime.Keys.Contains(id))
+ {
+ faceDicStopTime.Add(id, DateTime.Now);
+ }
+ else if (!faceDicStopTime[id].HasValue)
+ {
+ faceDicStopTime[id] = DateTime.Now;
+ }
+ else if (faceDicStopTime[id].Value.AddSeconds(2) <= DateTime.Now)
+ {
+ AddFaceView(faceDic[id], faceDicTime[id]);
+ //log.WriteLogFile(faceDicTime.Keys.Count.ToString(), "face12345");
+ faceDic.Remove(id);
+ faceDicTime.Remove(id);
+ //log.WriteLogFile("浜虹寮","face12345");
+ //log.WriteLogFile(faceDicTime.Keys.Count.ToString(), "face12345");
+ faceDicStopTime.Remove(id);
+ if (maxFace.Value.trackId == id)
+ {
+ //log.WriteLogFile("涓昏劯绂诲紑", "face12345");
+ maxFace = null;
+ ChatWebSocketMiddleware.CurFaceID = "";
+ ChatWebSocketMiddleware.allSockets.ToList().ForEach(s => s.Send(JsonConvert.SerializeObject(ChatWebSocketMiddleware.NoFaceModel)));
+ //if (ChatWebSocketMiddleware.isTestLive)
+ //{
+ // var faceData = new
+ // {
+ // faceID = "-1",
+ // faceImage = ""
+ // };
+ // ChatWebSocketMiddleware.allSocketsForTest.ToList().ForEach(s => s.Send(JsonConvert.SerializeObject(faceData)));
+ //}
+ }
+ }
+ }
+ if (maxFace.HasValue && !faceDic.Keys.Contains(maxFace.Value.trackId))
+ {
+ maxFace = null;
+ //if (ChatWebSocketMiddleware.isTestLive)
+ //{
+ // var faceData = new
+ // {
+ // faceID = "-1",
+ // faceImage = ""
+ // };
+ // ChatWebSocketMiddleware.allSocketsForTest.ToList().ForEach(s => s.Send(JsonConvert.SerializeObject(faceData)));
+ //}
+ ChatWebSocketMiddleware.CurFaceID = "";
+ ChatWebSocketMiddleware.allSockets.ToList().ForEach(s => s.Send(JsonConvert.SerializeObject(ChatWebSocketMiddleware.NoFaceModel)));
+ }
+ //log.WriteLogFile("鏄惁鏈夎劯"+maxFace.HasValue, "face12345");
+ //log.WriteLogFile("褰撳墠鑴" + curMatFace.HasValue, "face12345");
+ //if (curMatFace.HasValue) {
+ // log.WriteLogFile("褰撳墠鑴告槸鍚﹁秴鏃" + (faceDicTime[curMatFace.Value.trackId].AddSeconds(2) <= DateTime.Now), "face12345");
+ //}
+ if (!isOpenLive && !maxFace.HasValue && curMatFace.HasValue && faceDicTime[curMatFace.Value.trackId].AddSeconds(2) <= DateTime.Now)
+ {
+ maxFace = curMatFace;
+ //CvInvoke.Rectangle(mat, new System.Drawing.Rectangle(maxFace.Value.faceRect.x, maxFace.Value.faceRect.y, maxFace.Value.faceRect.width, maxFace.Value.faceRect.height), new MCvScalar(0, 0, 255), 2);
+ //CvInvoke.PutText(mat, $"{maxFace.Value.trackId}", new System.Drawing.Point(maxFace.Value.faceRect.x + (maxFace.Value.faceRect.width / 2), maxFace.Value.faceRect.y), Emgu.CV.CvEnum.FontFace.HersheyScriptComplex, 1, new MCvScalar(255, 255, 0), 2);
+ CvInvoke.Imwrite("./a.jpg", m_matFrame);
+ SendHttpForKiosk(mat, curMatFace.Value);
+ ChatWebSocketMiddleware.CurFaceImage = mat;
+ ChatWebSocketMiddleware.CurFaceModel = curMatFace.Value;
+ }
+ }
+ else
+ {
+ foreach (int id in pendingRemoveList)
+ {
+ if (!faceDicStopTime.Keys.Contains(id))
+ {
+ faceDicStopTime.Add(id, DateTime.Now);
+ }
+ else if (!faceDicStopTime[id].HasValue)
+ {
+ faceDicStopTime[id] = DateTime.Now;
+ }
+ else if (faceDicStopTime[id].Value.AddSeconds(2) <= DateTime.Now)
+ {
+ AddFaceView(faceDic[id], faceDicTime[id]);
+ faceDic.Remove(id);
+ faceDicTime.Remove(id);
+ faceDicStopTime.Remove(id);
+ }
+ }
+ if (maxFace.HasValue && !faceDic.Keys.Contains(maxFace.Value.trackId))
+ {
+ maxFace = null;
+ ChatWebSocketMiddleware.CurFaceID = "";
+ ChatWebSocketMiddleware.allSockets.ToList().ForEach(s => s.Send(JsonConvert.SerializeObject(ChatWebSocketMiddleware.NoFaceModel)));
+ //if (ChatWebSocketMiddleware.isTestLive)
+ //{
+ // var faceData = new
+ // {
+ // faceID = "-1",
+ // faceImage = ""
+ // };
+ // ChatWebSocketMiddleware.allSocketsForTest.ToList().ForEach(s => s.Send(JsonConvert.SerializeObject(faceData)));
+ //}
+ }
+ }
+
+ this.Dispatcher.BeginInvoke(new Action(() =>
+ {
+ video.Source = ToBitmapSource(mat); // 鏄剧ず鍒扮晫闈笂
+ }));
+ }
+
+ }
+ catch (Exception e)
+ {
+ string s = e.Message.ToString();
+ }
+ }
+ }
+
+ private void SendHttpForKiosk(Mat frame, cw_face_res_t face)
+ {
+ if (faceDic.ContainsKey(face.trackId))
+ {
+ var age = faceDic[face.trackId].age;
+ var sex = faceDic[face.trackId].sex;
+ //Process[] proSc = Process.GetProcesses();
+ //bool pcstart = false;
+ //var oldFace = faceEntryTime.Where(i => i.Value.AddMinutes(1) < DateTime.Now).Select(i => i.Key).ToList();
+ //foreach (var item in oldFace)
+ //{
+ // faceEntryTime.Remove(item);
+ //}
+ //for (int i = 0; i < proSc.Length; i++)
+ //{
+ // if (proSc[i].ProcessName.ToLower().Trim() == "pcscreensavers")
+ // {
+ // pcstart = true;
+ // break;
+ // }
+ //}
+ //if (pcstart)
+ //{
+ int x = 0;
+ int y = 0;
+ int width = 0;
+ int height = 0;
+ if ((int)face.faceRect.x > 20)
+ {
+ x = (int)face.faceRect.x - 20;
+ //qMLog.WriteLogToFile("x:"+ ((int)face.Rect.X)+ " Width"+ ((int)face.Rect.Width)+ " frame"+ frame.Width,"111");
+ width = (x + (int)face.faceRect.width+40) >= frame.Width ? (frame.Width - x) : (int)face.faceRect.width+60;
+ //width += 10;
+ }
+ else
+ {
+ x = 0;
+ width = (int)face.faceRect.x+(int)face.faceRect.width+40 >= frame.Width ? frame.Width : (int)face.faceRect.width + 40 + (int)face.faceRect.x ;
+ //width += x;
+ }
+
+ if ((int)face.faceRect.y > 60)
+ {
+ y = (int)face.faceRect.y - 60;
+
+ height = (y + (int)face.faceRect.height+ 40) >= frame.Height ? (frame.Height - y) : (int)face.faceRect.height+100;
+
+ }
+ else
+ {
+ y = 0;
+ height = (int)face.faceRect.y+(int)face.faceRect.height+ 40 >= frame.Height ? frame.Height : (int)face.faceRect.height+ 40 + (int)face.faceRect.y;
+
+ }
+ string AddressIP = string.Empty;
+ foreach (IPAddress _IPAddress in Dns.GetHostEntry(Dns.GetHostName()).AddressList)
+ {
+ if (_IPAddress.AddressFamily.ToString() == "InterNetwork")
+ {
+ AddressIP = _IPAddress.ToString();
+ }
+ }
+ try
+ {
+ using (Mat newFrame = new Mat(frame, new System.Drawing.Rectangle(new System.Drawing.Point(x, y),
+ new System.Drawing.Size(width, height))))
+ {
+ Emgu.CV.Util.VectorOfByte buff = new Emgu.CV.Util.VectorOfByte();
+ CvInvoke.Imencode(".jpg", newFrame, buff);
+ //CvInvoke.Imwrite("./Kiosk/" + Guid.NewGuid().ToString()+".jpg", newFrame);
+ byte[] encodeBuff = new byte[buff.Size];
+ Marshal.Copy(buff.StartAddress, encodeBuff, 0, buff.Size);
+
+ string base64Str = Convert.ToBase64String(encodeBuff);
+ //if (!faceEntryTime.ContainsKey(face.ID))
+ //{
+ // faceEntryTime.Add(face.ID, DateTime.Now);
+ var url = ConfigurationManager.AppSettings["KioskUrl"] + "/api/Face/UpLoadFace";
+ string data = "Face=" + base64Str + "&ip=" + AddressIP + "&Age=" + age + "&GenderMale=" + sex;
+ log.WriteLogFile(data, "111");
+ var _r = PostMothsForm(url, data);
+ log.WriteLogFile(_r,"111");
+ Dictionary dic = JsonConvert.DeserializeObject>(_r);
+ log.WriteLogFile(dic["code"].ToString(), "222");
+ if (dic["code"].ToString() == "200")
+ {
+ Dictionary dicData = JsonConvert.DeserializeObject>(dic["data"].ToString());
+ //log.WriteLogFile((sex == 1 ? "鐢" : 3 "濂") + " " + (dicData["genderMale"].ToString() == "1" ? "鐢" : "濂"), "sex");
+ var faceData = new { faceID = dicData["faceID"], isValid = dicData["isValid"], beautyScore = dicData["beautyScore"], faceImage = base64Str, genderMale = (sex == 1 ? "鐢" : "濂") };
+ //var faceData = new { faceID= dicData["faceID"], isValid= dicData["isValid"], beautyScore= dicData["beautyScore"],faceImage= base64Str, genderMale= (dicData["genderMale"].ToString() == "1"?"鐢":"濂") };
+ ChatWebSocketMiddleware.CurFaceID =JsonConvert.SerializeObject(faceData);
+ ChatWebSocketMiddleware.allSockets.ToList().ForEach(s => s.Send(ChatWebSocketMiddleware.CurFaceID));
+ }
+
+ //}
+ }
+
+
+ }
+ catch (Exception e)
+ {
+ log.WriteLogFile(e.Message, "HTTPError");
+ }
+ }
+ //}
+ }
+
+ //private void SendHttpForLive(Mat frame, cw_face_res_t face)
+ //{
+ // if (faceDic.ContainsKey(face.trackId))
+ // {
+ // //Process[] proSc = Process.GetProcesses();
+ // //bool pcstart = false;
+ // //var oldFace = faceEntryTime.Where(i => i.Value.AddMinutes(1) < DateTime.Now).Select(i => i.Key).ToList();
+ // //foreach (var item in oldFace)
+ // //{
+ // // faceEntryTime.Remove(item);
+ // //}
+ // //for (int i = 0; i < proSc.Length; i++)
+ // //{
+ // // if (proSc[i].ProcessName.ToLower().Trim() == "pcscreensavers")
+ // // {
+ // // pcstart = true;
+ // // break;
+ // // }
+ // //}
+ // //if (pcstart)
+ // //{
+ // var faceRectWidth = 400;
+ // var faceRectHeight = 400;
+ // int x = 0;
+ // int y = 0;
+ // int width = 0;
+ // int height = 0;
+ // if ((int)face.faceRect.x > 20)
+ // {
+ // x = (int)face.faceRect.x - 20;
+ // //qMLog.WriteLogToFile("x:"+ ((int)face.Rect.X)+ " Width"+ ((int)face.Rect.Width)+ " frame"+ frame.Width,"111");
+ // // width = (x + (int)face.faceRect.width + 40) >= frame.Width ? (frame.Width - x) : (int)face.faceRect.width + 60;
+ // width = (x + faceRectWidth) >= frame.Width ? (frame.Width - x) : faceRectWidth + 20;
+ // //width += 10;
+ // }
+ // else
+ // {
+ // x = 0;
+ // //width = (int)face.faceRect.x + (int)face.faceRect.width + 40 >= frame.Width ? frame.Width : (int)face.faceRect.width + 40 + (int)face.faceRect.x;
+
+ // width = (int)face.faceRect.x + faceRectWidth >= frame.Width ? frame.Width : faceRectWidth + (int)face.faceRect.x;
+ // //width += x;
+ // }
+
+ // if ((int)face.faceRect.y > 60)
+ // {
+ // y = (int)face.faceRect.y - 60;
+
+ // //height = (y + (int)face.faceRect.height + 40) >= frame.Height ? (frame.Height - y) : (int)face.faceRect.height + 100;
+ // height = (y + faceRectHeight) >= frame.Height ? (frame.Height - y) : faceRectHeight + 60;
+
+ // }
+ // else
+ // {
+ // y = 0;
+ // //height = (int)face.faceRect.y + (int)face.faceRect.height + 40 >= frame.Height ? frame.Height : (int)face.faceRect.height + 40 + (int)face.faceRect.y;
+ // height = (int)face.faceRect.y + faceRectHeight >= frame.Height ? frame.Height : faceRectHeight + (int)face.faceRect.y;
+
+ // }
+ // string AddressIP = string.Empty;
+ // foreach (IPAddress _IPAddress in Dns.GetHostEntry(Dns.GetHostName()).AddressList)
+ // {
+ // if (_IPAddress.AddressFamily.ToString() == "InterNetwork")
+ // {
+ // AddressIP = _IPAddress.ToString();
+ // }
+ // }
+ // try
+ // {
+ // using (Mat newFrame = new Mat(frame, new System.Drawing.Rectangle(new System.Drawing.Point(x, y),
+ // new System.Drawing.Size(width, height))))
+ // {
+ // Emgu.CV.Util.VectorOfByte buff = new Emgu.CV.Util.VectorOfByte();
+ // CvInvoke.Imencode(".jpg", newFrame, buff);
+ // //CvInvoke.Imwrite("./Kiosk/" + Guid.NewGuid().ToString()+".jpg", newFrame);
+ // byte[] encodeBuff = new byte[buff.Size];
+ // Marshal.Copy(buff.StartAddress, encodeBuff, 0, buff.Size);
+
+ // string base64Str = Convert.ToBase64String(encodeBuff);
+ // //if (!faceEntryTime.ContainsKey(face.ID))
+ // //{
+ // // faceEntryTime.Add(face.ID, DateTime.Now);
+ // //var url = ConfigurationManager.AppSettings["KioskUrl"] + "/api/Face/UpLoadFace";
+ // //string data = "Face=" + base64Str + "&ip=" + AddressIP + "&Age=" + age + "&GenderMale=" + sex;
+ // //log.WriteLogFile(data, "111");
+ // //var _r = PostMothsForm(url, data);
+ // //log.WriteLogFile(_r, "111");
+ // //Dictionary dic = JsonConvert.DeserializeObject>(_r);
+ // //if (dic["code"].ToString() == "200")
+ // //{
+
+ // // Dictionary dicData = JsonConvert.DeserializeObject>(dic["data"].ToString());
+ // // //log.WriteLogFile((sex == 1 ? "鐢" : "濂") + " " + (dicData["genderMale"].ToString() == "1" ? "鐢" : "濂"), "sex");
+ // // var faceData = new { faceID = dicData["faceID"], isValid = dicData["isValid"], beautyScore = dicData["beautyScore"], faceImage = base64Str, genderMale = (sex == 1 ? "鐢" : "濂") };
+ // // //var faceData = new { faceID= dicData["faceID"], isValid= dicData["isValid"], beautyScore= dicData["beautyScore"],faceImage= base64Str, genderMale= (dicData["genderMale"].ToString() == "1"?"鐢":"濂") };
+ // // ChatWebSocketMiddleware.CurFaceID = JsonConvert.SerializeObject(faceData);
+ // // ChatWebSocketMiddleware.allSockets.ToList().ForEach(s => s.Send(ChatWebSocketMiddleware.CurFaceID));
+ // //}
+ // var faceData = new
+ // {
+ // faceID = "-1",
+ // faceImage = base64Str
+ // };
+ // ChatWebSocketMiddleware.allSocketsForTest.ToList().ForEach(s => s.Send(JsonConvert.SerializeObject(faceData)));
+ // //}
+ // }
+
+
+ // }
+ // catch (Exception e)
+ // {
+ // log.WriteLogFile(e.Message, "HTTPError");
+ // }
+ // }
+ // //}
+ //}
+
+ private void SendHttpForNavigation(Mat frame, cw_face_res_t face)
+ {
+ if (faceDic.ContainsKey(face.trackId))
+ {
+ var age = faceDic[face.trackId].age;
+ var sex = faceDic[face.trackId].sex;
+ Process[] proSc = Process.GetProcesses();
+ bool pcstart = false;
+ for (int i = 0; i < proSc.Length; i++)
+ {
+ if (proSc[i].ProcessName.ToLower().Trim() == "pcscreensavers")
+ {
+ pcstart = true;
+ break;
+ }
+ }
+ if (pcstart)
+ {
+ int x = 0;
+ int y = 0;
+ int width = 0;
+ int height = 0;
+ if ((int)face.faceRect.x > 20)
+ {
+ x = (int)face.faceRect.x - 20;
+ //qMLog.WriteLogToFile("x:"+ ((int)face.Rect.X)+ " Width"+ ((int)face.Rect.Width)+ " frame"+ frame.Width,"111");
+ width = (x + (int)face.faceRect.width + 40) >= frame.Width ? (frame.Width - x) : (int)face.faceRect.width + 60;
+ //width += 10;
+ }
+ else
+ {
+ x = 0;
+ width = (int)face.faceRect.x + (int)face.faceRect.width + 40 >= frame.Width ? frame.Width : (int)face.faceRect.width + 40 + (int)face.faceRect.x;
+ //width += x;
+ }
+
+ if ((int)face.faceRect.y > 60)
+ {
+ y = (int)face.faceRect.y - 60;
+
+ height = (y + (int)face.faceRect.height + 40) >= frame.Height ? (frame.Height - y) : (int)face.faceRect.height + 100;
+
+ }
+ else
+ {
+ y = 0;
+ height = (int)face.faceRect.y + (int)face.faceRect.height + 40 >= frame.Height ? frame.Height : (int)face.faceRect.height + 40 + (int)face.faceRect.y;
+
+ }
+ string AddressIP = string.Empty;
+ foreach (IPAddress _IPAddress in Dns.GetHostEntry(Dns.GetHostName()).AddressList)
+ {
+ if (_IPAddress.AddressFamily.ToString() == "InterNetwork")
+ {
+ AddressIP = _IPAddress.ToString();
+ }
+ }
+ try
+ {
+ using (Mat newFrame = new Mat(frame, new System.Drawing.Rectangle(new System.Drawing.Point(x, y),
+ new System.Drawing.Size(width, height))))
+ {
+ Emgu.CV.Util.VectorOfByte buff = new Emgu.CV.Util.VectorOfByte();
+ CvInvoke.Imencode(".jpg", newFrame, buff);
+ //CvInvoke.Imwrite("./rich/" + Guid.NewGuid().ToString() + ".jpg", newFrame);
+ byte[] encodeBuff = new byte[buff.Size];
+ Marshal.Copy(buff.StartAddress, encodeBuff, 0, buff.Size);
+
+ string base64Str = Convert.ToBase64String(encodeBuff);
+ //if (!faceEntryTime.ContainsKey(face.ID))
+ //{
+ // faceEntryTime.Add(face.ID, DateTime.Now);
+ var url = ConfigurationManager.AppSettings["KioskUrl"] + "/api/Face/UpLoadFace";
+ string data = "Face=" + base64Str + "&ip=" + AddressIP + "&method=relay&Age=" + age + "&GenderMale=" + sex;
+ var _r = PostMothsForm(url, data);
+ log.WriteLogFile("鎺ㄩ佸瘜骞垮憡", "22222");
+ log.WriteLogFile(ChatWebSocketMiddleware.faceSockets.Count.ToString(), "22222");
+ //Dictionary dic = JsonConvert.DeserializeObject>(_r);
+ ChatWebSocketMiddleware.faceSockets.ToList().ForEach(s => s.Send("richad"));
+
+ //}
+ }
+
+
+ }
+ catch (Exception e)
+ {
+ log.WriteLogFile(e.Message, "HTTPError");
+ }
+ }
+ }
+ }
+
+ private void AddFaceView(cwFaceAttr faceModel, DateTime dtBegin, bool isSubmit = false)
+ {
+
+
+ var url = ServiceUrl + "/api/Face/UpLoadFace";
+ try
+ {
+ FaceDataModel model = new FaceDataModel();
+ model.Age = faceModel.age.ToString();
+ model.BeginTime = dtBegin;
+ model.EndTime = DateTime.Now;
+ model.GenderMale = faceModel.sex == 0 ? "濂" : "鐢";
+ model.StopTime = Convert.ToInt32((DateTime.Now - dtBegin).TotalSeconds);
+ model.IP = AddressIP;
+ if (model.StopTime > 1)
+ {
+ listFaceView.Add(model);
+ if (listFaceView.Count >= 5)
+ {
+ var param = JsonConvert.SerializeObject(listFaceView);
+ var _r = PostMoths(url, param);
+ if (!string.IsNullOrEmpty(_r))
+ {
+ Dictionary dic = JsonConvert.DeserializeObject>(_r);
+ if (dic["code"].ToString() == "200")
+ {
+ listFaceView.Clear();
+ }
+ }
+ }
+
+ }
+
+ }
+ catch (Exception e)
+ {
+ //MessageBox.Show(url + e.Message);
+ }
+ }
+
+ public string PostMoths(string url, string param)
+ {
+ string strURL = url;
+ System.Net.HttpWebRequest request;
+ request = (System.Net.HttpWebRequest)WebRequest.Create(strURL);
+ request.Method = "POST";
+ request.ContentType = "application/json;charset=UTF-8";
+ string paraUrlCoded = param;
+ byte[] payload;
+ payload = System.Text.Encoding.UTF8.GetBytes(paraUrlCoded);
+ request.ContentLength = payload.Length;
+ Stream writer = request.GetRequestStream();
+ writer.Write(payload, 0, payload.Length);
+ writer.Close();
+ System.Net.HttpWebResponse response;
+ response = (System.Net.HttpWebResponse)request.GetResponse();
+ System.IO.Stream s;
+ s = response.GetResponseStream();
+ string StrDate = "";
+ string strValue = "";
+ StreamReader Reader = new StreamReader(s, Encoding.UTF8);
+ while ((StrDate = Reader.ReadLine()) != null)
+ {
+ strValue += StrDate + "\r\n";
+ }
+ return strValue;
+ }
+
+ public static string PostMothsForm(string url, string param)
+ {
+ string strURL = url;
+ System.Net.HttpWebRequest request;
+ request = (System.Net.HttpWebRequest)WebRequest.Create(strURL);
+ request.Method = "POST";
+ request.ContentType = "application/x-www-form-urlencoded;charset=UTF-8";
+ string paraUrlCoded = param;
+ byte[] payload;
+ payload = System.Text.Encoding.UTF8.GetBytes(paraUrlCoded);
+ request.ContentLength = payload.Length;
+ Stream writer = request.GetRequestStream();
+ writer.Write(payload, 0, payload.Length);
+ writer.Close();
+ System.Net.HttpWebResponse response;
+ response = (System.Net.HttpWebResponse)request.GetResponse();
+ System.IO.Stream s;
+ s = response.GetResponseStream();
+ string StrDate = "";
+ string strValue = "";
+ StreamReader Reader = new StreamReader(s, Encoding.UTF8);
+ while ((StrDate = Reader.ReadLine()) != null)
+ {
+ strValue += StrDate + "\r\n";
+ }
+ return strValue;
+ }
+
+ List FaceDetect(Mat mat)
+ {
+ try
+ {
+
+
+ // 缁欏浘鍍忕粨鏋勪綋璧嬪
+ SDK.cw_img_t srcImg = new SDK.cw_img_t();
+ srcImg.dataLen = mat.GetData().Length;
+ srcImg.width = mat.Width;
+ srcImg.height = mat.Height;
+ srcImg.format = SDK.cw_img_form_t.CW_IMAGE_BGR888;
+ srcImg.angle = SDK.cw_img_angle_t.CW_IMAGE_ANGLE_0;
+ srcImg.mirror = cw_img_mirror_t.CW_IMAGE_MIRROR_NONE;
+
+ //涓嬮潰杩欎袱鍙ワ紝澶歝opy涓娆℃槸蹇呴』鐨勶紝涓嶇劧鍦ㄦ湁鐨勭數鑴戜笂鏈夋姤opencv閿欒
+ if (m_btImgBuff == null || m_btImgBuff.Length < srcImg.dataLen)
+ {
+ m_btImgBuff = new byte[srcImg.dataLen];
+ if (m_gc.IsAllocated)
+ {
+ m_gc.Free();
+ }
+ m_gc = GCHandle.Alloc(m_btImgBuff, GCHandleType.Pinned);
+ }
+ Array.Copy(mat.GetData(), m_btImgBuff, srcImg.dataLen);
+ //srcImg.data = Marshal.UnsafeAddrOfPinnedArrayElement(m_btImgBuff, 0);
+ srcImg.data = Marshal.AllocHGlobal(m_btImgBuff.Length);
+ Marshal.Copy(m_btImgBuff, 0, srcImg.data, m_btImgBuff.Length);
+
+ int iSize = Marshal.SizeOf(typeof(cw_face_res_t));
+ if (IntPtr.Zero == m_buffResult)
+ {
+ m_buffResult = Marshal.AllocHGlobal(10 * iSize);
+ if (m_buffResult == IntPtr.Zero)
+ {
+ return null;
+ }
+ }
+
+ // 浜鸿劯妫娴
+ int iFaceNum = 0;
+ cw_errcode_t errCode = NativeCWFaceDetection.cwFaceDetection(m_pDet, ref srcImg, m_buffResult, 10, ref iFaceNum, (int)(DetectTrackOperationType.CW_OP_ALIGN | DetectTrackOperationType.CW_OP_DET | DetectTrackOperationType.CW_OP_QUALITY | DetectTrackOperationType.CW_OP_TRACK));
+ if (errCode != cw_errcode_t.CW_OK || iFaceNum < 1)
+ {
+ Marshal.FreeHGlobal(srcImg.data);
+ return null;
+ }
+
+ // 鍙栦汉鑴哥殑鏁版嵁
+ List vecRet = new List();
+ for (int i = 0; i < iFaceNum; i++)
+ {
+ cw_face_res_t faceRet = new cw_face_res_t();
+ faceRet = (cw_face_res_t)Marshal.PtrToStructure(m_buffResult + i * iSize, typeof(cw_face_res_t));
+
+ vecRet.Add(faceRet);
+ }
+ Marshal.FreeHGlobal(srcImg.data);
+ return vecRet;
+ }
+ catch (Exception e)
+ {
+ string error = e.Message;
+ return null;
+ }
+
+ }
+
+ [DllImport("gdi32")]
+ private static extern int DeleteObject(IntPtr o);
+
+ public static BitmapSource ToBitmapSource(Mat mat)
+ {
+ using (System.Drawing.Bitmap source = mat.ToImage().Bitmap)
+ {
+ IntPtr ptr = source.GetHbitmap();
+
+ BitmapSource bs = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
+ ptr,
+ IntPtr.Zero,
+ Int32Rect.Empty,
+ System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
+
+ DeleteObject(ptr);// 閲婃斁鍐呭瓨锛屽惁鍒欏唴瀛樻硠闇
+
+ return bs;
+ }
+ }
+
+
+ string GetFeatureFromPath(byte[] btImgData, byte[] pFeatueData)
+ {
+ // 缁欏浘鍍忕粨鏋勪綋璧嬪
+ SDK.cw_img_t srcImg = new SDK.cw_img_t();
+ srcImg.data = Marshal.UnsafeAddrOfPinnedArrayElement(btImgData, 0);
+ srcImg.dataLen = btImgData.Length;
+ srcImg.height = 0;
+ srcImg.width = 0;
+ srcImg.format = SDK.cw_img_form_t.CW_IMAGE_BINARY;
+ srcImg.angle = SDK.cw_img_angle_t.CW_IMAGE_ANGLE_0;
+ srcImg.mirror = cw_img_mirror_t.CW_IMAGE_MIRROR_NONE;
+
+ int iSize = Marshal.SizeOf(typeof(cw_face_res_t));
+ if (IntPtr.Zero == m_buffVerify)
+ {
+ m_buffVerify = Marshal.AllocHGlobal(2 * iSize);
+ if (IntPtr.Zero == m_buffVerify)
+ {
+ return null;
+ }
+ }
+
+ int iFaceNum = 0;
+ // 浜鸿劯妫娴嬶紝鑾峰彇瀵归綈浜鸿劯
+ cw_errcode_t errCode = NativeCWFaceDetection.cwFaceDetection(m_pDetVerify, ref srcImg, m_buffVerify, 2, ref iFaceNum,
+ (int)(DetectTrackOperationType.CW_OP_DET | DetectTrackOperationType.CW_OP_ALIGN));
+
+ if (errCode != cw_errcode_t.CW_OK)
+ {
+ return ("Face detect Error, Code: " + errCode.ToString());
+ }
+ if (iFaceNum < 1)
+ {
+ return "No Face Detected";
+ }
+
+ // 鍙栫涓寮犱汉鑴哥殑鏁版嵁
+ cw_face_res_t faceRect = new cw_face_res_t();
+ faceRect = (cw_face_res_t)Marshal.PtrToStructure(m_buffVerify, typeof(cw_face_res_t));
+ errCode = NativeCWFaceRecognition.cwGetFaceFeature(m_pRecog, ref faceRect.faceAligned, pFeatueData);
+ if (cw_errcode_t.CW_OK != errCode)
+ {
+ return ("Get Feature Error: " + errCode.ToString());
+ }
+
+ return null;
+ }
+
+ private BitmapImage GetBitmapImage(string path)
+ {
+ BitmapImage bitmap = new BitmapImage();
+ bitmap.BeginInit();
+
+ bitmap.CacheOption = BitmapCacheOption.OnLoad;
+ bitmap.StreamSource = new MemoryStream(File.ReadAllBytes(path));
+ bitmap.EndInit();
+ bitmap.Freeze();
+ return bitmap;
+ }
+
+
+ /****************************************************浜鸿劯灞炴************************************************************/
+ private SDK.cw_errcode_t CreateAttributeHandle()
+ {
+ //鍒涘缓灞炴у彞鏌
+ SDK.cw_errcode_t errCode = cw_errcode_t.CW_OK;
+ m_pRaceAttri = NativeCWFaceAttribute.cwCreateAttributeHandle(out errCode, "../../CWModels/attribute/faceRace/cw_race_config.xml", m_sLicence);
+ if (IntPtr.Zero == m_pRaceAttri || errCode != cw_errcode_t.CW_OK)
+ {
+ MessageBox.Show("浜虹鍙ユ焺鍒涘缓澶辫触锛岄敊璇爜锛" + errCode.ToString());
+ return errCode;
+ }
+
+ m_pAgeAttri = NativeCWFaceAttribute.cwCreateAttributeHandle(out errCode, "../../CWModels/attribute/ageGroup/CWR_Config3.0.xml", m_sLicence);
+ if (IntPtr.Zero == m_pAgeAttri || errCode != cw_errcode_t.CW_OK)
+ {
+ MessageBox.Show("骞撮緞娈靛彞鏌勫垱寤哄け璐ワ紝閿欒鐮侊細" + errCode.ToString());
+ return errCode;
+ }
+
+ m_pGenderAttri = NativeCWFaceAttribute.cwCreateAttributeHandle(out errCode, "../../CWModels/attribute/faceGender/cw_gender_config.xml", m_sLicence);
+ if (IntPtr.Zero == m_pGenderAttri || errCode != cw_errcode_t.CW_OK)
+ {
+ MessageBox.Show("鎬у埆鍙ユ焺鍒涘缓澶辫触锛岄敊璇爜锛" + errCode.ToString());
+ return errCode;
+ }
+
+ return errCode;
+ }
+
+ private void DestroyAttributeHandle()
+ {
+ if (IntPtr.Zero != m_pRaceAttri)
+ {
+ NativeCWFaceAttribute.cwReleaseAttributeHandle(m_pRaceAttri);
+ m_pRaceAttri = IntPtr.Zero;
+ }
+
+ if (IntPtr.Zero != m_pAgeAttri)
+ {
+ NativeCWFaceAttribute.cwReleaseAttributeHandle(m_pAgeAttri);
+ m_pAgeAttri = IntPtr.Zero;
+ }
+
+ if (IntPtr.Zero != m_pGenderAttri)
+ {
+ NativeCWFaceAttribute.cwReleaseAttributeHandle(m_pGenderAttri);
+ m_pGenderAttri = IntPtr.Zero;
+ }
+ }
+
+ /*****************************************************绾㈠娲讳綋************************************************************/
+ private SDK.cw_nirliveness_err_t CreateNirLivenessHandle()
+ {
+ //鍒涘缓绾㈠娲讳綋鍙ユ焺
+ SDK.cw_nirliveness_err_t errCode = cw_nirliveness_err_t.CW_NIRLIV_OK;
+ string pNirModelPath = "../../CWModels/nirLiveness_model_20181102_pc.bin";
+ string pRecogModelPath = "../../CWModels/hd171019.bin";
+ string pPairFilePath = "../../CWModels/matrix_para640x480.xml";
+ float fskinThread = 0.35f;
+ m_pNirLive = CWFaceNisLiveness.cwCreateNirLivenessHandle(out errCode, pNirModelPath, pRecogModelPath, pPairFilePath, "./log", fskinThread, m_sLicence);
+ if (IntPtr.Zero == m_pNirLive || errCode != cw_nirliveness_err_t.CW_NIRLIV_OK)
+ {
+ MessageBox.Show("绾㈠娲讳綋鍙ユ焺鍒涘缓澶辫触锛岄敊璇爜锛" + errCode.ToString());
+ return errCode;
+ }
+ return errCode;
+ }
+
+ }
+}
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/Properties/AssemblyInfo.cs b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..015cc36
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/Properties/AssemblyInfo.cs
@@ -0,0 +1,55 @@
+锘縰sing System.Reflection;
+using System.Resources;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Windows;
+
+// 鏈夊叧绋嬪簭闆嗙殑甯歌淇℃伅閫氳繃浠ヤ笅
+// 鐗规ч泦鎺у埗銆傛洿鏀硅繖浜涚壒鎬у煎彲淇敼
+// 涓庣▼搴忛泦鍏宠仈鐨勪俊鎭
+[assembly: AssemblyTitle("DemoUI")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("DemoUI")]
+[assembly: AssemblyCopyright("Copyright 漏 2016")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// 灏 ComVisible 璁剧疆涓 false 浣挎绋嬪簭闆嗕腑鐨勭被鍨
+// 瀵 COM 缁勪欢涓嶅彲瑙併傚鏋滈渶瑕佷粠 COM 璁块棶姝ょ▼搴忛泦涓殑绫诲瀷锛
+// 鍒欏皢璇ョ被鍨嬩笂鐨 ComVisible 鐗规ц缃负 true銆
+[assembly: ComVisible(false)]
+
+//鑻ヨ寮濮嬬敓鎴愬彲鏈湴鍖栫殑搴旂敤绋嬪簭锛岃鍦
+// 涓殑 .csproj 鏂囦欢涓
+//璁剧疆 CultureYouAreCodingWith銆備緥濡傦紝濡傛灉鎮ㄥ湪婧愭枃浠朵腑
+//浣跨敤鐨勬槸缇庡浗鑻辫锛岃灏 璁剧疆涓 en-US銆傜劧鍚庡彇娑
+//瀵逛互涓 NeutralResourceLanguage 鐗规х殑娉ㄩ噴銆傛洿鏂
+//浠ヤ笅琛屼腑鐨勨渆n-US鈥濅互鍖归厤椤圭洰鏂囦欢涓殑 UICulture 璁剧疆銆
+
+//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
+
+
+[assembly: ThemeInfo(
+ ResourceDictionaryLocation.None, //涓婚鐗瑰畾璧勬簮璇嶅吀鎵澶勪綅缃
+ //(鍦ㄩ〉闈㈡垨搴旂敤绋嬪簭璧勬簮璇嶅吀涓
+ // 鏈壘鍒版煇涓祫婧愮殑鎯呭喌涓嬩娇鐢)
+ ResourceDictionaryLocation.SourceAssembly //甯歌璧勬簮璇嶅吀鎵澶勪綅缃
+ //(鍦ㄩ〉闈€佸簲鐢ㄧ▼搴忔垨浠讳綍涓婚鐗瑰畾璧勬簮璇嶅吀涓
+ // 鏈壘鍒版煇涓祫婧愮殑鎯呭喌涓嬩娇鐢)
+)]
+
+
+// 绋嬪簭闆嗙殑鐗堟湰淇℃伅鐢变笅闈㈠洓涓肩粍鎴:
+//
+// 涓荤増鏈
+// 娆$増鏈
+// 鐢熸垚鍙
+// 淇鍙
+//
+// 鍙互鎸囧畾鎵鏈夎繖浜涘硷紝涔熷彲浠ヤ娇鐢ㄢ滅敓鎴愬彿鈥濆拰鈥滀慨璁㈠彿鈥濈殑榛樿鍊硷紝
+// 鏂规硶鏄寜濡備笅鎵绀轰娇鐢ㄢ*鈥:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/Properties/Resources.Designer.cs b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/Properties/Resources.Designer.cs
new file mode 100644
index 0000000..c626272
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/Properties/Resources.Designer.cs
@@ -0,0 +1,63 @@
+锘//------------------------------------------------------------------------------
+//
+// 姝や唬鐮佺敱宸ュ叿鐢熸垚銆
+// 杩愯鏃剁増鏈:4.0.30319.42000
+//
+// 瀵规鏂囦欢鐨勬洿鏀瑰彲鑳戒細瀵艰嚧涓嶆纭殑琛屼负锛屽苟涓斿鏋
+// 閲嶆柊鐢熸垚浠g爜锛岃繖浜涙洿鏀瑰皢浼氫涪澶便
+//
+//------------------------------------------------------------------------------
+
+namespace DemoUI.Properties {
+ using System;
+
+
+ ///
+ /// 涓涓己绫诲瀷鐨勮祫婧愮被锛岀敤浜庢煡鎵炬湰鍦板寲鐨勫瓧绗︿覆绛夈
+ ///
+ // 姝ょ被鏄敱 StronglyTypedResourceBuilder
+ // 绫婚氳繃绫讳技浜 ResGen 鎴 Visual Studio 鐨勫伐鍏疯嚜鍔ㄧ敓鎴愮殑銆
+ // 鑻ヨ娣诲姞鎴栫Щ闄ゆ垚鍛橈紝璇风紪杈 .ResX 鏂囦欢锛岀劧鍚庨噸鏂拌繍琛 ResGen
+ // (浠 /str 浣滀负鍛戒护閫夐」)锛屾垨閲嶆柊鐢熸垚 VS 椤圭洰銆
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources() {
+ }
+
+ ///
+ /// 杩斿洖姝ょ被浣跨敤鐨勭紦瀛樼殑 ResourceManager 瀹炰緥銆
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DemoUI.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// 閲嶅啓褰撳墠绾跨▼鐨 CurrentUICulture 灞炴
+ /// 閲嶅啓褰撳墠绾跨▼鐨 CurrentUICulture 灞炴с
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+ }
+}
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/Properties/Resources.resx b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/Properties/Resources.resx
new file mode 100644
index 0000000..af7dbeb
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/Properties/Resources.resx
@@ -0,0 +1,117 @@
+锘
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/Properties/Settings.Designer.cs b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/Properties/Settings.Designer.cs
new file mode 100644
index 0000000..286a387
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/Properties/Settings.Designer.cs
@@ -0,0 +1,26 @@
+锘//------------------------------------------------------------------------------
+//
+// 姝や唬鐮佺敱宸ュ叿鐢熸垚銆
+// 杩愯鏃剁増鏈:4.0.30319.42000
+//
+// 瀵规鏂囦欢鐨勬洿鏀瑰彲鑳戒細瀵艰嚧涓嶆纭殑琛屼负锛屽苟涓斿鏋
+// 閲嶆柊鐢熸垚浠g爜锛岃繖浜涙洿鏀瑰皢浼氫涪澶便
+//
+//------------------------------------------------------------------------------
+
+namespace DemoUI.Properties {
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.9.0.0")]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
+
+ private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+ public static Settings Default {
+ get {
+ return defaultInstance;
+ }
+ }
+ }
+}
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/Properties/Settings.settings b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/Properties/Settings.settings
new file mode 100644
index 0000000..033d7a5
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/Properties/Settings.settings
@@ -0,0 +1,7 @@
+锘
+
+
+
+
+
+
\ No newline at end of file
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/SDK/FaceApi.cs b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/SDK/FaceApi.cs
new file mode 100644
index 0000000..0a7be0a
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/SDK/FaceApi.cs
@@ -0,0 +1,13 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace DemoUI.SDK
+{
+ class FaceApi
+ {
+ private const string CloudWalkSDKDll = "FaceApi.dll";
+ }
+}
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/SDK/NativeCWFaceAttLiveness.cs b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/SDK/NativeCWFaceAttLiveness.cs
new file mode 100644
index 0000000..b788ae8
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/SDK/NativeCWFaceAttLiveness.cs
@@ -0,0 +1,54 @@
+锘縰sing System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Text;
+using System;
+
+namespace DemoUI.SDK
+{
+ ///
+ /// 鍙鍏夊崟鐩椿浣撴帴鍙
+ ///
+ public class CWFaceAttLiveness
+ {
+ private const string CloudWalkSDKDll = "CWFaceSDK.dll";
+
+ ///
+ /// 鍒涘缓鍙鍏夊崟鐩椿浣撳彞鏌
+ ///
+ /// 杈撳嚭閿欒鐮
+ /// 鍗曠洰娲讳綋妫娴嬫ā寮
+ /// 鍗曠洰娲讳綋妫娴嬪櫒妯″瀷鏂囦欢澶硅矾寰
+ /// 鎺堟潈鐮
+ /// 濡傛灉鍒涘缓鎴愬姛锛岃繑鍥炲崟鐩椿浣撳彞鏌勶紝鍚﹀垯杩斿洖绌
+ [DllImport(CloudWalkSDKDll, EntryPoint = "cwCreateAttLivenessHandle", CallingConvention = CallingConvention.Cdecl)]
+ public static extern IntPtr cwCreateAttLivenessHandle(out cw_attliveness_err_t errCode, cw_attliv_mode_t attDetType, string pModelPath, string pLicence);
+
+
+ ///
+ /// 閲婃斁鍗曠洰娲讳綋妫娴嬪彞鏌
+ ///
+ /// 鍗曠洰娲讳綋鍙ユ焺
+ [DllImport(CloudWalkSDKDll, EntryPoint = "cwReleaseAttLivenessHandle", CallingConvention = CallingConvention.Cdecl)]
+ public static extern void cwReleaseAttLivenessHandle(IntPtr pHandle);
+
+
+ ///
+ /// 鍙鍏夊崟鐩椿浣撴娴嬫帴鍙
+ ///
+ /// 鍗曠洰娲讳綋鍙ユ焺
+ /// 杈撳叆鐨勫浘鐗囧強鍏抽敭鐐圭瓑淇℃伅
+ /// 鏀诲嚮绫诲瀷
+ ///
+ [DllImport(CloudWalkSDKDll, EntryPoint = "cwFaceAttLivenessDet", CallingConvention = CallingConvention.Cdecl)]
+ public static extern cw_attliveness_err_t cwFaceAttLivenessDet(IntPtr pHandle, ref cw_att_liv_detinfo_t pAttDetInfo, out cw_attliv_det_rst_t pAttackType);
+
+
+ ///
+ /// 閲嶇疆娲讳綋妫娴嬪櫒鐘舵
+ ///
+ /// 鍗曠洰娲讳綋鍙ユ焺
+ ///
+ [DllImport(CloudWalkSDKDll, EntryPoint = "cwFaceAttLivenessReset", CallingConvention = CallingConvention.Cdecl)]
+ public static extern cw_attliveness_err_t cwFaceAttLivenessReset(IntPtr pHandle);
+ }
+}
\ No newline at end of file
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/SDK/NativeCWFaceAttribute.cs b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/SDK/NativeCWFaceAttribute.cs
new file mode 100644
index 0000000..94a3f11
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/SDK/NativeCWFaceAttribute.cs
@@ -0,0 +1,67 @@
+锘縰sing System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Text;
+using System;
+
+namespace DemoUI.SDK
+{
+ ///
+ /// 浜鸿劯妫娴
+ ///
+ public class NativeCWFaceAttribute
+ {
+ private const string CloudWalkSDKDll = "CWFaceSDK.dll";
+
+ ///
+ /// 鍒涘缓灞炴у彞鏌
+ ///
+ /// 妯″瀷鍙傛暟閰嶇疆鏂囦欢
+ /// 鎺堟潈鐮
+ /// 濡傛灉鍒涘缓鎴愬姛锛岃繑鍥濧ttribute鍙ユ焺锛屽惁鍒欒繑鍥炵┖
+ [DllImport(CloudWalkSDKDll, EntryPoint = "cwCreateAttributeHandle", CallingConvention = CallingConvention.Cdecl)]
+ public static extern IntPtr cwCreateAttributeHandle(out cw_errcode_t errCode, string pConfigFile, string pLicence);
+
+
+ ///
+ /// 閲婃斁灞炴у彞鏌
+ ///
+ ///
+ [DllImport(CloudWalkSDKDll, EntryPoint = "cwReleaseAttributeHandle", CallingConvention = CallingConvention.Cdecl)]
+ public static extern void cwReleaseAttributeHandle(IntPtr pAttributeHandle);
+
+
+ ///
+ /// 骞撮緞娈典及璁
+ ///
+ ///
+ /// 瀵归綈浜鸿劯
+ /// 骞撮緞娈典及璁″硷紝0 灏忓 1 鎴愬勾浜 2 鑰佷汉
+ /// 缃俊鍒嗘暟 0-1涔嬮棿鐨勪竴涓硷紝缃俊搴﹁秺楂
+ ///
+ [DllImport(CloudWalkSDKDll, EntryPoint = "cwGetAgeEval", CallingConvention = CallingConvention.Cdecl)]
+ public static extern cw_errcode_t cwGetAgeEval(IntPtr pAttributeHandle, ref cw_aligned_face_t alignedFace, out int pAge);
+
+
+ ///
+ /// 鎬у埆浼拌
+ ///
+ ///
+ /// 瀵归綈浜鸿劯
+ /// 鎬у埆浼拌鍊硷紝0 濂虫, 1 鐢锋
+ ///
+ [DllImport(CloudWalkSDKDll, EntryPoint = "cwGetGenderEval", CallingConvention = CallingConvention.Cdecl)]
+ public static extern cw_errcode_t cwGetGenderEval(IntPtr pAttributeHandle, ref cw_aligned_face_t alignedFace, out int pGender, out float confidence);
+
+
+ ///
+ /// 浜虹浼拌
+ ///
+ ///
+ /// 瀵归綈浜鸿劯
+ /// 浜虹浼拌鍊硷紝0 榛戜汉 1 鐧戒汉 2 榛勪汉
+ ///
+ [DllImport(CloudWalkSDKDll, EntryPoint = "cwGetRaceEval", CallingConvention = CallingConvention.Cdecl)]
+ public static extern cw_errcode_t cwGetRaceEval(IntPtr pAttributeHandle, ref cw_aligned_face_t alignedFace, out int pRace, out float confidence);
+
+ }
+}
\ No newline at end of file
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/SDK/NativeCWFaceConfig.cs b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/SDK/NativeCWFaceConfig.cs
new file mode 100644
index 0000000..f32904d
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/SDK/NativeCWFaceConfig.cs
@@ -0,0 +1,360 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace DemoUI.SDK
+{
+ ///
+ /// 妫娴嬪姛鑳藉紑鍏抽夐」
+ ///
+ public enum DetectTrackOperationType
+ {
+ ///
+ /// 杩涜浜鸿劯妫娴嬶紝骞惰繑鍥炰汉鑴哥煩褰綅缃紝榛樿寮鍚
+ ///
+ CW_OP_DET = 0,
+ ///
+ /// 杩涜浜鸿劯璺熻釜锛屽苟杩斿洖浜鸿劯璺熻釜鐨処D
+ ///
+ CW_OP_TRACK = 2,
+ ///
+ /// 杩涜浜鸿劯鍏抽敭鐐规娴嬪紑鍏
+ ///
+ CW_OP_KEYPT = 4,
+ ///
+ /// 杩涜浜鸿劯鍥惧儚瀵归綈锛屽苟杩斿洖瀵归綈鍚庣殑浜鸿劯鍥惧儚锛岀敤鏉ユ彁鍙栫壒寰
+ ///
+ CW_OP_ALIGN = 8,
+ ///
+ /// 浜鸿劯璐ㄩ噺璇勪及寮鍏筹紙璐ㄩ噺鍒嗗瓙椤瑰紑鍏冲湪閰嶇疆鏂囦欢涓厤缃級
+ ///
+ CW_OP_QUALITY = 16,
+ ///
+ /// 锛堟墍鏈夊紑鍏崇患鍚堬級鎬诲紑鍏
+ ///
+ CW_OP_ALL = 30,
+ };
+
+ ///
+ /// 閫氱敤閿欒鐮
+ ///
+ public enum cw_errcode_t
+ {
+ CW_OK = 0, // 鎴愬姛 or 鍚堟硶
+
+ CW_UNKNOWN_ERR = 20000, // 鏈煡閿欒
+ CW_DETECT_INIT_ERR, // 鍒濆鍖栦汉鑴告娴嬪櫒澶辫触:濡傚姞杞芥ā鍨嬪け璐ョ瓑
+ CW_KEYPT_INIT_ERR, // 鍒濆鍖栧叧閿偣妫娴嬪櫒澶辫触锛氬鍔犺浇妯″瀷澶辫触绛
+ CW_QUALITY_INIT_ERR, // 鍒濆鍖栬窡韪櫒澶辫触锛氬鍔犺浇妯″瀷澶辫触绛
+
+ CW_DET_ERR, // 妫娴嬪け璐
+ CW_TRACK_ERR, // 璺熻釜澶辫触
+ CW_KEYPT_ERR, // 鎻愬彇鍏抽敭鐐瑰け璐
+ CW_ALIGN_ERR, // 瀵归綈浜鸿劯澶辫触
+ CW_QUALITY_ERR, // 璐ㄩ噺璇勪及澶辫触
+
+ CW_EMPTY_FRAME_ERR, // 绌哄浘鍍
+ CW_UNSUPPORT_FORMAT_ERR, // 鍥惧儚鏍煎紡涓嶆敮鎸
+ CW_ROI_ERR, // ROI璁剧疆澶辫触
+ CW_UNINITIALIZED_ERR, // 灏氭湭鍒濆鍖
+ CW_MINMAX_ERR, // 鏈灏忔渶澶т汉鑴歌缃け璐
+ CW_OUTOF_RANGE_ERR, // 鏁版嵁鑼冨洿閿欒
+ CW_UNAUTHORIZED_ERR, // 鏈巿鏉
+ CW_METHOD_UNAVAILABLE, // 鏂规硶鏃犳晥
+ CW_PARAM_INVALID, // 鍙傛暟鏃犳晥
+ CW_BUFFER_EMPTY, // 缂撳啿鍖虹┖
+
+ CW_FILE_UNAVAILABLE, // 鏂囦欢涓嶅瓨鍦細濡傚姞杞界殑妯″瀷涓嶅瓨鍦ㄧ瓑.
+ CW_DEVICE_UNAVAILABLE, // 璁惧涓嶅瓨鍦
+ CW_DEVICE_ID_UNAVAILABLE, // 璁惧id涓嶅瓨鍦
+ CW_EXCEEDMAXHANDLE_ERR, // 瓒呰繃鎺堟潈鏈澶у彞鏌勬暟
+
+ CW_RECOG_FEATURE_MODEL_ERR, // 鍔犺浇鐗瑰緛璇嗗埆妯″瀷澶辫触
+ CW_RECOG_ALIGNEDFACE_ERR, // 瀵归綈鍥剧墖鏁版嵁閿欒
+ CW_RECOG_MALLOCMEMORY_ERR, // 棰勫垎閰嶇壒寰佺┖闂翠笉瓒
+
+ CW_RECOG_FEATUREDATA_ERR, // 鐗瑰緛鏁版嵁閿欒
+ CW_RECOG_EXCEEDMAXFEASPEED, // 瓒呰繃鎺堟潈鏈澶ф彁鐗瑰緛閫熷害
+ CW_RECOG_EXCEEDMAXCOMSPEED, // 瓒呰繃鎺堟潈鏈澶ф瘮瀵归熷害
+ CW_RECOG_GROUPSIZE_ERR, // 鐗瑰緛姣斿鐗瑰緛鏁癗瓒呰繃鏈澶ф巿鏉冩暟
+ CW_RECOG_CONVERT_ERR, // 鐗瑰緛杞崲澶辫触
+ CW_RECOG_NOFACEDET, // 鏈娴嬪埌浜鸿劯
+
+ CW_LICENCE_JSON_CREATE_ERR, // Json鎿嶄綔澶辫触
+ CW_LICENCE_DECRYPT_ERR, // 鍔犲瘑澶辫触
+ CW_LICENCE_HTTP_ERROR, // HTTP澶辫触
+ CW_LICENCE_MALLOCMEMORY_ERR, // 鎺堟潈鍐呭瓨鍒嗛厤涓嶈冻
+ CW_LICENCE_KEY_DEVICE_ERR, // 鑾峰彇璁惧鏂囦欢閿欒
+ CW_LICENCE_KEY_LICENSE_ERR, // 鑾峰彇鎺堟潈鏂囦欢閿欒
+ CW_LICENCE_KEY_INSTALL_ERR, // 瀹夎鎺堟潈鏂囦欢閿欒
+
+ CW_ATTRI_AGEGENDER_MODEL_ERR, //鍔犺浇骞撮緞鎬у埆妯″瀷澶辫触
+ CW_ATTRI_EVAL_AGE_ERR, //骞撮緞璇嗗埆澶辫触
+ CW_ATTRI_EVAL_GENDER_ERR, //鎬у埆璇嗗埆澶辫触
+ CW_ATTRI_EVAL_RACE_ERR, //绉嶆棌璇嗗埆澶辫触
+ }
+
+ ///
+ /// 璐ㄩ噺鍒嗘娴嬮敊璇爜
+ ///
+ public enum cw_quality_errcode_t
+ {
+ CW_QUALITY_OK = 0, // 璐ㄩ噺鍒嗘暟鎹湁鏁
+ CW_QUALITY_NO_DATA = 20150, // 璐ㄩ噺鍒嗘暟鎹棤鏁堬紝鍘熷洜锛氬皻鏈娴
+ CW_QUALITY_ERROR_UNKNOWN, // 鏈煡閿欒
+ }
+
+ ///
+ /// 鎺ュ彛鍔熻兘鍙傛暟
+ ///
+ [StructLayoutAttribute(LayoutKind.Sequential)]
+ public struct cw_det_param_t
+ {
+ public int roiX; // roi, 榛樿鏁村抚鍥惧儚0, 0, 0, 0 鑻ヨ缃负寮傚父鍊兼娴嬮樁娈靛皢鎭㈠榛樿
+ public int roiY;
+ public int roiWidth;
+ public int roiHeight;
+
+ public int minSize; // 妫娴嬩汉鑴稿昂瀵歌寖鍥达細 pc绔粯璁48,600];绉诲姩绔粯璁100,400]
+ public int maxSize;
+
+ public string pConfigFile; // 鍐呴儴鍙傛暟閰嶇疆鏂囦欢璺緞锛屾鍙傛暟鍙兘璁剧疆(set);浠庡彞鏌勫唴閮ㄨ幏鍙栧嚭鏉ョ殑涓寰嬫棤鏁-------
+ }
+
+ ///
+ /// 鍥惧儚鏃嬭浆瑙掑害锛堥嗘椂閽堬級
+ ///
+ public enum cw_img_angle_t
+ {
+ CW_IMAGE_ANGLE_0 = 0,
+ CW_IMAGE_ANGLE_90,
+ CW_IMAGE_ANGLE_180,
+ CW_IMAGE_ANGLE_270
+ }
+
+ ///
+ /// 鍥惧儚闀滃儚
+ ///
+ public enum cw_img_mirror_t
+ {
+ CW_IMAGE_MIRROR_NONE = 0, // 涓嶉暅鍍
+ CW_IMAGE_MIRROR_HOR, // 姘村钩闀滃儚
+ CW_IMAGE_MIRROR_VER, // 鍨傜洿闀滃儚
+ CW_IMAGE_MIRROR_HV // 鍨傜洿鍜屾按骞抽暅鍍
+ }
+
+ ///
+ /// 鍥惧儚鏍煎紡
+ ///
+ public enum cw_img_form_t
+ {
+ CW_IMAGE_GRAY8 = 0,
+ CW_IMAGE_BGR888,
+ CW_IMAGE_BGRA8888,
+ CW_IMAGE_RGB888,
+ CW_IMAGE_RGBA8888,
+ CW_IMAGE_YUV420P,
+ CW_IMAGE_YV12,
+ CW_IMAGE_NV12,
+ CW_IMAGE_NV21,
+ CW_IMAGE_BINARY,
+ }
+
+ /***************
+ * 鍏抽敭鐐逛俊鎭
+ */
+ public struct cw_point
+ {
+ public float keypoint_x;
+ public float keypoint_y;
+ }
+
+ [StructLayoutAttribute(LayoutKind.Sequential)]
+ public struct cw_keypt
+ {
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 68)]
+ public cw_point[] points; // 鍏抽敭鐐
+ public int nkeypt; // 鍏抽敭鐐逛釜鏁
+ public float keyptScore; // 鍏抽敭鐐瑰緱鍒,鎺ㄨ崘闃堝间负0.7
+ }
+
+ ///
+ /// 鍥惧儚
+ ///
+ public struct cw_img_t
+ {
+ public Int64 frameId; // 甯у彿
+ public IntPtr data; // 鍥惧儚鏁版嵁锛堝繀椤婚鍒嗛厤瓒冲鐨勭┖闂达級
+ public int dataLen; // 鏁版嵁闀垮害锛孋W_IMAGE_BINARY鏍煎紡蹇呴』璁剧疆锛屽叾浠栨牸寮忓彲涓嶈
+ public int width; // 瀹斤紝CW_IMAGE_BINARY鏍煎紡鍙笉璁撅紝鍏朵粬鏍煎紡蹇呴』璁剧疆
+ public int height; // 楂橈紝CW_IMAGE_BINARY鏍煎紡鍙笉璁撅紝鍏朵粬鏍煎紡蹇呴』璁剧疆
+ public cw_img_form_t format; // 鍥惧儚鏍煎紡
+ public cw_img_angle_t angle; // 鏃嬭浆瑙掑害
+ public cw_img_mirror_t mirror; // 闀滃儚
+ }
+
+ ///
+ /// 浜鸿劯妗
+ ///
+ public struct cw_facepos_rect_t
+ {
+ public int x;
+ public int y;
+ public int width;
+ public int height;
+ }
+
+ ///
+ /// 瀵归綈浜鸿劯
+ ///
+ public struct cw_aligned_face_t
+ {
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 128 * 128)]
+ public byte[] data; //鍥惧儚鏁版嵁,鍥哄畾澶у皬128 * 128
+ public int width; //瀹
+ public int height; //楂
+ public int nChannels; //鍥惧儚閫氶亾
+ }
+
+ ///
+ /// 浜鸿劯璐ㄩ噺鍒
+ ///
+ public struct cw_quality_t
+ {
+ public cw_quality_errcode_t errcode; // 璐ㄩ噺鍒嗘瀽閿欒鐮
+
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
+ public float[] scores;
+ /* 璐ㄩ噺鍒嗗垎鏁伴」锛屽叿浣撳惈涔夛紙鏍规嵁鏁版嵁涓嬫爣椤哄簭锛:
+ * 0 - 浜鸿劯璐ㄩ噺鎬诲垎锛0.72
+ * 1 - 娓呮櫚搴︼紝瓒婂ぇ琛ㄧず瓒婃竻鏅帮紝鎺ㄨ崘鑼冨洿0.65-1.0(鍦ㄥ惎鐢ㄧ16涓」mog鍒嗘暟鐨勬诲垎鏃讹紝姝ゅ垎鏁颁负甯告暟1.0锛岃蹇界暐)
+ * 2 - 浜害锛岃秺澶ц〃绀鸿秺浜紝鎺ㄨ崘鑼冨洿0.2-0.8
+ * 3 - 浜鸿劯瑙掑害锛屽乏杞负姝o紝鍙宠浆涓鸿礋
+ * 4 - 浜鸿劯瑙掑害锛屾姮澶翠负姝o紝浣庡ご涓鸿礋
+ * 5 - 浜鸿劯瑙掑害锛岄『鏃堕拡涓烘锛岄嗘椂閽堜负璐
+ * 6 - 宸﹀彸杞▼搴︼紝瓒婂ぇ琛ㄧず瑙掑害瓒婃锛屾帹鑽愯寖鍥0.5-1.0
+ * 7 - 鎶綆澶寸▼搴︼紝瓒婂ぇ琛ㄧず瑙掑害瓒婃,鎺ㄨ崘鑼冨洿0.5-1.0
+ * 8 - 鑲よ壊鎺ヨ繎鐪熶汉鑲よ壊绋嬪害锛岃秺澶ц〃绀鸿秺鐪熷疄锛屾帹鑽愯寖鍥0.5-1.0
+ * 9 - 寮犲槾鍒嗘暟锛 瓒婂ぇ琛ㄧず瓒婂彲鑳藉紶鍢达紝鎺ㄨ崘鑼冨洿0.0-0.5
+ * 10 - 宸︾溂鐫佺溂鍒嗘暟锛 瓒婂ぇ琛ㄧず宸︾溂瓒婂彲鑳芥槸鐫佺溂锛屾帹鑽愯寖鍥0.5-1.0
+ * 11 - 鍙崇溂鐫佺溂鍒嗘暟锛 瓒婂ぇ琛ㄧず鍙崇溂瓒婂彲鑳芥槸鐫佺溂锛屾帹鑽愯寖鍥0.5-1.0
+ * 12 - 鎴撮粦妗嗙溂闀滅疆淇″害锛岃秺澶ц〃绀烘埓榛戞鐪奸暅鐨勫彲鑳芥ц秺澶э紝鎺ㄨ崘鑼冨洿0.0-0.5
+ * 13 - 鎴村ⅷ闀滅殑缃俊鍒嗭紝瓒婂ぇ琛ㄧず鎴村ⅷ闀滅殑鍙兘鎬ц秺澶э紝鎺ㄨ崘鑼冨洿0.0-0.5
+ * 14 - 宸︾溂鐪肩潧琚伄鎸$殑缃俊搴︼紝瓒婂ぇ琛ㄧず鐪奸暅瓒婂彲鑳借閬尅锛岀洰鍓嶅彧鍦ㄧ潄鐪煎垎灏忎簬0.5鏃舵湁鎰忎箟锛屾帹鑽愯寖鍥0.0-0.5
+ * 15 - 鍙崇溂鐪肩潧琚伄鎸$殑缃俊搴︼紝瓒婂ぇ琛ㄧず鐪奸暅瓒婂彲鑳借閬尅锛岀洰鍓嶅彧鍦ㄧ潄鐪煎垎灏忎簬0.5鏃舵湁鎰忎箟锛屾帹鑽愯寖鍥0.0-0.5
+ * 16 - mog娓呮櫚搴︼紝杩斿洖0.0~1.0鐨勫垎鏁帮紝瓒婂ぇ瓒婃竻鏅帮紝闃堝煎缓璁0.100001
+ * 17 - 鍙g僵鍒嗭紝0.0~1.0锛岃秺澶ц〃绀鸿秺涓嶅彲鑳藉甫鍙g僵锛屽缓璁槇鍊0.44宸﹀彸.(娉ㄦ剰瑕佺敤鏀寔鍙g僵妫娴嬬殑妫娴嬫ā鍨)*/
+ }
+
+ ///
+ /// 浜鸿劯缁煎悎淇℃伅
+ ///
+ [StructLayoutAttribute(LayoutKind.Sequential)]
+ public struct cw_face_res_t
+ {
+ public Int64 frameId; // 浜鸿劯鎵鍦ㄥ抚鍙
+
+ public int detected; // 0: 璺熻釜鍒扮殑浜鸿劯; 1: 妫娴嬪埌鐨勪汉鑴; 2:妫娴嬪埌浣嗕笉浼氳杩涜鍚庣画璁$畻(鍏抽敭鐐)鐨勪汉鑴;
+ // 3: 鍙兘鏄潤鎬佽妫妗嗭紱4:澶ц搴︿汉鑴; 5:鍏抽敭鐐归敊璇; 6:涓嶉渶鍐嶅鐞嗙殑浜鸿劯锛堝彧鏈夋爣璁颁负1鐨勪汉鑴革紝鍏抽敭鐐广
+ // 瀵归綈銆佽川閲忓垎鎵嶆湁鏁堬紱浣嗛櫎0涔嬪鍏朵粬閮藉彲鑳芥湁鍙g僵鍒嗭級7:琚及璁′负浣庤川閲忎汉鑴
+
+ public int trackId; // 浜鸿劯ID锛圛D<0琛ㄧず娌℃湁杩涘叆璺熻釜锛
+
+ public cw_facepos_rect_t faceRect; // 浜鸿劯妗
+
+ public cw_keypt keypt; // 鍏抽敭鐐
+
+ public cw_aligned_face_t faceAligned; // 瀵归綈浜鸿劯
+
+ public cw_quality_t quality; // 浜鸿劯璐ㄩ噺
+ }
+
+ public enum cw_recog_pattern_t
+ {
+ CW_FEATURE_EXTRACT = 0, // 鐗瑰緛鎻愬彇
+ CW_RECOGNITION = 1 // 璇 鍒
+ }
+
+
+ [StructLayoutAttribute(LayoutKind.Sequential)]
+ public struct cwFaceAttr
+ {
+ public int sex;
+
+ public string age;
+ public string faceid;
+
+ }
+
+ //////////////////////////////////////////////////////////////////////////绾㈠娲讳綋
+
+ /***************
+ * 绾㈠娲讳綋妫娴嬬粨鏋滆繑鍥炲
+ */
+ public enum cw_nirliv_det_rst_t
+ {
+ CW_NIR_LIV_DET_LIVE = 0, // 浠ラ槇鍊0.5鍒ゆ柇涓烘椿浣
+ CW_NIR_LIV_DET_UNLIVE, // 浠ラ槇鍊0.5鍒ゆ柇涓洪潪娲讳綋
+ CW_NIR_LIV_DET_DIST_FAILED, // 浜鸿劯璺濈妫娴嬫湭閫氳繃
+ CW_NIR_LIV_DET_SKIN_FAILED, // 浜鸿劯鑲よ壊妫娴嬫湭閫氳繃
+ CW_NIR_LIV_DET_NO_PAIR_FACE, // 鏈尮閰嶅埌浜鸿劯
+ CW_NIR_LIV_DET_IS_INIT // 绾㈠娲讳綋妫娴嬬粨鏋滃垵濮嬪
+ }
+
+ /***************
+ * 绾㈠娲讳綋妫娴嬮敊璇爜
+ */
+ public enum cw_nirliveness_err_t
+ {
+ CW_NIRLIV_OK = 0, // 鎴愬姛杩斿洖
+ CW_NIRLIV_ERR_CREATE_HANDLE = 26000, // 鍒涘缓绾㈠娲讳綋妫娴嬪彞鏌勫け璐
+ CW_NIRLIV_ERR_FREE_HANDLE, // 閲婃斁绾㈠娲讳綋妫娴嬪彞鏌勫け璐
+ CW_NIRLIV_ERR_FACE_PAIR, // 浜鸿劯鍖归厤鍒濆鍖栧け璐
+ CW_NIRLIV_ERR_CREAT_LOG_DIR, // 鍒涘缓鏃ュ織璺緞澶辫触
+ CW_NIRLIV_ERR_MODEL_NOTEXIST, // 杈撳叆妯″瀷涓嶅瓨鍦
+ CW_NIRLIV_ERR_MODEL_FAILED, // 杈撳叆妯″瀷鍒濆鍖栧け璐
+ CW_NIRLIV_ERR_INPUT_UNINIT, // 杈撳叆鏈垵濮嬪寲
+ CW_NIRLIV_ERR_NIR_NO_FACE, // 杈撳叆绾㈠鍥剧墖娌℃湁浜鸿劯
+ CW_NIRLIV_ERR_VIS_NO_FACE, // 杈撳叆鍙鍏夊浘鐗囨病鏈変汉鑴
+ CW_NIRLIV_ERR_NO_PAIR_FACE, // 杈撳叆鍙鍏夊拰绾㈠鍥剧墖浜鸿劯鏈兘鍖归厤
+ CW_NIRLIV_ERR_PUSH_DATA, // 杈撳叆鏁版嵁澶辫触
+ CW_NIRLIV_ERR_NUM_LANDMARKS, // 杈撳叆鍙鍏夊浘鐗囧拰绾㈠鍥剧墖鍏抽敭鐐逛釜鏁颁笉绛
+ CW_NIRLIV_ERR_NO_LANDMARKS, // 杈撳叆绾㈠鍥剧墖娌℃湁浜鸿劯鍏抽敭鐐
+ CW_NIRLIV_ERR_INPUT_IMAGE, // 杈撳叆绾㈠鍥剧墖鎴栬呭彲瑙佸厜鍥剧墖涓嶆槸澶氶氶亾
+ CW_NIRLIV_ERR_UNAUTHORIZED, // 娌℃湁license锛堟湭鎺堟潈锛
+ CW_NIRLIV_ERR_FACE_NUM_ERR, // 鏈紑鍚汉鑴稿尮閰嶅紑鍏虫椂锛屽彲瑙佸厜鎴栫孩澶栧浘鍍忎汉鑴稿ぇ浜1
+ CW_NIRLIV_ERR_CAM_UNCW, // 闈炰簯浠庡畾鍒舵憚鍍忓ご
+ CW_NIRLIV_ERR_UNKNOWN, // 鏈煡缁撴灉
+ CW_NIRLIV_ERR_MAXHANDLE, // 瓒呰繃鏈澶х孩澶栨椿浣撴渶澶ф巿鏉冨彞鏌勬暟
+ CW_NIRLIV_ERR_NIRIMAGE, // 杈撳叆绾㈠鍥剧墖鏁版嵁閿欒
+ CW_NIRLIV_ERR_VISIMAGE, // 杈撳叆鍙鍏夊浘鐗囨暟鎹敊璇
+ }
+
+ /***************
+ * 绾㈠娲讳綋妫娴嬬粨鏋
+ */
+ public struct cw_nirliv_res_t
+ {
+ public cw_nirliv_det_rst_t livRst; // 杈撳嚭绾㈠娲讳綋妫娴嬬粨鏋滆繑鍥炲
+ public float score; // 杈撳嚭绾㈠娲讳綋妫娴嬪緱鍒嗭紝闈炴椿浣撶殑鏃跺欎负0
+ }
+
+ public class FaceDataModel
+ {
+ public string GenderMale { get; set; }
+
+ public string Age { get; set; }
+
+ public int StopTime { get; set; }
+
+ public DateTime BeginTime { get; set; }
+
+ public DateTime EndTime { get; set; }
+
+ public string IP { get; set; }
+ }
+
+}
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/SDK/NativeCWFaceDetection.cs b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/SDK/NativeCWFaceDetection.cs
new file mode 100644
index 0000000..2585ddd
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/SDK/NativeCWFaceDetection.cs
@@ -0,0 +1,78 @@
+锘縰sing System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Text;
+using System;
+
+namespace DemoUI.SDK
+{
+ ///
+ /// 浜鸿劯妫娴
+ ///
+ public class NativeCWFaceDetection
+ {
+ private const string CloudWalkSDKDll = "CWFaceSDK.dll";
+
+ ///
+ /// 鍒涘缓妫娴嬪櫒鍙ユ焺
+ ///
+ /// 妯″瀷鍙傛暟閰嶇疆鏂囦欢
+ /// 鎺堟潈鐮侊紙浠呯敤浜庡畨鍗撳钩鍙帮紝PC绔紶绌哄嵆鍙級
+ /// 濡傛灉鍒涘缓鎴愬姛锛岃繑鍥瀌etector鍙ユ焺锛屽惁鍒欒繑鍥炵┖
+ [DllImport(CloudWalkSDKDll, EntryPoint = "cwCreateDetHandle", CallingConvention = CallingConvention.Cdecl)]
+ public static extern IntPtr cwCreateDetHandle(out cw_errcode_t errCode, string pConfigFile, string pLicence);
+
+
+ ///
+ /// 閲婃斁鍒涘缓鐨勬娴嬪櫒
+ ///
+ ///
+ [DllImport(CloudWalkSDKDll, EntryPoint = "cwReleaseDetHandle", CallingConvention = CallingConvention.Cdecl)]
+ public static extern void cwReleaseDetHandle(IntPtr pDetector);
+
+
+ ///
+ /// 鑾峰彇妫娴嬪櫒鍙傛暟
+ ///
+ ///
+ ///
+ ///
+ [DllImport(CloudWalkSDKDll, EntryPoint = "cwGetFaceParam", CallingConvention = CallingConvention.Cdecl)]
+ public static extern cw_errcode_t cwGetFaceParam(IntPtr pDetector, out cw_det_param_t param);
+
+
+ ///
+ /// 璁剧疆妫娴嬪櫒鍙傛暟锛堝繀椤诲厛璋冪敤cwGetFaceParam鍐嶄娇鐢ㄦ鍑芥暟锛
+ ///
+ ///
+ ///
+ ///
+ [DllImport(CloudWalkSDKDll, EntryPoint = "cwSetFaceParam", CallingConvention = CallingConvention.Cdecl)]
+ public static extern cw_errcode_t cwSetFaceParam(IntPtr pDetector, ref cw_det_param_t param);
+
+
+
+
+ ///
+ /// 浜鸿劯妫娴嬭窡韪帴鍙
+ ///
+ ///
+ /// 琚娴嬪浘鍍. 濡傛灉浼犲叆鐨勬暟鎹彧鏈塨gr,鍒檔ImageChannel 鍥哄畾涓3锛屽鏋減imageData涓哄叾浠栨牸寮忥紝鍒欒繕搴旀湁涓涓弬鏁版潵琛ㄧず鍥惧儚鏍煎紡
+ /// 妫娴嬪埌鐨勪汉鑴革紝璇ョ紦鍐插尯鍒濆鍖栧繀椤昏冻澶熷ぇ
+ /// 鏈澶ф娴嬪埌浜鸿劯涓暟锛屼富瑕佸畾涔変簡pFaceBuffer鐨勫垵濮嬪寲澶у皬锛涘鏋滃疄闄呬汉鑴镐釜鏁板浜庢鍊煎垯鍙兘杩斿洖nMaxFaceNumber涓汉鑴.
+ /// 瀹為檯妫娴嬪埌鐨勪汉鑴镐釜鏁
+ /// 浜鸿劯妫娴嬫帴鍙e彲浠ヨ繘琛岀殑鎿嶄綔锛圥OS鏄粯璁ゆ搷浣滐紝鍏朵粬椤瑰彲閫夛紱杩斿洖缁撴灉鍜屾搷浣滈夐」鏄搴旂殑锛,鍏蜂綋鍙傝僁ET_OP瀹氫箟.
+ ///
+ [DllImport(CloudWalkSDKDll, EntryPoint = "cwFaceDetection", CallingConvention = CallingConvention.Cdecl)]
+ public static extern cw_errcode_t cwFaceDetection(IntPtr pDetector, ref cw_img_t pFrameImg, IntPtr pFaceBuffer, int iBuffLen, ref int nFaceNum, int iOp);
+
+
+ ///
+ /// 娓呴櫎妫娴嬭窡韪姸鎬佷俊鎭嚱鏁
+ ///
+ /// 妫娴嬪櫒鍙ユ焺
+ /// 鎴愬姛杩斿洖CW_OK锛屽け璐ヨ繑鍥炲叾浠
+ [DllImport(CloudWalkSDKDll, EntryPoint = "cwResetDetTrackState", CallingConvention = CallingConvention.Cdecl)]
+ public static extern cw_errcode_t cwResetDetTrackState(IntPtr pDetector);
+
+ }
+}
\ No newline at end of file
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/SDK/NativeCWFaceNISLiveness.cs b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/SDK/NativeCWFaceNISLiveness.cs
new file mode 100644
index 0000000..f9a1ac2
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/SDK/NativeCWFaceNISLiveness.cs
@@ -0,0 +1,49 @@
+锘縰sing System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Text;
+using System;
+
+namespace DemoUI.SDK
+{
+ ///
+ /// 浜鸿劯妫娴
+ ///
+ public class CWFaceNisLiveness
+ {
+ private const string CloudWalkSDKDll = "CWFaceSDK.dll";
+
+ ///
+ /// 鍒涘缓娲讳綋妫娴嬪彞鏌
+ ///
+ /// 绾㈠娲讳綋妫娴嬪櫒妯″瀷鏂囦欢
+ /// 绾㈠娲讳綋璇嗗埆姣斿妯″瀷鏂囦欢
+ /// 鍖归厤鏂囦欢璺緞
+ /// 鑲よ壊闃堝硷紙鏍规嵁涓嶅悓鐨勫墠绔増鏈缃級
+ /// 鎺堟潈鐮
+ /// 濡傛灉鍒涘缓鎴愬姛锛岃繑鍥濧ttribute鍙ユ焺锛屽惁鍒欒繑鍥炵┖
+ [DllImport(CloudWalkSDKDll, EntryPoint = "cwCreateNirLivenessHandle", CallingConvention = CallingConvention.Cdecl)]
+ public static extern IntPtr cwCreateNirLivenessHandle(out cw_nirliveness_err_t errCode, string pNirModelPath, string pRecogModelPath, string pPairFilePath, string pLogPath, float skinThresh, string pLicence);
+
+
+ ///
+ /// 閲婃斁娲讳綋妫娴嬪彞鏌
+ ///
+ /// 绾㈠娲讳綋鍙ユ焺
+ [DllImport(CloudWalkSDKDll, EntryPoint = "cwReleaseNirLivenessHandle", CallingConvention = CallingConvention.Cdecl)]
+ public static extern void cwReleaseNirLivenessHandle(IntPtr pHandle);
+
+
+ ///
+ /// 绾㈠娲讳綋妫娴嬫帴鍙
+ ///
+ /// 浜鸿劯妫娴嬪彞鏌
+ /// 绾㈠娲讳綋鍙ユ焺
+ /// 杈撳叆鍙鍏夊浘鐗囨暟鎹
+ /// 杈撳叆绾㈠鍏夊浘鐗囨暟鎹
+ /// 瀛樻斁绾㈠娲讳綋妫娴嬬粨鏋滐紝闇浜嬪厛鍒嗛厤鍐呭瓨
+ ///
+ [DllImport(CloudWalkSDKDll, EntryPoint = "cwFaceNirByImageData", CallingConvention = CallingConvention.Cdecl)]
+ public static extern cw_nirliveness_err_t cwFaceNirByImageData(IntPtr pDetector, IntPtr pNirHandle, ref cw_img_t pImgVis, ref cw_img_t pImgNir, out cw_nirliv_res_t pNirLivRes);
+
+ }
+}
\ No newline at end of file
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/SDK/NativeCWFaceRecognition.cs b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/SDK/NativeCWFaceRecognition.cs
new file mode 100644
index 0000000..62120fe
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/SDK/NativeCWFaceRecognition.cs
@@ -0,0 +1,84 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace DemoUI.SDK
+{
+ ///
+ ///
+ ///
+ public class NativeCWFaceRecognition
+ {
+ private const string CloudWalkSDKDll = "CWFaceSDK.dll";
+
+ ///
+ ///鍔熻兘锛氬垱寤鸿瘑鍒彞鏌
+ ///
+ /// 鍒涘缓鐨勮瘑鍒彞鏌
+ /// 閰嶇疆鏂囦欢璺緞
+ /// 鍒涘缓鐨勫彞鏌勭被鍨
+ ///
+ [DllImport(CloudWalkSDKDll, EntryPoint = "cwCreateRecogHandle", CallingConvention = CallingConvention.Cdecl)]
+ public static extern IntPtr cwCreateRecogHandle(out cw_errcode_t errCode, string pConfigurePath, string pLicence, cw_recog_pattern_t emRecogPattern);
+
+
+ ///
+ /// 閲婃斁閫氶亾
+ ///
+ /// 璇嗗埆鍙ユ焺
+ ///
+ [DllImport(CloudWalkSDKDll, EntryPoint = "cwReleaseRecogHandle", CallingConvention = CallingConvention.Cdecl)]
+ public static extern void cwReleaseRecogHandle(IntPtr pRecogHandle);
+
+
+ ///
+ /// 鍔熻兘锛氳幏鍙栫壒寰佸奸暱搴
+ ///
+ /// 璇嗗埆鍙ユ焺
+ ///
+ [DllImport(CloudWalkSDKDll, EntryPoint = "cwGetFeatureLength", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int cwGetFeatureLength(IntPtr pRecogHandle);
+
+
+ ///
+ /// 鍔熻兘锛氭彁鍙栦汉鑴哥壒寰佸
+ ///
+ /// 璇嗗埆鍙ユ焺
+ /// 瀵归綈浜鸿劯鏁版嵁鎸囬拡
+ /// 杩斿洖鐨勭壒寰佹暟锛岄渶瑕侀鍏堝垎閰嶈冻澶熺┖闂
+ ///
+ [DllImport(CloudWalkSDKDll, EntryPoint = "cwGetFaceFeature", CallingConvention = CallingConvention.Cdecl)]
+ public static extern cw_errcode_t cwGetFaceFeature(IntPtr pRecogHandle, ref cw_aligned_face_t alignedFace, byte[] featueData);
+
+
+
+ ///
+ /// 鍔熻兘锛氳绠2涓壒寰佷笌N涓壒寰佺殑鐩镐技搴︼紝杩斿洖鐨勭浉浼煎害scores鐨勪釜鏁颁负N涓
+ ///
+ /// 璇嗗埆鍙ユ焺
+ /// 鐗瑰緛1锛屽彧鑳芥槸涓涓壒寰
+ /// 鐗瑰緛2锛屽彲浠ユ槸N涓壒寰
+ /// 鐗瑰緛2鐨勪釜鏁
+ /// 杩斿洖鐨勭浉浼煎害鍒嗘暟鏁扮粍锛岄暱搴︿负Fea2num锛岄渶瑕侀鍏堝垎閰嶇┖闂
+ ///
+ [DllImport(CloudWalkSDKDll, EntryPoint = "cwComputeMatchScore", CallingConvention = CallingConvention.Cdecl)]
+ public static extern cw_errcode_t cwComputeMatchScore(IntPtr pRecogHandle, byte[] pFea1, byte[] pFea2, int Fea2Num, float[] scores);
+
+
+ ///
+ /// 鍔熻兘锛氭瘮瀵逛袱涓汉鑴稿浘鐗囦腑鏈澶т汉鑴哥壒寰侊紝鑾峰彇鐩镐技搴
+ ///
+ /// 妫娴嬪彞鏌
+ /// 璇嗗埆鍙ユ焺
+ /// 鍥剧墖1鏁版嵁
+ /// 鍥剧墖2鏁版嵁
+ /// 姣斿鍒嗘暟
+ ///
+ [DllImport(CloudWalkSDKDll, EntryPoint = "cwVerifyImageData", CallingConvention = CallingConvention.Cdecl)]
+ public static extern cw_errcode_t cwVerifyImageData(IntPtr pDetector, IntPtr pRecogHandle, cw_img_t[] pFrameImg1, cw_img_t[] pFrameImg2, float[] scores);
+
+ }
+}
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/SDK/NativeCWFaceVersion.cs b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/SDK/NativeCWFaceVersion.cs
new file mode 100644
index 0000000..d329514
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/SDK/NativeCWFaceVersion.cs
@@ -0,0 +1,47 @@
+锘縰sing System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Text;
+using System;
+
+namespace DemoUI.SDK
+{
+ ///
+ /// 浜鸿劯妫娴
+ ///
+ public class NativeCWFaceVersion
+ {
+ private const string CloudWalkSDKDll = "CWFaceSDK.dll";
+
+ ///
+ /// 鍔熻兘锛氳幏鍙朣DK鐗堟湰淇℃伅
+ ///
+ /// 鐗堟湰淇℃伅锛岄渶浜嬪厛鍒嗛厤鍐呭瓨
+ /// 杈撳嚭buf鍒嗛厤瀛楄妭闀垮害>
+ /// 鎴愬姛杩斿洖CW_OK锛屽け璐ヨ繑鍥炲叾浠
+ [DllImport(CloudWalkSDKDll, EntryPoint = "cwGetSDKVersion", CallingConvention = CallingConvention.Cdecl)]
+ public static extern cw_errcode_t cwGetSDKVersion(StringBuilder pVersion, int iBuffLen);
+
+
+ ///
+ /// 鍔熻兘锛氳幏鍙栬澶囩爜
+ ///
+ /// 璁惧鍞竴鐮侊紝闇浜嬪厛鍒嗛厤鍐呭瓨锛屼笉浣庝簬160瀛楄妭
+ /// 杈撳嚭buf鍒嗛厤瀛楄妭闀垮害锛屼笉浣庝簬160瀛楄妭
+ /// 杈撳嚭鐨勮澶囩爜鐨勯暱搴
+ /// 鎴愬姛杩斿洖CW_OK锛屽け璐ヨ繑鍥炲叾浠
+ [DllImport(CloudWalkSDKDll, EntryPoint = "cwGetDeviceInfo", CallingConvention = CallingConvention.Cdecl)]
+ public static extern cw_errcode_t cwGetDeviceInfo(StringBuilder pDeviceInfo, int iBuffLen, ref int iUseLen);
+
+
+
+ ///
+ /// 鍔熻兘锛氬畨瑁呮巿鏉
+ ///
+ /// 鎺堟潈AppKey锛岄渶浠庝簯浠庣鎶鑾峰彇
+ /// 鎺堟潈ProductId锛岄渶浠庝簯浠庣鎶鑾峰彇
+ /// 鎺堟潈sAppSecret锛岄渶浠庝簯浠庣鎶鑾峰彇
+ /// 鎺堟潈骞跺彂鏁
+ [DllImport(CloudWalkSDKDll, EntryPoint = "cwInstallLicence", CallingConvention = CallingConvention.Cdecl)]
+ public static extern cw_errcode_t cwInstallLicence(string sAppKey, string sAppSecret, string sProductId);
+ }
+}
\ No newline at end of file
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/Window1.xaml b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/Window1.xaml
new file mode 100644
index 0000000..e4ceca7
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/Window1.xaml
@@ -0,0 +1,235 @@
+锘
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/Window1.xaml.cs b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/Window1.xaml.cs
new file mode 100644
index 0000000..30c3803
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/Window1.xaml.cs
@@ -0,0 +1,2022 @@
+锘縰sing DemoUI.Common;
+using DemoUI.SDK;
+using Emgu.CV;
+using Emgu.CV.Structure;
+using Newtonsoft.Json;
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Configuration;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading;
+using System.Windows;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+
+namespace DemoUI
+{
+ ///
+ /// MainWindow.xaml 鐨勪氦浜掗昏緫
+ ///
+ public partial class Window1 : Window
+ {
+ private int m_iShrelhod = 70; // 姣斿闃堝
+ private int m_iCameraIndex = 0; // 鎵撳紑鐨勬憚鍍忓ご绱㈠紩
+ private string m_IMG1Path = string.Empty; // 鐓х墖1璺緞
+ private string m_IMG2Path = string.Empty; // 鐓х墖2璺緞
+ private string m_IMGAttrPath = string.Empty;// 灞炴х収鐗囪矾寰
+
+ private string m_sLicence = ""; // 浜戜粠鎺堟潈licence
+ private IntPtr m_pDet = IntPtr.Zero; // 妫娴嬪彞鏌勶紝鐢ㄤ簬妫娴嬬嚎绋
+ private IntPtr m_pDetVerify = IntPtr.Zero; // 妫娴嬪彞鏌勶紝鐢ㄤ簬涓荤嚎绋嬶紝姣斿鏃朵汉鑴告娴
+ private IntPtr m_pDetVerify1 = IntPtr.Zero; // 妫娴嬪彞鏌勶紝鐢ㄤ簬涓荤嚎绋嬶紝姣斿鏃朵汉鑴告娴
+ private IntPtr m_pRecog = IntPtr.Zero; // 璇嗗埆鍙ユ焺锛岀敤浜庝富绾跨▼锛屼汉鑴告瘮瀵
+
+ private IntPtr m_pAgeAttri = IntPtr.Zero; // 骞撮緞灞炴у彞鏌勶紝鐢ㄤ簬涓荤嚎绋
+ private IntPtr m_pGenderAttri = IntPtr.Zero; // 鎬у埆灞炴у彞鏌勶紝鐢ㄤ簬涓荤嚎绋
+ private IntPtr m_pRaceAttri = IntPtr.Zero; // 浜虹灞炴у彞鏌勶紝鐢ㄤ簬涓荤嚎绋
+
+ private IntPtr m_pNirLive = IntPtr.Zero; // 绾㈠娲讳綋鍙ユ焺锛岀敤浜庝富绾跨▼
+
+ private IntPtr m_buffResult = IntPtr.Zero; // 淇濆瓨浜鸿劯妫娴嬬粨鏋滅殑鎸囬拡锛屼繚璇佸唴瀛樺彧鍒嗛厤涓娆
+ private IntPtr m_buffVerify = IntPtr.Zero; // 浜鸿劯姣斿鏃朵繚瀛樼粨鏋滅殑鎸囬拡锛屼繚璇佸唴瀛樺彧鍒嗛厤涓娆
+
+ private Capture m_capture = null; // 鎽勫儚澶存搷浣滃璞
+ //private Capture m_capture1 = null; // 鎽勫儚澶存搷浣滃璞
+ private Thread m_threadFaceDet = null; // 妫娴嬬嚎绋
+ private Object m_lock = null; // 閿
+ private Mat m_matFrame = null; // 褰撳墠甯
+ //private Mat m_matFrame1 = null; // 褰撳墠甯
+
+ private byte[] m_btImgBuff = null; // 鍒嗛厤鍐呭瓨淇濆瓨鍥剧墖data
+ private GCHandle m_gc;
+ private bool m_bStartThread = false;
+ private DateTime dtNows = DateTime.Now;
+ private cw_face_res_t? maxFace = null;
+ private Dictionary faceDic = new Dictionary();
+ private Dictionary faceDicTime = new Dictionary();
+ private Dictionary faceDicStopTime = new Dictionary();
+ private List matList = new List();
+ private bool isOpenLive = false;
+
+ private List listFaceView = new List();
+ private string AddressIP = string.Empty;
+ private string ServiceUrl = string.Empty;
+
+ private QMLog log = new QMLog();
+
+ public Window1()
+ {
+ InitializeComponent();
+
+ Loaded += MainWindow_Loaded;
+ //ChatWebSocketMiddleware chatWebSocket = new ChatWebSocketMiddleware();
+ //chatWebSocket.openSocket();
+ }
+
+ private void MainWindow_Loaded(object sender, RoutedEventArgs e)
+ {
+ int.TryParse(System.Configuration.ConfigurationManager.AppSettings["Shrelhod"], out m_iShrelhod);
+ if (m_iShrelhod <= 0)
+ {
+ m_iShrelhod = 70;
+ }
+
+ int.TryParse(System.Configuration.ConfigurationManager.AppSettings["CameraIndex"], out m_iCameraIndex);
+
+ m_lock = new object();
+
+ AddressIP = string.Empty;
+ foreach (IPAddress _IPAddress in Dns.GetHostEntry(Dns.GetHostName()).AddressList)
+ {
+ if (_IPAddress.AddressFamily.ToString() == "InterNetwork")
+ {
+ AddressIP = _IPAddress.ToString();
+ }
+ }
+
+ ServiceUrl = ConfigurationManager.AppSettings["HttpUrl"];
+
+ listFaceView.Clear();
+ }
+
+ private void Window_Closed(object sender, EventArgs e)
+ {
+ m_bStartThread = false;
+ try
+ {
+ if (null != m_capture)
+ {
+ m_capture.Stop();
+ m_capture.Dispose();
+ }
+
+ //if (null != m_capture1)
+ //{
+ // m_capture1.Stop();
+ // m_capture1.Dispose();
+ //}
+ }
+ catch (Exception exec)
+ {
+
+ }
+
+ if (IntPtr.Zero != m_pDet)
+ {
+ NativeCWFaceDetection.cwReleaseDetHandle(m_pDet);
+ m_pDet = IntPtr.Zero;
+ }
+
+ if (IntPtr.Zero != m_pDetVerify)
+ {
+ NativeCWFaceDetection.cwReleaseDetHandle(m_pDetVerify);
+ m_pDetVerify = IntPtr.Zero;
+ }
+
+ if (IntPtr.Zero != m_pRecog)
+ {
+ NativeCWFaceRecognition.cwReleaseRecogHandle(m_pRecog);
+ m_pRecog = IntPtr.Zero;
+ }
+
+ DestroyAttributeHandle();
+ DestroyNirLivenessHandle();
+
+ if (m_buffResult != IntPtr.Zero)
+ {
+ Marshal.FreeHGlobal(m_buffResult);
+ m_buffResult = IntPtr.Zero;
+ }
+ if (m_buffVerify != IntPtr.Zero)
+ {
+ Marshal.FreeHGlobal(m_buffVerify);
+ m_buffVerify = IntPtr.Zero;
+ }
+
+ if (m_gc.IsAllocated)
+ {
+ m_gc.Free();
+ }
+ try
+ {
+ var pendingRemoveList = faceDic.Keys.ToList();
+ foreach (int id in pendingRemoveList)
+ {
+ FaceDataModel model = new FaceDataModel();
+ model.Age = faceDic[id].age.ToString();
+ model.BeginTime = faceDicTime[id];
+ model.EndTime = DateTime.Now;
+ model.GenderMale = faceDic[id].sex == 0 ? "濂" : "鐢";
+ model.StopTime = Convert.ToInt32((DateTime.Now - faceDicTime[id]).TotalSeconds);
+ model.IP = AddressIP;
+ if (model.StopTime > 1)
+ {
+ listFaceView.Add(model);
+ }
+ }
+ //MessageBox.Show(listFaceView.Count.ToString());
+ if (listFaceView.Count > 0)
+ {
+ //var data = new
+ //{
+ // FaceListModel = listFaceView,
+ // IP = AddressIP
+ //};
+ var url = ServiceUrl + "/api/Face/UpLoadFace";
+ var param = JsonConvert.SerializeObject(listFaceView);
+ var _r = PostMoths(url, param);
+ listFaceView.Clear();
+ }
+ //MessageBox.Show(pendingRemoveList.Count.ToString());
+ }
+ catch (Exception ex)
+ {
+ //MessageBox.Show(ex.Message);
+ //throw;
+ }
+ Close();
+ }
+
+
+ private bool OnBtnInit()
+ {
+ bool flag = false;
+ StringBuilder sbVersion = new StringBuilder(100);
+ NativeCWFaceVersion.cwGetSDKVersion(sbVersion, 100);
+ tbSDKVersion.Text = sbVersion.ToString();
+
+ if (IntPtr.Zero != m_pDet && IntPtr.Zero != m_pRecog)
+ {
+ MessageBox.Show("宸插垵濮嬪寲杩囷紝涓嶅啀鍒濆鍖");
+ return flag;
+ }
+
+ // 32浣嶅拰64浣嶆娴嬫ā鍨嬩笉鑳藉叡鐢紝64浣嶇敤_configs_frontend.xml锛岄潪64浣嶇敤_configs_frontend_x86_arm.xml
+ string sModelXmlPath;
+ if (Environment.Is64BitProcess)
+ {
+ sModelXmlPath = "../../CWModels/_configs_frontend.xml";
+ }
+ else
+ {
+ sModelXmlPath = "../../CWModels/_configs_frontend_x86_arm.xml";
+ }
+
+ SDK.cw_errcode_t errCode = cw_errcode_t.CW_OK;
+ m_pDet = NativeCWFaceDetection.cwCreateDetHandle(out errCode, sModelXmlPath, m_sLicence);
+ if (IntPtr.Zero == m_pDet || errCode != cw_errcode_t.CW_OK)
+ {
+ MessageBox.Show("妫娴嬪彞鏌1鍒涘缓澶辫触锛岄敊璇爜锛" + errCode.ToString());
+ return flag;
+ }
+ cw_det_param_t param;
+ NativeCWFaceDetection.cwGetFaceParam(m_pDet, out param);
+ param.minSize = 48;
+ param.maxSize = 600;
+ param.pConfigFile = sModelXmlPath; // 璁剧疆鎺ュ彛鍔熻兘鍙傛暟
+ NativeCWFaceDetection.cwSetFaceParam(m_pDet, ref param);
+
+ m_pDetVerify = NativeCWFaceDetection.cwCreateDetHandle(out errCode, sModelXmlPath, m_sLicence);
+ if (IntPtr.Zero == m_pDetVerify || errCode != cw_errcode_t.CW_OK)
+ {
+ MessageBox.Show("妫娴嬪彞鏌2鍒涘缓澶辫触锛岄敊璇爜锛" + errCode.ToString());
+ return flag;
+ }
+ NativeCWFaceDetection.cwGetFaceParam(m_pDetVerify, out param);
+ param.minSize = 30;
+ param.maxSize = 600;
+ param.pConfigFile = sModelXmlPath; // 璁剧疆鎺ュ彛鍔熻兘鍙傛暟
+ NativeCWFaceDetection.cwSetFaceParam(m_pDetVerify, ref param);
+
+ m_pDetVerify1 = NativeCWFaceDetection.cwCreateDetHandle(out errCode, sModelXmlPath, m_sLicence);
+ if (IntPtr.Zero == m_pDetVerify1 || errCode != cw_errcode_t.CW_OK)
+ {
+ MessageBox.Show("妫娴嬪彞鏌2鍒涘缓澶辫触锛岄敊璇爜锛" + errCode.ToString());
+ return flag;
+ }
+ NativeCWFaceDetection.cwGetFaceParam(m_pDetVerify1, out param);
+ param.minSize = 30;
+ param.maxSize = 600;
+ param.pConfigFile = sModelXmlPath; // 璁剧疆鎺ュ彛鍔熻兘鍙傛暟
+ NativeCWFaceDetection.cwSetFaceParam(m_pDetVerify1, ref param);
+
+ // NativeCWFaceDetection.cwSetFaceBufOrder(m_pDetVerify, 1);
+
+ //鎻愬彇鐗瑰緛
+ m_pRecog = NativeCWFaceRecognition.cwCreateRecogHandle(out errCode, "../../CWModels/CWR_Config_1_1.xml", m_sLicence, SDK.cw_recog_pattern_t.CW_FEATURE_EXTRACT);
+
+ if (IntPtr.Zero == m_pRecog || errCode != cw_errcode_t.CW_OK)
+ {
+ MessageBox.Show("璇嗗埆鍙ユ焺鍒涘缓澶辫触锛岄敊璇爜锛" + errCode.ToString());
+ return flag;
+ }
+
+ errCode = CreateAttributeHandle();
+ if (errCode != cw_errcode_t.CW_OK)
+ {
+ return flag;
+ }
+
+ cw_nirliveness_err_t errCodeNir = CreateNirLivenessHandle();
+ if (errCodeNir == cw_nirliveness_err_t.CW_NIRLIV_OK)
+ {
+ flag = true;
+
+ }
+ return flag;
+ }
+
+ // 鍒濆鍖栦簨浠讹紝鍔犺浇妯″瀷锛屽垱寤哄彞鏌
+ private void OnBtnInit(object sender, RoutedEventArgs e)
+ {
+ bool flag = OnBtnInit();
+ if (flag)
+ {
+ MessageBox.Show("鍒濆鍖栨垚鍔");
+ }
+ else
+ {
+ MessageBox.Show("鍒濆鍖栧け璐");
+ }
+ }
+
+ private void OnBtnOpenUsb()
+ {
+ if (IntPtr.Zero == m_pDet)
+ {
+ MessageBox.Show("妫娴嬪彞鏌勪负绌猴紝璇峰厛鍒濆鍖栧垱寤哄彞鏌");
+ return;
+ }
+ if (m_bStartThread)
+ {
+ MessageBox.Show("鎽勫儚澶村凡鎵撳紑");
+ return;
+ }
+
+ try
+ {
+ // 璋冪敤emgu鎵撳紑鎽勫儚澶达紝闇鍏堝皢emgu鏂囦欢澶逛腑鐨"cvextern.dll"鎷疯礉鍒扮紪璇戝ソ鐨凟XE绋嬪簭鐩綍"build_32/bin"涓
+ m_capture = new Capture(0);
+ if (m_capture.Height < 1 || m_capture.Width < 1)
+ {
+ MessageBox.Show("绾㈠鎽勫儚澶存墦寮澶辫触");
+ return;
+ }
+ m_capture.Start();
+
+
+ //m_capture1 = new Capture(1);
+ //if (m_capture1.Height < 1 || m_capture1.Width < 1)
+ //{
+ // MessageBox.Show("鍙鍏夋憚鍍忓ご鎵撳紑澶辫触");
+ // return;
+ //}
+ //m_capture1.Start();
+
+ m_threadFaceDet = new Thread(new ThreadStart(ThreadFaceDet));
+ m_bStartThread = true;
+ m_threadFaceDet.Start();
+ }
+ catch (Exception exec)
+ {
+ MessageBox.Show(exec.Message + "\r\n璇峰皢褰撳墠鐩綍emgu涓嬬殑cvextern.dll鎷疯礉鍒版墽琛岀▼搴忕洰褰");
+ }
+ }
+
+ // 寮鍚疷SB鎽勫儚澶
+ private void OnBtnOpenUsb(object sender, RoutedEventArgs e)
+ {
+ OnBtnOpenUsb();
+ }
+
+ private void ThreadFaceDet()
+ {
+ while (m_bStartThread)
+ {
+ try
+ {
+ Mat mat = null;
+ Mat mat1 = null;
+ Mat matCenter = null;
+ Mat mat1Center = null;
+ var flagCount = 0;
+ lock (m_lock)
+ {
+ m_matFrame = m_capture.QueryFrame();
+ if (null != m_matFrame)
+ {
+ mat = m_matFrame.Clone();
+ matCenter = new Mat(mat, new System.Drawing.Rectangle(new System.Drawing.Point(mat.Width / 2 - 150, mat.Height / 2 - 150),
+ new System.Drawing.Size(300, 300)));
+ }
+
+
+ //m_matFrame1 = m_capture1.QueryFrame();
+ //if (null != m_matFrame1)
+ //{
+ // mat1 = m_matFrame1.Clone();
+ // mat1Center = new Mat(mat1, new System.Drawing.Rectangle(new System.Drawing.Point(mat1.Width / 2 - 150, mat1.Height / 2 - 150),
+ // new System.Drawing.Size(300, 300)));
+ //}
+
+
+
+ /////////鎺ㄩ佹祦鏂囦欢
+ //Emgu.CV.Util.VectorOfByte buff = new Emgu.CV.Util.VectorOfByte();
+ //CvInvoke.Imencode(".jpg", m_matFrame1, buff);
+ //byte[] encodeBuff = new byte[buff.Size];
+ //Marshal.Copy(buff.StartAddress, encodeBuff, 0, buff.Size);
+
+ //string base64Str = Convert.ToBase64String(encodeBuff);
+ //ChatWebSocketMiddleware.allSockets.ToList().ForEach(s => s.Send(base64Str));
+
+ }
+
+ if (mat != null)
+ {
+ var result = FaceDetect(mat);
+ //int channels = mat.NumberOfChannels;
+ cw_face_res_t? curMatFace = null;
+ var pendingRemoveList = faceDic.Keys.ToList();
+ var removeList = new ArrayList();
+ if (result != null && result.Count > 0)
+ {
+ SDK.cw_errcode_t errCode = cw_errcode_t.CW_OK;
+ foreach (cw_face_res_t facepos in result)
+ {
+ if (facepos.quality.errcode == cw_quality_errcode_t.CW_QUALITY_OK && facepos.quality.scores[0] > 0.8 && (curMatFace == null || (curMatFace != null && facepos.faceRect.width > curMatFace.Value.faceRect.width)))
+ {
+ curMatFace = facepos;
+ }
+
+ if (!faceDic.ContainsKey(facepos.trackId))
+ {
+ //CvInvoke.Rectangle(mat1, new System.Drawing.Rectangle(facepos.faceRect.x, facepos.faceRect.y, facepos.faceRect.width, facepos.faceRect.height), new MCvScalar(0, 0, 255), 2);
+ int pAge = 0;
+ float pAgeConfidence = 0.000F;
+ cw_aligned_face_t faceAligned = facepos.faceAligned;
+ errCode = NativeCWFaceAttribute.cwGetAgeEval(m_pAgeAttri, ref faceAligned, out pAge);
+ //ShowAgeGroupResult(errCode, pAge, pAgeConfidence);
+
+ int pGender = 0;
+ float pGenderConfidence = 0.000F;
+ errCode = NativeCWFaceAttribute.cwGetGenderEval(m_pGenderAttri, ref faceAligned, out pGender, out pGenderConfidence);
+ cwFaceAttr cwFaceAttr = new cwFaceAttr();
+ //0 灏忓 1 鎴愬勾浜 2 鑰佷汉
+ cwFaceAttr.age = pAge.ToString();
+ cwFaceAttr.sex = pGender;
+ cwFaceAttr.faceid = facepos.trackId.ToString();
+ //ShowGenderResult(errCode, pGender, pGenderConfidence);
+ faceDic.Add(facepos.trackId, cwFaceAttr);
+ //dict[face.ID] = faceResult.Item2;
+ faceDicTime.Add(facepos.trackId, DateTime.Now);
+ //SendHttpForMap(frame, face);
+ //dictFace[face.ID] = face;
+ }
+ else
+ {
+ pendingRemoveList.Remove(facepos.trackId);
+ //dictFace[face.ID] = face;
+ }
+ if (faceDicStopTime.Keys.Contains(facepos.trackId) && faceDicStopTime[facepos.trackId].HasValue)
+ {
+ faceDicStopTime[facepos.trackId] = null;
+ }
+ if (maxFace.HasValue && maxFace.Value.trackId == facepos.trackId)
+ {
+ CvInvoke.PutText(mat, $"{facepos.trackId}", new System.Drawing.Point(facepos.faceRect.x + (facepos.faceRect.width / 2), facepos.faceRect.y), Emgu.CV.CvEnum.FontFace.HersheyScriptComplex, 1, new MCvScalar(255, 255, 0), 2);
+ //CvInvoke.PutText(mat1, $"{facepos.trackId}", new System.Drawing.Point(facepos.faceRect.x + (facepos.faceRect.width / 2), facepos.faceRect.y), Emgu.CV.CvEnum.FontFace.HersheyScriptComplex, 1, new MCvScalar(255, 255, 0), 2);
+
+ }
+ //CvInvoke.PutText(mat, $"{facepos.trackId}, {pAge} ,{pGender},{pRace}", new System.Drawing.Point(facepos.faceRect.x + (facepos.faceRect.width / 2), facepos.faceRect.y), Emgu.CV.CvEnum.FontFace.HersheyScriptComplex, 1, new MCvScalar(255, 255, 0), 2);
+ //CvInvoke.PutText(mat1, $"{facepos.trackId}, {pAge} ,{pGender},{pRace}", new System.Drawing.Point(facepos.faceRect.x + (facepos.faceRect.width / 2), facepos.faceRect.y), Emgu.CV.CvEnum.FontFace.HersheyScriptComplex, 1, new MCvScalar(255, 255, 0), 2);
+ }
+
+ foreach (int id in pendingRemoveList)
+ {
+ if (!faceDicStopTime.Keys.Contains(id))
+ {
+ faceDicStopTime.Add(id, DateTime.Now);
+ }
+ else if (!faceDicStopTime[id].HasValue)
+ {
+ faceDicStopTime[id] = DateTime.Now;
+ }
+ else if (faceDicStopTime[id].Value.AddSeconds(2) <= DateTime.Now)
+ {
+ AddFaceView(faceDic[id], faceDicTime[id]);
+ faceDic.Remove(id);
+ faceDicTime.Remove(id);
+ faceDicStopTime.Remove(id);
+ }
+ }
+ if (maxFace.HasValue && !faceDic.Keys.Contains(maxFace.Value.trackId))
+ {
+ maxFace = null;
+ }
+ if (!isOpenLive && !maxFace.HasValue && curMatFace.HasValue)
+ {
+ maxFace = curMatFace;
+ CvInvoke.Rectangle(mat, new System.Drawing.Rectangle(maxFace.Value.faceRect.x, maxFace.Value.faceRect.y, maxFace.Value.faceRect.width, maxFace.Value.faceRect.height), new MCvScalar(0, 0, 255), 2);
+ // CvInvoke.PutText(mat, $"{maxFace.Value.trackId}", new System.Drawing.Point(maxFace.Value.faceRect.x + (maxFace.Value.faceRect.width / 2), maxFace.Value.faceRect.y), Emgu.CV.CvEnum.FontFace.HersheyScriptComplex, 1, new MCvScalar(255, 255, 0), 2);
+ CvInvoke.Imwrite("./a.jpg", m_matFrame);
+ SendHttpForMap(mat, curMatFace.Value);
+ //Bd_Pic1.Background = new ImageBrush(GetBitmapImage(m_IMG1Path));
+ //isSendFace = false;
+ //saveImage(frame, maxFace);
+ }
+
+ //if (isOpenLive)
+ //{
+ // if (matCenter != null && mat1Center != null)
+ // {
+ // if (matList.Count <= 8)
+ // {
+ // var matCenterResult = FaceDetect(mat);
+ // //var matCenterResult1 = FaceDetect(mat1Center);
+ // //if (matCenterResult != null && matCenterResult.Count > 0 && matCenterResult1 != null && matCenterResult1.Count > 0)
+ // if (matCenterResult != null && matCenterResult.Count > 0)
+ // {
+
+ // if (!maxFace.HasValue)
+ // {
+ // foreach (cw_face_res_t facepos in result)
+ // {
+ // if (facepos.quality.errcode == cw_quality_errcode_t.CW_QUALITY_OK && facepos.quality.scores[0] > 0.8 && (curMatFace == null || (curMatFace != null && facepos.faceRect.width > curMatFace.Value.faceRect.width)))
+ // {
+ // curMatFace = facepos;
+ // }
+ // }
+ // }
+
+ // matList.Add(matCenter);
+ // matList.Add(mat1Center);
+
+ // if (matList.Count == 10)
+ // {
+ // var list = matList.GetRange(0, matList.Count);
+ // for (int i = 0; i < 5; i++)
+ // {
+ // bool flag = NirLiveness(list[i*2], list[i*2+1]);
+ // if (flag)
+ // {
+ // flagCount += 1;
+ // }
+ // }
+ // if (flagCount < 3)
+ // {
+ // matList.Clear();
+ // }
+ // else {
+ // ////////////////鎺ㄩ佺敤鎴风櫥闄
+ // maxFace = curMatFace;
+ // }
+ // }
+ // }
+ // }
+
+
+ // }
+ //}
+
+ }
+ else
+ {
+ foreach (int id in pendingRemoveList)
+ {
+ if (!faceDicStopTime.Keys.Contains(id))
+ {
+ faceDicStopTime.Add(id, DateTime.Now);
+ }
+ else if (!faceDicStopTime[id].HasValue)
+ {
+ faceDicStopTime[id] = DateTime.Now;
+ }
+ else if (faceDicStopTime[id].Value.AddSeconds(2) <= DateTime.Now)
+ {
+ AddFaceView(faceDic[id], faceDicTime[id]);
+ faceDic.Remove(id);
+ faceDicTime.Remove(id);
+ faceDicStopTime.Remove(id);
+ }
+ }
+ if (maxFace.HasValue && !faceDic.Keys.Contains(maxFace.Value.trackId))
+ {
+ maxFace = null;
+ }
+ }
+
+ this.Dispatcher.BeginInvoke(new Action(() =>
+ {
+ video.Source = ToBitmapSource(mat); // 鏄剧ず鍒扮晫闈笂
+ //if (isOpenLive)
+ //{
+ // if (matCenter != null)
+ // {
+ // video1.Source = ToBitmapSource(matCenter); // 鏄剧ず鍒扮晫闈笂
+ // }
+ // if (mat1Center != null)
+ // {
+ // video2.Source = ToBitmapSource(mat1Center); // 鏄剧ず鍒扮晫闈笂
+ // }
+ // if (!txtFaceLive.Text.Contains(" 娲讳綋"))
+ // {
+ // txtFaceLive.Text = flagCount >= 3 ? flagCount +" " + "娲讳綋" :flagCount+ " " + "闈炴椿浣";
+ // }
+ //}
+ //if (result.Count > 0)
+ //{
+ // if (dtNows.AddSeconds(5) >= DateTime.Now)
+ // {
+ // lock (m_lock)
+ // {
+ // m_IMG1Path = "./1.jpg";
+ // CvInvoke.Imwrite(m_IMG1Path, m_matFrame);
+ // Bd_Pic1.Background = new ImageBrush(GetBitmapImage(m_IMG1Path));
+
+ // m_IMG2Path = "./2.jpg";
+ // CvInvoke.Imwrite(m_IMG2Path, m_matFrame);
+ // Bd_Pic2.Background = new ImageBrush(GetBitmapImage(m_IMG2Path));
+ // }
+ // }
+ //}
+ }));
+ }
+ }
+ catch (Exception e)
+ {
+ string s = e.Message.ToString();
+ }
+ }
+ }
+
+ private void SendHttpForMap(Mat frame, cw_face_res_t face)
+ {
+ if (faceDic.ContainsKey(face.trackId))
+ {
+ var age = faceDic[face.trackId].age;
+ var sex = faceDic[face.trackId].sex;
+ //Process[] proSc = Process.GetProcesses();
+ //bool pcstart = false;
+ //var oldFace = faceEntryTime.Where(i => i.Value.AddMinutes(1) < DateTime.Now).Select(i => i.Key).ToList();
+ //foreach (var item in oldFace)
+ //{
+ // faceEntryTime.Remove(item);
+ //}
+ //for (int i = 0; i < proSc.Length; i++)
+ //{
+ // if (proSc[i].ProcessName.ToLower().Trim() == "pcscreensavers")
+ // {
+ // pcstart = true;
+ // break;
+ // }
+ //}
+ //if (pcstart)
+ //{
+ int x = 0;
+ int y = 0;
+ int width = 0;
+ int height = 0;
+ if ((int)face.faceRect.x > 0)
+ {
+ x = (int)face.faceRect.x;
+ //qMLog.WriteLogToFile("x:"+ ((int)face.Rect.X)+ " Width"+ ((int)face.Rect.Width)+ " frame"+ frame.Width,"111");
+ width = ((int)face.faceRect.x + (int)face.faceRect.width) >= frame.Width ? (frame.Width - (int)face.faceRect.x - 1) : (int)face.faceRect.width;
+ }
+ else
+ {
+ x = 0;
+ width = (int)face.faceRect.width >= frame.Width ? frame.Width - 1 : (int)face.faceRect.width + (int)face.faceRect.x - 1;
+ }
+
+ if ((int)face.faceRect.y > 0)
+ {
+ y = (int)face.faceRect.y;
+
+ height = ((int)face.faceRect.y + (int)face.faceRect.height) >= frame.Height ? (frame.Height - (int)face.faceRect.y - 1) : (int)face.faceRect.height;
+ }
+ else
+ {
+ y = 0;
+ height = (int)face.faceRect.height >= frame.Height ? frame.Height - 1 : (int)face.faceRect.height + (int)face.faceRect.y - 1;
+ }
+ string AddressIP = string.Empty;
+ foreach (IPAddress _IPAddress in Dns.GetHostEntry(Dns.GetHostName()).AddressList)
+ {
+ if (_IPAddress.AddressFamily.ToString() == "InterNetwork")
+ {
+ AddressIP = _IPAddress.ToString();
+ }
+ }
+ try
+ {
+ using (Mat newFrame = new Mat(frame, new System.Drawing.Rectangle(new System.Drawing.Point(x, y),
+ new System.Drawing.Size(width, height))))
+ {
+ Emgu.CV.Util.VectorOfByte buff = new Emgu.CV.Util.VectorOfByte();
+ CvInvoke.Imencode(".jpg", newFrame, buff);
+ byte[] encodeBuff = new byte[buff.Size];
+ Marshal.Copy(buff.StartAddress, encodeBuff, 0, buff.Size);
+
+ string base64Str = Convert.ToBase64String(encodeBuff);
+ //if (!faceEntryTime.ContainsKey(face.ID))
+ //{
+ // faceEntryTime.Add(face.ID, DateTime.Now);
+ var url = ConfigurationManager.AppSettings["KioskUrl"] + "/api/Face/UpLoadFace";
+
+
+
+
+ System.Text.UnicodeEncoding converter = new System.Text.UnicodeEncoding();
+ string data = "Face=" + base64Str + "&ip=" + AddressIP + "&method=relay&Age=" + age + "&GenderMale=" + sex;
+ var _r = PostMothsForm(url, data);
+ Dictionary dic = JsonConvert.DeserializeObject>(_r);
+ if (dic["code"].ToString() == "200")
+ {
+ ChatWebSocketMiddleware.allSockets.ToList().ForEach(s => s.Send(dic["data"].ToString()));
+ }
+
+ //}
+ }
+
+
+ }
+ catch (Exception e)
+ {
+ log.WriteLogFile(e.Message, "HTTPError");
+ }
+ }
+ //}
+ }
+
+ private void AddFaceView(cwFaceAttr faceModel, DateTime dtBegin, bool isSubmit = false)
+ {
+
+
+ var url = ServiceUrl + "/api/Face/UpLoadFace";
+ try
+ {
+ FaceDataModel model = new FaceDataModel();
+ model.Age = faceModel.age.ToString();
+ model.BeginTime = dtBegin;
+ model.EndTime = DateTime.Now;
+ model.GenderMale = faceModel.sex == 0 ? "濂" : "鐢";
+ model.StopTime = Convert.ToInt32((DateTime.Now - dtBegin).TotalSeconds);
+ model.IP = AddressIP;
+ if (model.StopTime > 1)
+ {
+ listFaceView.Add(model);
+ if (listFaceView.Count >= 5)
+ {
+ //var data = new
+ //{
+ // FaceListModel = listFaceView,
+ // IP = AddressIP
+ //};
+ var param = JsonConvert.SerializeObject(listFaceView);
+ var _r = PostMoths(url, param);
+ if (!string.IsNullOrEmpty(_r))
+ {
+ Dictionary dic = JsonConvert.DeserializeObject>(_r);
+ if (dic["code"].ToString() == "200")
+ {
+ listFaceView.Clear();
+ }
+ }
+ }
+
+ }
+
+ }
+ catch (Exception e)
+ {
+ //MessageBox.Show(url + e.Message);
+ }
+
+ //try
+ //{
+ // this.Dispatcher.BeginInvoke(new Action(() =>
+ // {
+ // string face = txtFace.Text;
+ // //if (!string.IsNullOrEmpty(face)) {
+ // // face = face.Substring(face.LastIndexOf("\n"));
+ // //}
+ // txtFace.Text= face+ "\n" + faceModel.faceid + " " + faceModel.age+" "+ faceModel.sex+" "+ Convert.ToInt32((DateTime.Now - dtBegin).TotalSeconds).ToString()+"s";
+ // }));
+
+ //}
+ //catch (Exception e)
+ //{
+ // //MessageBox.Show(url + e.Message);
+ //}
+ }
+
+ public string PostMoths(string url, string param)
+ {
+ string strURL = url;
+ System.Net.HttpWebRequest request;
+ request = (System.Net.HttpWebRequest)WebRequest.Create(strURL);
+ request.Method = "POST";
+ request.ContentType = "application/json;charset=UTF-8";
+ string paraUrlCoded = param;
+ byte[] payload;
+ payload = System.Text.Encoding.UTF8.GetBytes(paraUrlCoded);
+ request.ContentLength = payload.Length;
+ Stream writer = request.GetRequestStream();
+ writer.Write(payload, 0, payload.Length);
+ writer.Close();
+ System.Net.HttpWebResponse response;
+ response = (System.Net.HttpWebResponse)request.GetResponse();
+ System.IO.Stream s;
+ s = response.GetResponseStream();
+ string StrDate = "";
+ string strValue = "";
+ StreamReader Reader = new StreamReader(s, Encoding.UTF8);
+ while ((StrDate = Reader.ReadLine()) != null)
+ {
+ strValue += StrDate + "\r\n";
+ }
+ return strValue;
+ }
+
+ public static string PostMothsForm(string url, string param)
+ {
+ string strURL = url;
+ System.Net.HttpWebRequest request;
+ request = (System.Net.HttpWebRequest)WebRequest.Create(strURL);
+ request.Method = "POST";
+ request.ContentType = "application/x-www-form-urlencoded;charset=UTF-8";
+ string paraUrlCoded = param;
+ byte[] payload;
+ payload = System.Text.Encoding.UTF8.GetBytes(paraUrlCoded);
+ request.ContentLength = payload.Length;
+ Stream writer = request.GetRequestStream();
+ writer.Write(payload, 0, payload.Length);
+ writer.Close();
+ System.Net.HttpWebResponse response;
+ response = (System.Net.HttpWebResponse)request.GetResponse();
+ System.IO.Stream s;
+ s = response.GetResponseStream();
+ string StrDate = "";
+ string strValue = "";
+ StreamReader Reader = new StreamReader(s, Encoding.UTF8);
+ while ((StrDate = Reader.ReadLine()) != null)
+ {
+ strValue += StrDate + "\r\n";
+ }
+ return strValue;
+ }
+
+ List FaceDetect(Mat mat)
+ {
+ try
+ {
+
+
+ // 缁欏浘鍍忕粨鏋勪綋璧嬪
+ SDK.cw_img_t srcImg = new SDK.cw_img_t();
+ srcImg.dataLen = mat.GetData().Length;
+ srcImg.width = mat.Width;
+ srcImg.height = mat.Height;
+ srcImg.format = SDK.cw_img_form_t.CW_IMAGE_BGR888;
+ srcImg.angle = SDK.cw_img_angle_t.CW_IMAGE_ANGLE_0;
+ srcImg.mirror = cw_img_mirror_t.CW_IMAGE_MIRROR_NONE;
+
+ //涓嬮潰杩欎袱鍙ワ紝澶歝opy涓娆℃槸蹇呴』鐨勶紝涓嶇劧鍦ㄦ湁鐨勭數鑴戜笂鏈夋姤opencv閿欒
+ if (m_btImgBuff == null || m_btImgBuff.Length < srcImg.dataLen)
+ {
+ m_btImgBuff = new byte[srcImg.dataLen];
+ if (m_gc.IsAllocated)
+ {
+ m_gc.Free();
+ }
+ m_gc = GCHandle.Alloc(m_btImgBuff, GCHandleType.Pinned);
+ }
+ Array.Copy(mat.GetData(), m_btImgBuff, srcImg.dataLen);
+ //srcImg.data = Marshal.UnsafeAddrOfPinnedArrayElement(m_btImgBuff, 0);
+ srcImg.data = Marshal.AllocHGlobal(m_btImgBuff.Length);
+ Marshal.Copy(m_btImgBuff, 0, srcImg.data, m_btImgBuff.Length);
+
+ int iSize = Marshal.SizeOf(typeof(cw_face_res_t));
+ if (IntPtr.Zero == m_buffResult)
+ {
+ m_buffResult = Marshal.AllocHGlobal(10 * iSize);
+ if (m_buffResult == IntPtr.Zero)
+ {
+ return null;
+ }
+ }
+
+ // 浜鸿劯妫娴
+ int iFaceNum = 0;
+ cw_errcode_t errCode = NativeCWFaceDetection.cwFaceDetection(m_pDet, ref srcImg, m_buffResult, 10, ref iFaceNum, (int)(DetectTrackOperationType.CW_OP_ALIGN | DetectTrackOperationType.CW_OP_DET | DetectTrackOperationType.CW_OP_QUALITY | DetectTrackOperationType.CW_OP_TRACK));
+ if (errCode != cw_errcode_t.CW_OK || iFaceNum < 1)
+ {
+ Marshal.FreeHGlobal(srcImg.data);
+ return null;
+ }
+ //if (iFaceNum == 1)
+ //{
+ // byte[] imgData = new byte[srcImg.dataLen];
+ // Marshal.Copy(srcImg.data, imgData, 0, srcImg.dataLen);
+ // string name = Guid.NewGuid().ToString();
+
+ // CvInvoke.Imwrite($"./{name}.bmp", srcImg.data);
+ // CvInvoke.(saveFileDialog.FileName, this.img);
+
+ // MemoryStream ms = new MemoryStream(imgData);
+ // System.Drawing.Image img = Bitmap.FromStream(ms, true);
+ // img.Save($"./22222.bmp");
+
+
+ // using (var stream = new FileStream($"./{name}.bmp", FileMode.Create))
+ // {
+ // stream.Write(imgData, 0, imgData.Length);
+ // }
+ //}
+ //if (iFaceNum > 1)
+ //{
+
+ // byte[] imgData = new byte[srcImg.dataLen];
+ // Marshal.Copy(srcImg.data, imgData, 0, srcImg.dataLen);
+ // string name = Guid.NewGuid().ToString();
+
+ // string vsAccessoryPath = System.AppDomain.CurrentDomain.BaseDirectory.TrimEnd('\\') + "\\1234.bmp";
+ // FileStream fileStream = null;
+ // try
+ // {
+ // //File.Create Method (String):Creates or overwrites a file in the specified path.
+ // fileStream = File.Create(vsAccessoryPath);
+ // }
+ // catch (System.IO.IOException e)
+ // {
+
+ // }
+ // //FileStream.Write Method:Writes a block of bytes to the file stream.
+ // fileStream.Write(imgData, 0, imgData.Length);
+ // //FileStream.Flush 鏂规硶:娓呴櫎璇ユ祦鐨勬墍鏈夌紦鍐插尯锛屼娇寰楁墍鏈夌紦鍐茬殑鏁版嵁閮借鍐欏叆鍒板熀纭璁惧銆
+ // fileStream.Flush();
+ // //FileStream.Close Method:Closes the file and releases any resources associated with the current file stream.
+ // fileStream.Close();
+ // //using (var stream = new FileStream($"./{name}.txt", FileMode.Create))
+ // //{
+ // // //stream.Write(imgData, 0, imgData.Length);
+ // //}
+ //}
+
+
+ // 鍙栦汉鑴哥殑鏁版嵁
+ List vecRet = new List();
+ for (int i = 0; i < iFaceNum; i++)
+ {
+ cw_face_res_t faceRet = new cw_face_res_t();
+ faceRet = (cw_face_res_t)Marshal.PtrToStructure(m_buffResult + i * iSize, typeof(cw_face_res_t));
+
+ vecRet.Add(faceRet);
+ }
+ Marshal.FreeHGlobal(srcImg.data);
+ return vecRet;
+ }
+ catch (Exception e)
+ {
+ string error = e.Message;
+ return null;
+ }
+
+ }
+
+ [DllImport("gdi32")]
+ private static extern int DeleteObject(IntPtr o);
+
+ public static BitmapSource ToBitmapSource(Mat mat)
+ {
+ using (System.Drawing.Bitmap source = mat.ToImage().Bitmap)
+ {
+ IntPtr ptr = source.GetHbitmap();
+
+ BitmapSource bs = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
+ ptr,
+ IntPtr.Zero,
+ Int32Rect.Empty,
+ System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
+
+ DeleteObject(ptr);// 閲婃斁鍐呭瓨锛屽惁鍒欏唴瀛樻硠闇
+
+ return bs;
+ }
+ }
+
+ private void Init()
+ {
+ Tb_Score.Text = "";
+ Tb_Result.Text = "";
+ Tb_Time.Text = "";
+ }
+
+ // 缁欑収鐗1瀵煎叆鐓х墖
+ private void OnBtnLoad1(object sender, RoutedEventArgs e)
+ {
+ try
+ {
+ Init();
+
+ System.Windows.Forms.OpenFileDialog ofd = new System.Windows.Forms.OpenFileDialog();
+ if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
+ {
+ m_IMG1Path = ofd.FileName;
+ Bd_Pic1.Background = new ImageBrush(GetBitmapImage(m_IMG1Path));
+ }
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show(ex.Message);
+ }
+ }
+
+ // 缁欑収鐗2瀵煎叆鐓х墖
+ private void OnBtnLoad2(object sender, RoutedEventArgs e)
+ {
+ try
+ {
+ Init();
+
+ System.Windows.Forms.OpenFileDialog ofd = new System.Windows.Forms.OpenFileDialog();
+ if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
+ {
+ m_IMG2Path = ofd.FileName;
+ Bd_Pic2.Background = new ImageBrush(GetBitmapImage(m_IMG2Path));
+ }
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show(ex.Message);
+ }
+ }
+
+ //灞炴ф娴嬪鍏ョ収鐗
+ private void OnBtnLoad(object sender, RoutedEventArgs e)
+ {
+ try
+ {
+ System.Windows.Forms.OpenFileDialog ofd = new System.Windows.Forms.OpenFileDialog();
+ if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
+ {
+ m_IMGAttrPath = ofd.FileName;
+ Bd_Attri_Pic.Background = new ImageBrush(GetBitmapImage(m_IMGAttrPath));
+ }
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show(ex.Message);
+ }
+ }
+
+ // 缁欑収鐗1鎷嶇収
+ private void OnBtnCamera1(object sender, RoutedEventArgs e)
+ {
+ if (!m_bStartThread)
+ {
+ MessageBox.Show("璇峰厛鎵撳紑鎽勫儚澶");
+ return;
+ }
+
+ try
+ {
+ lock (m_lock)
+ {
+ m_IMG1Path = "./1.jpg";
+ CvInvoke.Imwrite(m_IMG1Path, m_matFrame);
+ Bd_Pic1.Background = new ImageBrush(GetBitmapImage(m_IMG1Path));
+ }
+ }
+ catch (Exception exec)
+ {
+ MessageBox.Show(exec.Message);
+ }
+
+ }
+
+ // 缁欑収鐗2鎷嶇収
+ private void OnBtnCamera2(object sender, RoutedEventArgs e)
+ {
+ if (!m_bStartThread)
+ {
+ MessageBox.Show("璇峰厛鎵撳紑鎽勫儚澶");
+ return;
+ }
+
+ try
+ {
+ lock (m_lock)
+ {
+ m_IMG2Path = "./2.jpg";
+ CvInvoke.Imwrite(m_IMG2Path, m_matFrame);
+ Bd_Pic2.Background = new ImageBrush(GetBitmapImage(m_IMG2Path));
+ }
+ }
+ catch (Exception exec)
+ {
+ MessageBox.Show(exec.Message);
+ }
+ }
+
+ // 涓ゅ紶鍥剧墖姣斿
+ private void OnBtnVerify(object sender, RoutedEventArgs e)
+ {
+ if (m_IMG1Path == string.Empty)
+ {
+ MessageBox.Show("璇峰厛閫夋嫨绗竴寮犲浘鐗");
+ return;
+ }
+
+ byte[] bzIMG1 = File.ReadAllBytes(m_IMG1Path);
+ if (bzIMG1 == null || bzIMG1.Length == 0)
+ {
+ MessageBox.Show("璇诲彇绗竴寮犵収鐗囧紓甯");
+ return;
+ }
+
+ if (m_IMG2Path == string.Empty)
+ {
+ MessageBox.Show("璇峰厛閫夋嫨绗簩寮犲浘鐗");
+ return;
+ }
+
+ byte[] bzIMG2 = File.ReadAllBytes(m_IMG2Path);
+ if (bzIMG2 == null || bzIMG2.Length == 0)
+ {
+ MessageBox.Show("璇诲彇绗簩寮犵収鐗囧紓甯");
+ return;
+ }
+
+ if (IntPtr.Zero == m_pDetVerify)
+ {
+ MessageBox.Show("妫娴嬪彞鏌勪负绌猴紝璇峰厛鍒濆鍖栨娴嬪彞鏌");
+ return;
+ }
+ if (IntPtr.Zero == m_pRecog)
+ {
+ MessageBox.Show("璇嗗埆鍙ユ焺涓虹┖锛岃鍏堝垵濮嬪寲璇嗗埆鍙ユ焺");
+ return;
+ }
+
+ try
+ {
+ DateTime dtStart = DateTime.Now;
+
+ int iFeaLen = NativeCWFaceRecognition.cwGetFeatureLength(m_pRecog);
+ byte[] pFea1 = new byte[iFeaLen];
+ string sRet = GetFeatureFromPath(bzIMG1, pFea1);
+ if (null != sRet)
+ {
+ MessageBox.Show("绗竴寮犲浘鐗囧け璐: " + sRet);
+ return;
+ }
+
+ byte[] pFea2 = new byte[iFeaLen];
+ sRet = GetFeatureFromPath(bzIMG2, pFea2);
+ if (null != sRet)
+ {
+ MessageBox.Show("绗簩寮犲浘鐗囧け璐: " + sRet);
+ return;
+ }
+
+ float[] pScores = new float[1];
+ cw_errcode_t errCode = NativeCWFaceRecognition.cwComputeMatchScore(m_pRecog, pFea1, pFea2, 1, pScores);
+ double dTime = (DateTime.Now - dtStart).TotalMilliseconds;
+ ShowResult(errCode, pScores[0], dTime);
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show(ex.Message);
+ }
+ }
+
+ string GetFeatureFromPath(byte[] btImgData, byte[] pFeatueData)
+ {
+ // 缁欏浘鍍忕粨鏋勪綋璧嬪
+ SDK.cw_img_t srcImg = new SDK.cw_img_t();
+ srcImg.data = Marshal.UnsafeAddrOfPinnedArrayElement(btImgData, 0);
+ srcImg.dataLen = btImgData.Length;
+ srcImg.height = 0;
+ srcImg.width = 0;
+ srcImg.format = SDK.cw_img_form_t.CW_IMAGE_BINARY;
+ srcImg.angle = SDK.cw_img_angle_t.CW_IMAGE_ANGLE_0;
+ srcImg.mirror = cw_img_mirror_t.CW_IMAGE_MIRROR_NONE;
+
+ int iSize = Marshal.SizeOf(typeof(cw_face_res_t));
+ if (IntPtr.Zero == m_buffVerify)
+ {
+ m_buffVerify = Marshal.AllocHGlobal(2 * iSize);
+ if (IntPtr.Zero == m_buffVerify)
+ {
+ return null;
+ }
+ }
+
+ int iFaceNum = 0;
+ // 浜鸿劯妫娴嬶紝鑾峰彇瀵归綈浜鸿劯
+ cw_errcode_t errCode = NativeCWFaceDetection.cwFaceDetection(m_pDetVerify, ref srcImg, m_buffVerify, 2, ref iFaceNum,
+ (int)(DetectTrackOperationType.CW_OP_DET | DetectTrackOperationType.CW_OP_ALIGN));
+
+ if (errCode != cw_errcode_t.CW_OK)
+ {
+ return ("Face detect Error, Code: " + errCode.ToString());
+ }
+ if (iFaceNum < 1)
+ {
+ return "No Face Detected";
+ }
+
+ // 鍙栫涓寮犱汉鑴哥殑鏁版嵁
+ cw_face_res_t faceRect = new cw_face_res_t();
+ faceRect = (cw_face_res_t)Marshal.PtrToStructure(m_buffVerify, typeof(cw_face_res_t));
+ errCode = NativeCWFaceRecognition.cwGetFaceFeature(m_pRecog, ref faceRect.faceAligned, pFeatueData);
+ if (cw_errcode_t.CW_OK != errCode)
+ {
+ return ("Get Feature Error: " + errCode.ToString());
+ }
+
+ return null;
+ }
+
+ private BitmapImage GetBitmapImage(string path)
+ {
+ BitmapImage bitmap = new BitmapImage();
+ bitmap.BeginInit();
+
+ bitmap.CacheOption = BitmapCacheOption.OnLoad;
+ bitmap.StreamSource = new MemoryStream(File.ReadAllBytes(path));
+ bitmap.EndInit();
+ bitmap.Freeze();
+ return bitmap;
+ }
+
+ private void ShowResult(cw_errcode_t errCode, float score, double dTime)
+ {
+ Tb_Score.Text = String.Format("{0:F}", score);
+ Tb_Time.Text = String.Format("{0:F} ms", dTime);
+
+ if (cw_errcode_t.CW_OK != errCode)
+ {
+ Tb_Result.Text = "姣斿寮傚父锛岄敊璇爜: " + errCode.ToString();
+ Tb_Result.Foreground = System.Windows.Media.Brushes.Red;
+ Tb_Score.Foreground = System.Windows.Media.Brushes.Red;
+ Tb_Time.Foreground = System.Windows.Media.Brushes.Red;
+ return;
+ }
+
+ if (m_iShrelhod > Convert.ToInt32(100 * score))
+ {
+ Tb_Result.Text = "姣斿涓嶉氳繃";
+ Tb_Result.Foreground = System.Windows.Media.Brushes.Red;
+ Tb_Score.Foreground = System.Windows.Media.Brushes.Red;
+ Tb_Time.Foreground = System.Windows.Media.Brushes.Red;
+ }
+ else
+ {
+ Tb_Result.Text = "姣斿閫氳繃";
+ Tb_Result.Foreground = System.Windows.Media.Brushes.Green;
+ Tb_Score.Foreground = System.Windows.Media.Brushes.Green;
+ Tb_Time.Foreground = System.Windows.Media.Brushes.Green;
+ }
+ }
+
+
+ /****************************************************浜鸿劯灞炴************************************************************/
+ private SDK.cw_errcode_t CreateAttributeHandle()
+ {
+ //鍒涘缓灞炴у彞鏌
+ SDK.cw_errcode_t errCode = cw_errcode_t.CW_OK;
+ m_pRaceAttri = NativeCWFaceAttribute.cwCreateAttributeHandle(out errCode, "../../CWModels/attribute/faceRace/cw_race_config.xml", m_sLicence);
+ if (IntPtr.Zero == m_pRaceAttri || errCode != cw_errcode_t.CW_OK)
+ {
+ MessageBox.Show("浜虹鍙ユ焺鍒涘缓澶辫触锛岄敊璇爜锛" + errCode.ToString());
+ return errCode;
+ }
+
+ m_pAgeAttri = NativeCWFaceAttribute.cwCreateAttributeHandle(out errCode, "../../CWModels/attribute/ageGroup/CWR_Config3.0.xml", m_sLicence);
+ if (IntPtr.Zero == m_pAgeAttri || errCode != cw_errcode_t.CW_OK)
+ {
+ MessageBox.Show("骞撮緞娈靛彞鏌勫垱寤哄け璐ワ紝閿欒鐮侊細" + errCode.ToString());
+ return errCode;
+ }
+
+ m_pGenderAttri = NativeCWFaceAttribute.cwCreateAttributeHandle(out errCode, "../../CWModels/attribute/faceGender/cw_gender_config.xml", m_sLicence);
+ if (IntPtr.Zero == m_pGenderAttri || errCode != cw_errcode_t.CW_OK)
+ {
+ MessageBox.Show("鎬у埆鍙ユ焺鍒涘缓澶辫触锛岄敊璇爜锛" + errCode.ToString());
+ return errCode;
+ }
+
+ return errCode;
+ }
+
+ private void DestroyAttributeHandle()
+ {
+ if (IntPtr.Zero != m_pRaceAttri)
+ {
+ NativeCWFaceAttribute.cwReleaseAttributeHandle(m_pRaceAttri);
+ m_pRaceAttri = IntPtr.Zero;
+ }
+
+ if (IntPtr.Zero != m_pAgeAttri)
+ {
+ NativeCWFaceAttribute.cwReleaseAttributeHandle(m_pAgeAttri);
+ m_pAgeAttri = IntPtr.Zero;
+ }
+
+ if (IntPtr.Zero != m_pGenderAttri)
+ {
+ NativeCWFaceAttribute.cwReleaseAttributeHandle(m_pGenderAttri);
+ m_pGenderAttri = IntPtr.Zero;
+ }
+ }
+ //灞炴
+ private void OnBtnAttribute(object sender, RoutedEventArgs e)
+ {
+ SDK.cw_errcode_t errCode = cw_errcode_t.CW_OK;
+ if ((IntPtr.Zero == m_pAgeAttri) || (IntPtr.Zero == m_pGenderAttri) || (IntPtr.Zero == m_pRaceAttri))
+ {
+ MessageBox.Show("灞炴у彞鏌勫叏涓虹┖锛岃鍏堝垵濮嬪寲鍒涘缓鍙ユ焺");
+ return;
+ }
+ if (m_IMGAttrPath == string.Empty)
+ {
+ MessageBox.Show("璇峰厛閫夋嫨灞炴у浘鐗");
+ return;
+ }
+ try
+ {
+ //璇诲叆鍥剧墖
+ byte[] bzIMG = File.ReadAllBytes(m_IMGAttrPath);
+ if (bzIMG == null || bzIMG.Length == 0)
+ {
+ MessageBox.Show("璇诲彇鐓х墖寮傚父");
+ return;
+ }
+
+ // 缁欏浘鍍忕粨鏋勪綋璧嬪
+ SDK.cw_img_t srcImg = new SDK.cw_img_t();
+ srcImg.data = Marshal.UnsafeAddrOfPinnedArrayElement(bzIMG, 0);
+ srcImg.dataLen = bzIMG.Length;
+ srcImg.height = 0;
+ srcImg.width = 0;
+ srcImg.format = SDK.cw_img_form_t.CW_IMAGE_BINARY;
+ srcImg.angle = SDK.cw_img_angle_t.CW_IMAGE_ANGLE_0;
+ srcImg.mirror = cw_img_mirror_t.CW_IMAGE_MIRROR_NONE;
+
+ int iSize = Marshal.SizeOf(typeof(cw_face_res_t));
+ if (IntPtr.Zero == m_buffVerify)
+ {
+ m_buffVerify = Marshal.AllocHGlobal(2 * iSize);
+ if (IntPtr.Zero == m_buffVerify)
+ {
+ return;
+ }
+ }
+
+ int iFaceNum = 0;
+ // 浜鸿劯妫娴嬶紝鑾峰彇瀵归綈浜鸿劯
+ errCode = NativeCWFaceDetection.cwFaceDetection(m_pDetVerify, ref srcImg, m_buffVerify, 2, ref iFaceNum,
+ (int)(DetectTrackOperationType.CW_OP_DET | DetectTrackOperationType.CW_OP_ALIGN));
+ if (errCode != cw_errcode_t.CW_OK)
+ {
+ MessageBox.Show("Face detect Error, Code: " + errCode.ToString());
+ return;
+ }
+ if (iFaceNum < 1)
+ {
+ MessageBox.Show("No Face Detected");
+ return;
+ }
+
+ // 鍙栫涓寮犱汉鑴哥殑鏁版嵁
+ cw_face_res_t faceRect = new cw_face_res_t();
+ faceRect = (cw_face_res_t)Marshal.PtrToStructure(m_buffVerify, typeof(cw_face_res_t));
+
+ int pAge = 0;
+ errCode = NativeCWFaceAttribute.cwGetAgeEval(m_pAgeAttri, ref faceRect.faceAligned, out pAge);
+ ShowAgeGroupResult(errCode, pAge);
+
+ int pGender = 0;
+ float pGenderConfidence = 0.000F;
+ errCode = NativeCWFaceAttribute.cwGetGenderEval(m_pGenderAttri, ref faceRect.faceAligned, out pGender, out pGenderConfidence);
+ ShowGenderResult(errCode, pGender, pGenderConfidence);
+
+ int pRace = 0;
+ float pRaceConfidence = 0.000F;
+ errCode = NativeCWFaceAttribute.cwGetRaceEval(m_pRaceAttri, ref faceRect.faceAligned, out pRace, out pRaceConfidence);
+ ShowRaceResult(errCode, pRace, pRaceConfidence);
+ }
+
+ catch (Exception ex)
+ {
+ MessageBox.Show(ex.Message);
+ }
+ }
+
+ private void ShowAgeGroupResult(cw_errcode_t errCode, int pAge)
+ {
+ if (cw_errcode_t.CW_OK != errCode)
+ {
+ Attr_Age.Text = "骞撮緞浼拌寮傚父锛岄敊璇爜: " + errCode.ToString();
+ Conf_Age.Text = "0";
+ Attr_Age.Foreground = System.Windows.Media.Brushes.Red;
+ Conf_Age.Foreground = System.Windows.Media.Brushes.Red;
+ return;
+ }
+ else
+ {
+ //if (0 == pAge)
+ //{
+ // Attr_Age.Text = "Children";
+ //}
+ //if (1 == pAge)
+ //{
+ // Attr_Age.Text = "Adult";
+ //}
+ //if (2 == pAge)
+ //{
+ // Attr_Age.Text = "Old";
+ //}
+ Attr_Age.Text = "Age";
+ Attr_Age.Foreground = System.Windows.Media.Brushes.Green;
+ Conf_Age.Text = String.Format("{0:N0}", pAge);
+ Conf_Age.Foreground = System.Windows.Media.Brushes.Green;
+ }
+ }
+
+ private void ShowGenderResult(cw_errcode_t errCode, int pGender, float GenderConfidence)
+ {
+ if (cw_errcode_t.CW_OK != errCode)
+ {
+ Attr_Gender.Text = "鎬у埆浼拌寮傚父锛岄敊璇爜: " + errCode.ToString();
+ Conf_Gender.Text = "0";
+ Attr_Gender.Foreground = System.Windows.Media.Brushes.Red;
+ Conf_Gender.Foreground = System.Windows.Media.Brushes.Red;
+ return;
+ }
+ else
+ {
+ if (0 == pGender)
+ {
+ Attr_Gender.Text = "Female";
+ }
+ else
+ {
+ Attr_Gender.Text = "Male";
+ }
+ Attr_Gender.Foreground = System.Windows.Media.Brushes.Green;
+ Conf_Gender.Text = String.Format("{0:F}", GenderConfidence);
+ Conf_Gender.Foreground = System.Windows.Media.Brushes.Green;
+ }
+ }
+
+ private void ShowRaceResult(cw_errcode_t errCode, int pRace, float RaceConfidence)
+ {
+ if (cw_errcode_t.CW_OK != errCode)
+ {
+ Attr_Race.Text = "浜虹浼拌寮傚父锛岄敊璇爜: " + errCode.ToString();
+ Attr_Race.Foreground = System.Windows.Media.Brushes.Red;
+
+ Conf_Race.Text = "0";
+ Conf_Race.Foreground = System.Windows.Media.Brushes.Red;
+ return;
+ }
+ else
+ {
+ if (0 == pRace)
+ {
+ Attr_Race.Text = "Black";
+ Attr_Race.Foreground = System.Windows.Media.Brushes.Green;
+ }
+ if (1 == pRace)
+ {
+ Attr_Race.Text = "White";
+ Attr_Race.Foreground = System.Windows.Media.Brushes.Green;
+ }
+ if (2 == pRace)
+ {
+ Attr_Race.Text = "Yellow";
+ Attr_Race.Foreground = System.Windows.Media.Brushes.Green;
+ }
+ Conf_Race.Text = String.Format("{0:F}", RaceConfidence);
+ Conf_Race.Foreground = System.Windows.Media.Brushes.Green;
+ }
+ }
+
+ /*****************************************************绾㈠娲讳綋************************************************************/
+ private SDK.cw_nirliveness_err_t CreateNirLivenessHandle()
+ {
+ //鍒涘缓绾㈠娲讳綋鍙ユ焺
+ SDK.cw_nirliveness_err_t errCode = cw_nirliveness_err_t.CW_NIRLIV_OK;
+ string pNirModelPath = "../../CWModels/nirLiveness_model_20181102_pc.bin";
+ string pRecogModelPath = "../../CWModels/hd171019.bin";
+ string pPairFilePath = "../../CWModels/matrix_para640x480.xml";
+ float fskinThread = 0.35f;
+ m_pNirLive = CWFaceNisLiveness.cwCreateNirLivenessHandle(out errCode, pNirModelPath, pRecogModelPath, pPairFilePath, "./log", fskinThread, m_sLicence);
+ if (IntPtr.Zero == m_pNirLive || errCode != cw_nirliveness_err_t.CW_NIRLIV_OK)
+ {
+ MessageBox.Show("绾㈠娲讳綋鍙ユ焺鍒涘缓澶辫触锛岄敊璇爜锛" + errCode.ToString());
+ return errCode;
+ }
+ return errCode;
+ }
+
+ //閿姣佺孩澶栨椿浣撳彞鏌
+ private void DestroyNirLivenessHandle()
+ {
+ if (IntPtr.Zero != m_pNirLive)
+ {
+ CWFaceNisLiveness.cwReleaseNirLivenessHandle(m_pNirLive);
+ m_pNirLive = IntPtr.Zero;
+ }
+ }
+
+ // 绾㈠娲讳綋妫娴
+ private void OnBtnNirLiveness(object sender, RoutedEventArgs e)
+ {
+ if (IntPtr.Zero == m_pDetVerify)
+ {
+ MessageBox.Show("妫娴嬪彞鏌勪负绌猴紝璇峰厛鍒濆鍖栨娴嬪彞鏌");
+ return;
+ }
+ if (IntPtr.Zero == m_pNirLive)
+ {
+ MessageBox.Show("绾㈠娲讳綋妫娴嬪彞鏌勪负绌猴紝璇峰厛鍒濆鍖栫孩澶栨椿浣撳彞鏌");
+ return;
+ }
+
+ if (m_IMG1Path == string.Empty)
+ {
+ MessageBox.Show("璇峰鍏ュ彲瑙佸厜鐓х墖鍥剧墖");
+ return;
+ }
+ byte[] bzIMG1 = File.ReadAllBytes(m_IMG1Path);
+ if (bzIMG1 == null || bzIMG1.Length == 0)
+ {
+ MessageBox.Show("瀵煎叆鍙鍏夌収鐗囧浘鐗囧紓甯");
+ return;
+ }
+
+ if (m_IMG2Path == string.Empty)
+ {
+ MessageBox.Show("瀵煎叆绾㈠鍥剧墖");
+ return;
+ }
+ byte[] bzIMG2 = File.ReadAllBytes(m_IMG2Path);
+ if (bzIMG2 == null || bzIMG2.Length == 0)
+ {
+ MessageBox.Show("瀵煎叆绾㈠鍥剧墖寮傚父");
+ return;
+ }
+
+ // 缁欏彲瑙佸厜鍥惧儚缁撴瀯浣撹祴鍊
+ cw_img_t srcImgVis = new SDK.cw_img_t();
+ //srcImgVis.data = Marshal.UnsafeAddrOfPinnedArrayElement(bzIMG1, 0);
+ srcImgVis.data = Marshal.AllocHGlobal(bzIMG1.Length);
+ Marshal.Copy(bzIMG1, 0, srcImgVis.data, bzIMG1.Length);
+ srcImgVis.dataLen = bzIMG1.Length;
+ srcImgVis.height = 0;
+ srcImgVis.width = 0;
+ srcImgVis.format = SDK.cw_img_form_t.CW_IMAGE_BGR888;
+ srcImgVis.angle = SDK.cw_img_angle_t.CW_IMAGE_ANGLE_0;
+ srcImgVis.mirror = cw_img_mirror_t.CW_IMAGE_MIRROR_NONE;
+
+ // 缁欑孩澶栧浘鍍忕粨鏋勪綋璧嬪
+ cw_img_t srcImgNir = new SDK.cw_img_t();
+ //srcImgNir.data = Marshal.UnsafeAddrOfPinnedArrayElement(bzIMG2, 0);
+ srcImgNir.data = Marshal.AllocHGlobal(bzIMG2.Length);
+ Marshal.Copy(bzIMG2, 0, srcImgNir.data, bzIMG2.Length);
+ srcImgNir.dataLen = bzIMG2.Length;
+ srcImgNir.height = 0;
+ srcImgNir.width = 0;
+ srcImgNir.format = SDK.cw_img_form_t.CW_IMAGE_BGR888;
+ srcImgNir.angle = SDK.cw_img_angle_t.CW_IMAGE_ANGLE_0;
+ srcImgNir.mirror = cw_img_mirror_t.CW_IMAGE_MIRROR_NONE;
+
+ try
+ {
+ DateTime dtStart = DateTime.Now;
+ cw_nirliv_res_t pNisLivenessRes = new cw_nirliv_res_t();
+ cw_nirliveness_err_t nisResCode = CWFaceNisLiveness.cwFaceNirByImageData(m_pDetVerify, m_pNirLive, ref srcImgVis, ref srcImgNir, out pNisLivenessRes);
+ Marshal.FreeHGlobal(srcImgNir.data);
+ Marshal.FreeHGlobal(srcImgVis.data);
+ double dTime = (DateTime.Now - dtStart).TotalMilliseconds;
+ ShowNirResult(nisResCode, pNisLivenessRes.livRst, pNisLivenessRes.score, dTime);
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show(ex.Message);
+ }
+ }
+
+
+ private bool NirLiveness2(Mat mat, Mat mat1)
+ {
+ if (IntPtr.Zero == m_pDetVerify)
+ {
+
+ return false;
+ }
+ if (IntPtr.Zero == m_pNirLive)
+ {
+ return false;
+ }
+
+ //if (m_IMG1Path == string.Empty)
+ //{
+ // return false;
+ //}
+ //byte[] bzIMG1 = File.ReadAllBytes(m_IMG1Path);
+ //if (bzIMG1 == null || bzIMG1.Length == 0)
+ //{
+ // return false;
+ //}
+
+ //if (m_IMG2Path == string.Empty)
+ //{
+ // return false;
+ //}
+ //byte[] bzIMG2 = File.ReadAllBytes(m_IMG2Path);
+ //if (bzIMG2 == null || bzIMG2.Length == 0)
+ //{
+ // return false;
+ //}
+
+
+ cw_img_form_t imgVisFormat = SDK.cw_img_form_t.CW_IMAGE_BINARY;
+ if (mat.NumberOfChannels == 1)
+ {
+ imgVisFormat = cw_img_form_t.CW_IMAGE_GRAY8;
+ }
+ else if (mat.NumberOfChannels == 3)
+ {
+ imgVisFormat = cw_img_form_t.CW_IMAGE_BGR888;
+ }
+ else if (mat.NumberOfChannels == 4)
+ {
+ imgVisFormat = cw_img_form_t.CW_IMAGE_BGRA8888;
+ }
+ else
+ {
+ //MessageBox.Show("杈撳叆鍙鍏夋暟鎹敊璇");
+ return false;
+ }
+
+
+ cw_img_form_t imgNirFormat = SDK.cw_img_form_t.CW_IMAGE_BINARY;
+ if (mat1.NumberOfChannels == 1)
+ {
+ imgNirFormat = cw_img_form_t.CW_IMAGE_GRAY8;
+ }
+ else if (mat1.NumberOfChannels == 3)
+ {
+ imgNirFormat = cw_img_form_t.CW_IMAGE_BGR888;
+ }
+ else if (mat1.NumberOfChannels == 4)
+ {
+ imgNirFormat = cw_img_form_t.CW_IMAGE_BGRA8888;
+ }
+ else
+ {
+ //MessageBox.Show("杈撳叆鍙鍏夋暟鎹敊璇");
+ return false;
+ }
+
+ // 缁欏彲瑙佸厜鍥惧儚缁撴瀯浣撹祴鍊
+ cw_img_t srcImgVis = new SDK.cw_img_t();
+ //srcImgVis.data = Marshal.UnsafeAddrOfPinnedArrayElement(bzIMG1, 0);
+ //srcImgVis.data = Marshal.AllocHGlobal(bzIMG1.Length);
+ //Marshal.Copy(bzIMG1, 0, srcImgVis.data, bzIMG1.Length);
+
+
+ //srcImgVis.data = mat.DataPointer;
+ srcImgVis.dataLen = mat.GetData().Length;
+ byte[] m_btImgBuff = null;
+ //涓嬮潰杩欎袱鍙ワ紝澶歝opy涓娆℃槸蹇呴』鐨勶紝涓嶇劧鍦ㄦ湁鐨勭數鑴戜笂鏈夋姤opencv閿欒
+ if (m_btImgBuff == null || m_btImgBuff.Length < srcImgVis.dataLen)
+ {
+ m_btImgBuff = new byte[srcImgVis.dataLen];
+ if (m_gc.IsAllocated)
+ {
+ m_gc.Free();
+ }
+ m_gc = GCHandle.Alloc(m_btImgBuff, GCHandleType.Pinned);
+ }
+ Array.Copy(mat.GetData(), m_btImgBuff, srcImgVis.dataLen);
+ srcImgVis.data = Marshal.AllocHGlobal(m_btImgBuff.Length);
+ Marshal.Copy(m_btImgBuff, 0, srcImgVis.data, m_btImgBuff.Length);
+ srcImgVis.height = 0;
+ srcImgVis.width = 0;
+ srcImgVis.format = cw_img_form_t.CW_IMAGE_BINARY;
+ srcImgVis.angle = SDK.cw_img_angle_t.CW_IMAGE_ANGLE_0;
+ srcImgVis.mirror = cw_img_mirror_t.CW_IMAGE_MIRROR_NONE;
+
+ // 缁欑孩澶栧浘鍍忕粨鏋勪綋璧嬪
+ cw_img_t srcImgNir = new SDK.cw_img_t();
+ //srcImgNir.data = Marshal.UnsafeAddrOfPinnedArrayElement(bzIMG2, 0);
+ //srcImgNir.data = Marshal.AllocHGlobal(bzIMG2.Length);
+ //Marshal.Copy(bzIMG2, 0, srcImgNir.data, bzIMG2.Length);
+ //srcImgNir.dataLen = bzIMG2.Length;
+
+
+ srcImgNir.dataLen = mat1.GetData().Length;
+ byte[] m_btImgBuff1 = null;
+ //涓嬮潰杩欎袱鍙ワ紝澶歝opy涓娆℃槸蹇呴』鐨勶紝涓嶇劧鍦ㄦ湁鐨勭數鑴戜笂鏈夋姤opencv閿欒
+ if (m_btImgBuff1 == null || m_btImgBuff1.Length < srcImgNir.dataLen)
+ {
+ m_btImgBuff1 = new byte[srcImgNir.dataLen];
+ if (m_gc.IsAllocated)
+ {
+ m_gc.Free();
+ }
+ m_gc = GCHandle.Alloc(m_btImgBuff1, GCHandleType.Pinned);
+ }
+ Array.Copy(mat1.GetData(), m_btImgBuff1, srcImgNir.dataLen);
+ //srcImgNir.data = Marshal.UnsafeAddrOfPinnedArrayElement(m_btImgBuff1, 0);
+ srcImgNir.data = Marshal.AllocHGlobal(m_btImgBuff1.Length);
+ Marshal.Copy(m_btImgBuff1, 0, srcImgNir.data, m_btImgBuff1.Length);
+ srcImgNir.height = 0;
+ srcImgNir.width = 0;
+ srcImgNir.format = cw_img_form_t.CW_IMAGE_BINARY;
+ srcImgNir.angle = SDK.cw_img_angle_t.CW_IMAGE_ANGLE_0;
+ srcImgNir.mirror = cw_img_mirror_t.CW_IMAGE_MIRROR_NONE;
+
+ try
+ {
+ DateTime dtStart = DateTime.Now;
+ cw_nirliv_res_t pNisLivenessRes = new cw_nirliv_res_t();
+ cw_nirliveness_err_t nisResCode = CWFaceNisLiveness.cwFaceNirByImageData(m_pDetVerify, m_pNirLive, ref srcImgVis, ref srcImgNir, out pNisLivenessRes);
+ Marshal.FreeHGlobal(srcImgNir.data);
+ Marshal.FreeHGlobal(srcImgVis.data);
+ double dTime = (DateTime.Now - dtStart).TotalMilliseconds;
+ if (nisResCode == cw_nirliveness_err_t.CW_NIRLIV_OK && pNisLivenessRes.livRst == cw_nirliv_det_rst_t.CW_NIR_LIV_DET_LIVE && pNisLivenessRes.score > 0)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show(ex.Message);
+ }
+ return false;
+ }
+
+
+
+ private bool NirLiveness(Mat mat, Mat mat1)
+ {
+ lock (m_lock)
+ {
+ //byte[] bzIMG1 = new byte[mat.Step * mat.Rows];
+ //Marshal.Copy(mat.DataPointer, bzIMG1, 0, mat.Step * mat.Rows);
+ //byte[] bzIMG2 = new byte[mat1.Step * mat1.Rows];
+ //Marshal.Copy(mat1.DataPointer, bzIMG2, 0, mat1.Step * mat1.Rows);
+
+
+ var m_IMG1Path = "./1.jpg";
+ CvInvoke.Imwrite(m_IMG1Path, mat);
+ byte[] bzIMG1 = File.ReadAllBytes(m_IMG1Path);
+ var m_IMG2Path = "./2.jpg";
+ CvInvoke.Imwrite(m_IMG2Path, mat1);
+ byte[] bzIMG2 = File.ReadAllBytes(m_IMG2Path);
+ if (IntPtr.Zero == m_pDetVerify)
+ {
+ //MessageBox.Show("妫娴嬪彞鏌勪负绌猴紝璇峰厛鍒濆鍖栨娴嬪彞鏌");
+ return false;
+ }
+ if (IntPtr.Zero == m_pNirLive)
+ {
+ // MessageBox.Show("绾㈠娲讳綋妫娴嬪彞鏌勪负绌猴紝璇峰厛鍒濆鍖栫孩澶栨椿浣撳彞鏌");
+ return false;
+ }
+ cw_img_form_t imgVisFormat = SDK.cw_img_form_t.CW_IMAGE_BINARY;
+ if (mat.NumberOfChannels == 1)
+ {
+ imgVisFormat = cw_img_form_t.CW_IMAGE_GRAY8;
+ }
+ else if (mat.NumberOfChannels == 3)
+ {
+ imgVisFormat = cw_img_form_t.CW_IMAGE_BGR888;
+ }
+ else if (mat.NumberOfChannels == 4)
+ {
+ imgVisFormat = cw_img_form_t.CW_IMAGE_BGRA8888;
+ }
+ else
+ {
+ //MessageBox.Show("杈撳叆鍙鍏夋暟鎹敊璇");
+ return false;
+ }
+
+
+ cw_img_form_t imgNirFormat = SDK.cw_img_form_t.CW_IMAGE_BINARY;
+ if (mat1.NumberOfChannels == 1)
+ {
+ imgNirFormat = cw_img_form_t.CW_IMAGE_GRAY8;
+ }
+ else if (mat1.NumberOfChannels == 3)
+ {
+ imgNirFormat = cw_img_form_t.CW_IMAGE_BGR888;
+ }
+ else if (mat1.NumberOfChannels == 4)
+ {
+ imgNirFormat = cw_img_form_t.CW_IMAGE_BGRA8888;
+ }
+ else
+ {
+ // MessageBox.Show("杈撳叆鍙鍏夋暟鎹敊璇");
+ return false;
+ }
+
+
+ //缁欏彲瑙佸厜鍥惧儚缁撴瀯浣撹祴鍊
+ cw_img_t srcImgVis = new SDK.cw_img_t();
+ //srcImgVis.data = Marshal.UnsafeAddrOfPinnedArrayElement(bzIMG1, 0);
+ srcImgVis.data = Marshal.AllocHGlobal(bzIMG1.Length);
+ Marshal.Copy(bzIMG1, 0, srcImgVis.data, bzIMG1.Length);
+ srcImgVis.dataLen = bzIMG1.Length;
+ srcImgVis.height = 0;
+ srcImgVis.width = 0;
+ srcImgVis.format = SDK.cw_img_form_t.CW_IMAGE_BINARY;
+ srcImgVis.angle = SDK.cw_img_angle_t.CW_IMAGE_ANGLE_0;
+ srcImgVis.mirror = cw_img_mirror_t.CW_IMAGE_MIRROR_NONE;
+
+ //缁欑孩澶栧浘鍍忕粨鏋勪綋璧嬪
+ cw_img_t srcImgNir = new SDK.cw_img_t();
+ //srcImgNir.data = Marshal.UnsafeAddrOfPinnedArrayElement(bzIMG2, 0);
+ srcImgNir.data = Marshal.AllocHGlobal(bzIMG2.Length);
+ Marshal.Copy(bzIMG2, 0, srcImgNir.data, bzIMG2.Length);
+ srcImgNir.dataLen = bzIMG2.Length;
+ srcImgNir.height = 0;
+ srcImgNir.width = 0;
+ srcImgNir.format = SDK.cw_img_form_t.CW_IMAGE_BINARY;
+ srcImgNir.angle = SDK.cw_img_angle_t.CW_IMAGE_ANGLE_0;
+ srcImgNir.mirror = cw_img_mirror_t.CW_IMAGE_MIRROR_NONE;
+
+ try
+ {
+ DateTime dtStart = DateTime.Now;
+ cw_nirliv_res_t pNisLivenessRes = new cw_nirliv_res_t();
+ cw_nirliveness_err_t nisResCode = CWFaceNisLiveness.cwFaceNirByImageData(m_pDetVerify, m_pNirLive, ref srcImgVis, ref srcImgNir, out pNisLivenessRes);
+ Marshal.FreeHGlobal(srcImgNir.data);
+ Marshal.FreeHGlobal(srcImgVis.data);
+ double dTime = (DateTime.Now - dtStart).TotalMilliseconds;
+ if (nisResCode == cw_nirliveness_err_t.CW_NIRLIV_OK && pNisLivenessRes.livRst == cw_nirliv_det_rst_t.CW_NIR_LIV_DET_LIVE && pNisLivenessRes.score > 0)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ ShowNirResult(nisResCode, pNisLivenessRes.livRst, pNisLivenessRes.score, dTime);
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show(ex.Message);
+ }
+ return false;
+ }
+ }
+
+
+ private bool NirLiveness1(Mat mat, Mat mat1)
+ {
+ if (IntPtr.Zero == m_pDetVerify1)
+ {
+ //MessageBox.Show("妫娴嬪彞鏌勪负绌猴紝璇峰厛鍒濆鍖栨娴嬪彞鏌");
+ return false;
+ }
+ if (IntPtr.Zero == m_pNirLive)
+ {
+ //MessageBox.Show("绾㈠娲讳綋妫娴嬪彞鏌勪负绌猴紝璇峰厛鍒濆鍖栫孩澶栨椿浣撳彞鏌");
+ return false;
+ }
+ cw_img_form_t imgVisFormat = SDK.cw_img_form_t.CW_IMAGE_BINARY;
+ if (mat.NumberOfChannels == 1)
+ {
+ imgVisFormat = cw_img_form_t.CW_IMAGE_GRAY8;
+ }
+ else if (mat.NumberOfChannels == 3)
+ {
+ imgVisFormat = cw_img_form_t.CW_IMAGE_BGR888;
+ }
+ else if (mat.NumberOfChannels == 4)
+ {
+ imgVisFormat = cw_img_form_t.CW_IMAGE_BGRA8888;
+ }
+ else
+ {
+ //MessageBox.Show("杈撳叆鍙鍏夋暟鎹敊璇");
+ return false;
+ }
+
+
+ cw_img_form_t imgNirFormat = SDK.cw_img_form_t.CW_IMAGE_BINARY;
+ if (mat1.NumberOfChannels == 1)
+ {
+ imgNirFormat = cw_img_form_t.CW_IMAGE_GRAY8;
+ }
+ else if (mat1.NumberOfChannels == 3)
+ {
+ imgNirFormat = cw_img_form_t.CW_IMAGE_BGR888;
+ }
+ else if (mat1.NumberOfChannels == 4)
+ {
+ imgNirFormat = cw_img_form_t.CW_IMAGE_BGRA8888;
+ }
+ else
+ {
+ //MessageBox.Show("杈撳叆鍙鍏夋暟鎹敊璇");
+ return false;
+ }
+ if (m_IMG1Path == string.Empty)
+ {
+ //MessageBox.Show("璇峰鍏ュ彲瑙佸厜鐓х墖鍥剧墖");
+ return false;
+ }
+ byte[] bzIMG1 = File.ReadAllBytes(m_IMG1Path);
+ if (bzIMG1 == null || bzIMG1.Length == 0)
+ {
+ //MessageBox.Show("瀵煎叆鍙鍏夌収鐗囧浘鐗囧紓甯");
+ return false;
+ }
+
+ if (m_IMG2Path == string.Empty)
+ {
+ //MessageBox.Show("瀵煎叆绾㈠鍥剧墖");
+ return false;
+ }
+ byte[] bzIMG2 = File.ReadAllBytes(m_IMG2Path);
+ if (bzIMG2 == null || bzIMG2.Length == 0)
+ {
+ //MessageBox.Show("瀵煎叆绾㈠鍥剧墖寮傚父");
+ return false;
+ }
+
+ // 缁欏彲瑙佸厜鍥惧儚缁撴瀯浣撹祴鍊
+ cw_img_t srcImgVis = new SDK.cw_img_t();
+ //srcImgVis.data = Marshal.UnsafeAddrOfPinnedArrayElement(bzIMG1, 0);
+ srcImgVis.data = Marshal.AllocHGlobal(bzIMG1.Length);
+ Marshal.Copy(bzIMG1, 0, srcImgVis.data, bzIMG1.Length);
+ srcImgVis.dataLen = bzIMG1.Length;
+ //srcImgVis.data = mat.DataPointer;
+ //srcImgVis.dataLen = mat.Step*mat.Rows;
+ srcImgVis.height = 0;
+ srcImgVis.width = 0;
+ srcImgVis.format = imgVisFormat;
+ srcImgVis.angle = SDK.cw_img_angle_t.CW_IMAGE_ANGLE_0;
+ srcImgVis.mirror = cw_img_mirror_t.CW_IMAGE_MIRROR_NONE;
+
+ // 缁欑孩澶栧浘鍍忕粨鏋勪綋璧嬪
+ cw_img_t srcImgNir = new SDK.cw_img_t();
+ //srcImgNir.data = Marshal.UnsafeAddrOfPinnedArrayElement(bzIMG2, 0);
+ srcImgNir.data = Marshal.AllocHGlobal(bzIMG2.Length);
+ Marshal.Copy(bzIMG2, 0, srcImgNir.data, bzIMG2.Length);
+ srcImgNir.dataLen = bzIMG2.Length;
+
+ //srcImgNir.data = mat1.DataPointer;
+ //srcImgNir.dataLen = mat1.Step * mat1.Rows;
+ srcImgNir.height = 0;
+ srcImgNir.width = 0;
+ srcImgNir.format = imgNirFormat;
+ srcImgNir.angle = SDK.cw_img_angle_t.CW_IMAGE_ANGLE_0;
+ srcImgNir.mirror = cw_img_mirror_t.CW_IMAGE_MIRROR_NONE;
+
+ try
+ {
+ DateTime dtStart = DateTime.Now;
+ cw_nirliv_res_t pNisLivenessRes = new cw_nirliv_res_t();
+ cw_nirliveness_err_t nisResCode = CWFaceNisLiveness.cwFaceNirByImageData(m_pDetVerify1, m_pNirLive, ref srcImgVis, ref srcImgNir, out pNisLivenessRes);
+ Marshal.FreeHGlobal(srcImgNir.data);
+ Marshal.FreeHGlobal(srcImgVis.data);
+ double dTime = (DateTime.Now - dtStart).TotalMilliseconds;
+ if (nisResCode == cw_nirliveness_err_t.CW_NIRLIV_OK && pNisLivenessRes.livRst == cw_nirliv_det_rst_t.CW_NIR_LIV_DET_LIVE && pNisLivenessRes.score > 0)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ // ShowNirResult(nisResCode, pNisLivenessRes.livRst, pNisLivenessRes.score, dTime);
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show(ex.Message);
+ }
+ return false;
+ }
+ private void ShowNirResult(cw_nirliveness_err_t errCode, cw_nirliv_det_rst_t ret, float score, double dTime)
+ {
+ Tb_Score.Text = String.Format("{0:F}", score);
+ Tb_Time.Text = String.Format("{0:F} ms", dTime);
+
+ if (cw_nirliveness_err_t.CW_NIRLIV_OK != errCode)
+ {
+ Tb_Result.Text = errCode.ToString();
+ Tb_Result.Foreground = System.Windows.Media.Brushes.Red;
+ Tb_Score.Foreground = System.Windows.Media.Brushes.Red;
+ Tb_Time.Foreground = System.Windows.Media.Brushes.Red;
+ }
+ else
+ {
+ Tb_Result.Text = ret.ToString();
+ Tb_Result.Foreground = System.Windows.Media.Brushes.Green;
+ Tb_Score.Foreground = System.Windows.Media.Brushes.Green;
+ Tb_Time.Foreground = System.Windows.Media.Brushes.Green;
+ }
+ }
+
+ private void OnBtnOpenNirLiveness(object sender, RoutedEventArgs e)
+ {
+
+ isOpenLive = !isOpenLive;
+ if (isOpenLive)
+ {
+ txtOpenLive.Text = "鍏抽棴娲讳綋妫娴";
+ }
+ else
+ {
+ txtOpenLive.Text = "寮鍚椿浣撴娴";
+
+ }
+ maxFace = null;
+ txtFaceLive.Text = "";
+ matList.Clear();
+ }
+ }
+
+}
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/emgu/Emgu.CV.dll b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/emgu/Emgu.CV.dll
new file mode 100644
index 0000000..020fdca
Binary files /dev/null and b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/emgu/Emgu.CV.dll differ
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/emgu/Emgu.Util.dll b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/emgu/Emgu.Util.dll
new file mode 100644
index 0000000..18a38dd
Binary files /dev/null and b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/emgu/Emgu.Util.dll differ
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/emgu/cvextern.dll b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/emgu/cvextern.dll
new file mode 100644
index 0000000..5f87608
Binary files /dev/null and b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/emgu/cvextern.dll differ
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/packages.config b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/packages.config
new file mode 100644
index 0000000..5e2572e
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/packages.config
@@ -0,0 +1,6 @@
+锘
+
+
+
+
+
\ No newline at end of file
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/浣跨敤璇存槑.txt b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/浣跨敤璇存槑.txt
new file mode 100644
index 0000000..2f94cab
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_CSharp/浣跨敤璇存槑.txt
@@ -0,0 +1,4 @@
+1. 建议采取Release配置编译该Demo,因SDK只提供Release版本。
+2. 该Demo使用第三方库emgu,主要用于视频解码,使用时需要将“cvextern.dll”拷贝到运行程序目录。如果编译32位SDK,拷贝“Demo_CSharp/emgu/x86”中的库,如果编译64位SDK,拷贝“Demo_CSharp/emgu/x64”中的库。
+3. SDK算法由VS2012开发,建议客户采取VS2012进行开发。如果无法采用VS2012,也需要安装vc2012运行库。
+4. emgu库“cvextern.dll依赖vc2013,需要安装vc2013运行库。
\ No newline at end of file
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/.classpath b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/.classpath
new file mode 100644
index 0000000..fceb480
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/.classpath
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/.gitignore b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/.gitignore
new file mode 100644
index 0000000..ae3c172
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/.gitignore
@@ -0,0 +1 @@
+/bin/
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/.project b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/.project
new file mode 100644
index 0000000..b59b407
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/.project
@@ -0,0 +1,17 @@
+
+
+ DemoJava
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/.settings/org.eclipse.core.resources.prefs b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..99f26c0
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/=UTF-8
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/.settings/org.eclipse.jdt.core.prefs b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..a698e59
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,12 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/src/CWSDK/FaceAttrRet.java b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/src/CWSDK/FaceAttrRet.java
new file mode 100644
index 0000000..e14018d
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/src/CWSDK/FaceAttrRet.java
@@ -0,0 +1,24 @@
+package CWSDK;
+
+
+public class FaceAttrRet {
+
+ /* *
+ * 骞撮緞娈
+ * 0涓哄皬瀛╋紝1涓烘垚骞翠汉 2涓鸿佷汉
+ *
+ * 鎬у埆
+ * 0涓哄コ澹紝1涓虹敺澹
+ *
+ *
+ * 鏅亶鎰忎箟涓婄殑浜虹 榛戙佺櫧銆侀粍
+ * 0 榛戠浜 1 鐧界浜 2 榛勭浜
+ * */
+ public int m_iValue = 0;
+
+ /* *
+ * 缃俊鍒嗘暟
+ * 涓0--1涔嬮棿鐨勬暟瀛楋紝缃俊鍒嗘暟瓒婇珮锛屼及鍊艰秺鍙潬
+ * */
+ public float m_fConfidence = 0.0f;
+}
\ No newline at end of file
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/src/CWSDK/FaceAttribute.java b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/src/CWSDK/FaceAttribute.java
new file mode 100644
index 0000000..6d8e9b3
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/src/CWSDK/FaceAttribute.java
@@ -0,0 +1,35 @@
+package CWSDK;
+
+
+
+public class FaceAttribute {
+
+ static FaceAttribute attri = null;
+
+ public FaceAttribute() {
+ FaceCommon.loadLibrarys();
+ }
+
+ public static FaceAttribute getInstance() {
+
+ if (null == attri) {
+ attri = new FaceAttribute();
+ }
+ return attri;
+ }
+
+
+ static public native int cwCreateAttributeHandle(String pConfigurePath, String pLicence);
+
+ static public native int cwReleaseAttributeHandle(int pAttributeHandle);
+
+ // 杩斿洖骞撮緞
+ static public native int cwGetAgeEval(int pAttributeHandle, byte[] dataAlign, int iWidth, int iHeight, int iChannels);
+
+ static public native int cwGetGenderEval(int pAttributeHandle, byte[] dataAlign, int iWidth, int iHeight, int iChannels,
+ FaceAttrRet attr);
+
+ static public native int cwGetRaceEval(int pAttributeHandle, byte[] dataAlign, int iWidth, int iHeight, int iChannels,
+ FaceAttrRet attr);
+
+}
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/src/CWSDK/FaceCommon.java b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/src/CWSDK/FaceCommon.java
new file mode 100644
index 0000000..a45c0c9
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/src/CWSDK/FaceCommon.java
@@ -0,0 +1,18 @@
+package CWSDK;
+
+public class FaceCommon {
+
+ private static void loadLibrary(String libraryName) {
+ System.loadLibrary(libraryName);
+ }
+
+ public static void loadLibrarys() {
+ // TODO Auto-generated method stub
+ loadLibrary("DeepNet");
+ loadLibrary("CWFaceDetTrack_CPU_GPU");
+ loadLibrary("CwNirLivDet");
+ loadLibrary("CloudWalkRecog");
+ loadLibrary("CWFaceSDK");
+ loadLibrary("CWFaceSDKJni");
+ }
+}
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/src/CWSDK/FaceDetTrack.java b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/src/CWSDK/FaceDetTrack.java
new file mode 100644
index 0000000..7ecc414
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/src/CWSDK/FaceDetTrack.java
@@ -0,0 +1,42 @@
+package CWSDK;
+
+
+
+public class FaceDetTrack {
+
+ static FaceDetTrack sCJNI = null;
+
+ public FaceDetTrack() {
+ FaceCommon.loadLibrarys();
+ }
+
+ public static FaceDetTrack getInstance() {
+
+ if (null == sCJNI) {
+ sCJNI = new FaceDetTrack();
+ }
+ return sCJNI;
+ }
+
+
+ // 娴滈缚鍔Λ锟藉ù濠糄K
+ static public native int cwCreateDetHandle(String pConfigFile, String pLicence);
+
+ static public native int cwReleaseDetHandle(int pDetector);
+
+ static public native int cwGetFaceParam(int pDetector, FaceParam param);
+
+ static public native int cwSetFaceParam(int pDetector, FaceParam param, String pConfigFile);
+
+ static public native int cwFaceDetection(int pDetector, byte[] pFrameImg,
+ int iWidth,
+ int iHeight,
+ int iFormat,
+ int iAngle,
+ int iMirror,
+ int iOp,
+ FaceInfo[] pFaceBuffer);
+
+ static public native int cwResetDetTrackState(int pDetector);
+
+}
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/src/CWSDK/FaceInfo.java b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/src/CWSDK/FaceInfo.java
new file mode 100644
index 0000000..704a3a6
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/src/CWSDK/FaceInfo.java
@@ -0,0 +1,50 @@
+package CWSDK;
+
+
+
+public class FaceInfo {
+ public FaceInfo()
+ {
+
+ }
+
+ public int detected; // 0: 璺熻釜鍒扮殑浜鸿劯; 1: 妫娴嬪埌鐨勪汉鑴; 2:妫娴嬪埌浣嗕笉浼氳杩涜鍚庣画璁$畻(鍏抽敭鐐)鐨勪汉鑴;
+ // 3: 鍙兘鏄潤鎬佽妫妗嗭紱4:澶ц搴︿汉鑴; 5:鍏抽敭鐐归敊璇; 6:涓嶉渶鍐嶅鐞嗙殑浜鸿劯锛堝彧鏈夋爣璁颁负1鐨勪汉鑴革紝鍏抽敭鐐广
+ // 瀵归綈銆佽川閲忓垎鎵嶆湁鏁堬紱浣嗛櫎0涔嬪鍏朵粬閮藉彲鑳芥湁鍙g僵鍒嗭級7:琚及璁′负浣庤川閲忎汉鑴
+
+ public int trackId; // 浜鸿劯ID锛圛D<0琛ㄧず娌℃湁杩涘叆璺熻釜锛
+
+ // face rect
+ public int x; // 浜鸿劯妗
+ public int y;
+ public int width;
+ public int height;
+
+ // face_point鍏抽敭鐐癸紝鏈澶68涓叧閿偣锛岀洰鍓嶄娇鐢9鐐瑰叧閿偣妯″瀷
+ public float[] keypt_x; // 鍏抽敭鐐箈鍧愭爣
+ public float[] keypt_y; // 鍏抽敭鐐箉鍧愭爣
+ public float keyptScore; // 鍏抽敭鐐瑰緱鍒
+ //鑲よ壊
+
+ // face_aligned
+ public byte[] alignedData; // 瀵归綈浜鸿劯鏁版嵁锛岀敤鏉ユ彁鐗瑰緛
+ public int alignedW;
+ public int alignedH;
+ public int nChannels;
+
+ // face_quality
+ public int errcode; // 璐ㄩ噺鍒嗘瀽閿欒鐮
+ public float[] scores; // 璐ㄩ噺鍒嗗垎鏁伴」锛屽叿浣撳惈涔夛紙鏍规嵁鏁版嵁涓嬫爣椤哄簭锛:
+ /* 0 - 浜鸿劯璐ㄩ噺鎬诲垎锛0.65-1.0
+ * 1 - 娓呮櫚搴︼紝瓒婂ぇ琛ㄧず瓒婃竻鏅帮紝鎺ㄨ崘鑼冨洿0.65-1.0
+ * 2 - 浜害锛岃秺澶ц〃绀鸿秺浜紝鎺ㄨ崘鑼冨洿0.2-0.8
+ * 3 - 浜鸿劯瑙掑害锛屽乏杞负姝o紝鍙宠浆涓鸿礋
+ * 4 - 浜鸿劯瑙掑害锛屾姮澶翠负姝o紝浣庡ご涓鸿礋
+ * 5 - 浜鸿劯瑙掑害锛岄『鏃堕拡涓烘锛岄嗘椂閽堜负璐
+ * 6 - 鑲よ壊鎺ヨ繎鐪熶汉鑲よ壊绋嬪害锛岃秺澶ц〃绀鸿秺鐪熷疄锛屾帹鑽愯寖鍥0.5-1.0
+ * 7 - 鎴撮粦妗嗙溂闀滅疆淇″害锛岃秺澶ц〃绀烘埓榛戞鐪奸暅鐨勫彲鑳芥ц秺澶э紝鎺ㄨ崘鑼冨洿0.0-0.5
+ * 8 - 鎴村ⅷ闀滅殑缃俊鍒嗭紝瓒婂ぇ琛ㄧず鎴村ⅷ闀滅殑鍙兘鎬ц秺澶э紝鎺ㄨ崘鑼冨洿0.0-0.5
+ */
+}
+
+
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/src/CWSDK/FaceInterface.java b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/src/CWSDK/FaceInterface.java
new file mode 100644
index 0000000..0b75cfb
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/src/CWSDK/FaceInterface.java
@@ -0,0 +1,153 @@
+package CWSDK;
+
+
+
+public interface FaceInterface {
+
+ // 鍥惧儚鏍煎紡
+ interface cw_img_form_t extends FaceInterface {
+ int CW_IMAGE_GRAY8 = 0;
+ int CW_IMAGE_BGR888 = 1;
+ int CW_IMAGE_BGRA8888 = 2;
+ int CW_IMAGE_RGB888 = 3;
+ int CW_IMAGE_RGBA8888 = 4;
+ int CW_IMAGE_YUV420P = 5;
+ int CW_IMAGE_YV12 = 6;
+ int CW_IMAGE_NV12 = 7;
+ int CW_IMAGE_NV21 = 8;
+ int CW_IMAGE_BINARY = 9;
+ }
+
+ // 鍥惧儚鏃嬭浆瑙掑害锛堥嗘椂閽堬級
+ interface cw_img_angle_t extends FaceInterface {
+ int CW_IMAGE_ANGLE_0 = 0;
+ int CW_IMAGE_ANGLE_90 = 1;
+ int CW_IMAGE_ANGLE_180 = 2;
+ int CW_IMAGE_ANGLE_270 = 3;
+ }
+
+ // 鍥惧儚闀滃儚
+ interface cw_img_mirror_t extends FaceInterface {
+ int CW_IMAGE_MIRROR_NONE = 0; // 涓嶉暅鍍
+ int CW_IMAGE_MIRROR_HOR = 1; // 姘村钩闀滃儚
+ int CW_IMAGE_MIRROR_VER = 2; // 鍨傜洿闀滃儚
+ int CW_IMAGE_MIRROR_HV = 3; // 鍨傜洿鍜屾按骞抽暅鍍
+ }
+
+
+ // 妫娴嬪紑鍏抽夐」
+ interface cw_op_t extends FaceInterface {
+ int CW_OP_DET = 0; // (1 << 0) 杩涜浜鸿劯妫娴嬶紝骞惰繑鍥炰汉鑴哥煩褰綅缃
+ int CW_OP_TRACK = 2; // (1 << 1)杩涜浜鸿劯璺熻釜锛屽苟杩斿洖浜鸿劯璺熻釜鐨処D
+ int CW_OP_KEYPT = 4; // (1 << 2)杩涜浜鸿劯鍏抽敭鐐规娴嬶紝骞惰繑鍥炰汉鑴镐笂鐨勫叧閿偣鍧愭爣淇℃伅
+ int CW_OP_ALIGN = 8; // (1 << 3)杩涜浜鸿劯鍥惧儚瀵归綈锛屽苟杩斿洖瀵归綈浜鸿劯鏁版嵁锛岀敤鏉ユ彁鐗瑰緛
+ int CW_OP_QUALITY = 16; // (1 << 4)浜鸿劯璐ㄩ噺鍒嗭紙璐ㄩ噺鍒嗗瓙椤瑰紑鍏冲湪閰嶇疆鏂囦欢涓厤缃級
+ int CW_OP_ALL = 30; // 锛堟墍鏈夊紑鍏崇患鍚堬級鎬诲紑鍏
+ }
+
+ // 鐗瑰緛鍙ユ焺鍔熻兘
+ interface cw_recog_pattern_t extends FaceInterface {
+ int CW_FEATURE_EXTRACT = 0;
+ int CW_RECOGNITION = 1;
+ }
+
+ // 閫氱敤閿欒鐮
+ interface cw_errcode_t extends FaceInterface {
+ int CW_SDKLIT_OK = 0; // 鎴愬姛
+
+ int CW_UNKNOWN_ERR = 20000; // 鏈煡閿欒
+ int CW_DETECT_INIT_ERR = 20001; // 鍒濆鍖栦汉鑴告娴嬪櫒澶辫触:濡傚姞杞芥ā鍨嬪け璐ョ瓑
+ int CW_KEYPT_INIT_ERR = 20002; // 鍒濆鍖栧叧閿偣妫娴嬪櫒澶辫触锛氬鍔犺浇妯″瀷澶辫触绛
+ int CW_QUALITY_INIT_ERR = 20003; // 鍒濆鍖栬窡韪櫒澶辫触锛氬鍔犺浇妯″瀷澶辫触绛
+
+ int CW_DET_ERR = 20004; // 妫娴嬪け璐
+ int CW_TRACK_ERR = 20005; // 璺熻釜澶辫触
+ int CW_KEYPT_ERR = 20006; // 鎻愬彇鍏抽敭鐐瑰け璐
+ int CW_ALIGN_ERR = 20007; // 瀵归綈浜鸿劯澶辫触
+ int CW_QUALITY_ERR = 20008; // 璐ㄩ噺璇勪及澶辫触
+
+ int CW_EMPTY_FRAME_ERR = 20009; // 绌哄浘鍍
+ int CW_UNSUPPORT_FORMAT_ERR = 20010; // 鍥惧儚鏍煎紡涓嶆敮鎸
+ int CW_ROI_ERR = 20011; // ROI璁剧疆澶辫触
+ int CW_UNINITIALIZED_ERR = 20012; // 灏氭湭鍒濆鍖
+ int CW_MINMAX_ERR = 20013; // 鏈灏忔渶澶т汉鑴歌缃け璐
+ int CW_OUTOF_RANGE_ERR = 20014; // 鏁版嵁鑼冨洿閿欒
+ int CW_UNAUTHORIZED_ERR = 20015; // 鏈巿鏉
+ int CW_METHOD_UNAVAILABLE = 20016; // 鏂规硶鏃犳晥
+ int CW_PARAM_INVALID = 20017; // 鍙傛暟鏃犳晥
+ int CW_BUFFER_EMPTY = 20018; // 缂撳啿鍖虹┖
+
+ int CW_FILE_UNAVAILABLE = 20019; // 鏂囦欢涓嶅瓨鍦細濡傚姞杞界殑妯″瀷涓嶅瓨鍦ㄧ瓑.
+ int CW_DEVICE_UNAVAILABLE = 20020; // 璁惧涓嶅瓨鍦細濡侴PU绛.
+ int CW_DEVICE_ID_UNAVAILABLE = 20021; // 璁惧id涓嶅瓨鍦細濡侴PU id绛
+ int CW_EXCEEDMAXHANDLE_ERR = 20022; // 瓒呰繃鎺堟潈鏈澶у彞鏌勬暟
+
+ int CW_RECOG_FEATURE_MODEL_ERR = 20023; // 鍔犺浇鐗瑰緛璇嗗埆妯″瀷澶辫触
+ int CW_RECOG_ALIGNEDFACE_ERR = 20024; // 瀵归綈鍥剧墖鏁版嵁閿欒
+ int CW_RECOG_MALLOCMEMORY_ERR = 20025; // 棰勫垎閰嶇壒寰佺┖闂翠笉瓒
+
+ int CW_RECOG_FEATUREDATA_ERR = 20026; // 鐗瑰緛鏁版嵁閿欒
+ int CW_RECOG_EXCEEDMAXFEASPEED = 20027; // 瓒呰繃鎺堟潈鏈澶ф彁鐗瑰緛閫熷害
+ int CW_RECOG_EXCEEDMAXCOMSPEED = 20028; // 瓒呰繃鎺堟潈鏈澶ф瘮瀵归熷害
+ int CW_RECOG_GROUPSIZE_ERR = 20029; // 鐗瑰緛姣斿鐗瑰緛鏁癗瓒呰繃鏈澶ф巿鏉冩暟
+ int CW_RECOG_CONVERT_ERR = 20030; // 鐗瑰緛杞崲澶辫触
+ int CW_RECOG_NOFACEDET = 20031; // 鏈娴嬪埌浜鸿劯
+
+ int CW_LICENCE_JSON_CREATE_ERR = 20032; // Json鎿嶄綔澶辫触
+ int CW_LICENCE_DECRYPT_ERR = 20033; // 鍔犲瘑澶辫触
+ int CW_LICENCE_HTTP_ERROR = 20034; // HTTP澶辫触
+ int CW_LICENCE_MALLOCMEMORY_ERR = 20035; // 鎺堟潈鍐呭瓨鍒嗛厤涓嶈冻
+ int CW_LICENCE_KEY_DEVICE_ERR = 20036; // 鑾峰彇璁惧鏂囦欢閿欒
+ int CW_LICENCE_KEY_LICENSE_ERR = 20037; // 鑾峰彇鎺堟潈鏂囦欢閿欒
+ int CW_LICENCE_KEY_INSTALL_ERR = 20038; // 瀹夎鎺堟潈鏂囦欢閿欒
+
+ int CW_ATTRI_AGEGENDER_MODEL_ERR=20039; //鍔犺浇骞撮緞鎬у埆妯″瀷澶辫触
+ int CW_ATTRI_EVAL_AGE_ERR=20040; //骞撮緞璇嗗埆澶辫触
+ int CW_ATTRI_EVAL_GENDER_ERR=20041; //鎬у埆璇嗗埆澶辫触
+ int CW_ATTRI_EVAL_RACE_ERR=20042; //绉嶆棌璇嗗埆澶辫触
+
+ }
+
+ // 璐ㄩ噺鍒嗘娴嬮敊璇爜
+ interface cw_quality_errcode_t extends FaceInterface {
+ int CW_QUALITY_OK = 0; // 璐ㄩ噺鍒嗘暟鎹湁鏁
+ int CW_QUALITY_NO_DATA = 20150; // 璐ㄩ噺鍒嗘暟鎹棤鏁堬紝鍘熷洜锛氬皻鏈娴
+ int CW_QUALITY_ERROR_UNKNOWN = 20151; // 鏈煡閿欒
+ }
+ // 绾㈠娲讳綋妫娴嬬粨鏋滆繑鍥炲
+ interface cw_nirliv_det_rst_t extends FaceInterface {
+ int CW_NIR_LIV_DET_LIVE = 0; // 浠ラ槇鍊0.5鍒ゆ柇涓烘椿浣
+ int CW_NIR_LIV_DET_UNLIVE = 1; // 浠ラ槇鍊0.5鍒ゆ柇涓洪潪娲讳綋
+ int CW_NIR_LIV_DET_DIST_FAILED = 2; // 浜鸿劯璺濈妫娴嬫湭閫氳繃
+ int CW_NIR_LIV_DET_SKIN_FAILED = 3; // 浜鸿劯鑲よ壊妫娴嬫湭閫氳繃
+ int CW_NIR_LIV_DET_NO_PAIR_FACE = 4; // 鏈尮閰嶅埌浜鸿劯
+ int CW_NIR_LIV_DET_IS_INIT = 5; // 绾㈠娲讳綋妫娴嬬粨鏋滃垵濮嬪
+ }
+
+ // 绾㈠娲讳綋妫娴嬮敊璇爜
+ interface cw_nirliveness_err_t extends FaceInterface {
+ int CW_NIRLIV_OK = 0; // 绾㈠妫娴嬫垚鍔
+
+ int CW_NIRLIV_ERR_CREATE_HANDLE = 26000; // 鍒涘缓绾㈠娲讳綋妫娴嬪彞鏌勫け璐
+ int CW_NIRLIV_ERR_FREE_HANDLE = 26001; // 閲婃斁绾㈠娲讳綋妫娴嬪彞鏌勫け璐
+ int CW_NIRLIV_ERR_FACE_PAIR = 26002; // 浜鸿劯鍖归厤鍒濆鍖栧け璐
+ int CW_NIRLIV_ERR_CREAT_LOG_DIR = 26003; // 鍒涘缓鏃ュ織璺緞澶辫触
+ int CW_NIRLIV_ERR_MODEL_NOTEXIST = 26004; // 杈撳叆妯″瀷涓嶅瓨鍦
+ int CW_NIRLIV_ERR_MODEL_FAILED = 26005; // 杈撳叆妯″瀷鍒濆鍖栧け璐
+ int CW_NIRLIV_ERR_INPUT_UNINIT = 26006; // 杈撳叆鏈垵濮嬪寲
+ int CW_NIRLIV_ERR_NIR_NO_FACE = 26007; // 杈撳叆绾㈠鍥剧墖娌℃湁浜鸿劯
+ int CW_NIRLIV_ERR_VIS_NO_FACE = 26008; // 杈撳叆鍙鍏夊浘鐗囨病鏈変汉鑴
+ int CW_NIRLIV_ERR_NO_PAIR_FACE = 26009; // 杈撳叆鍙鍏夊拰绾㈠鍥剧墖浜鸿劯鏈兘鍖归厤
+ int CW_NIRLIV_ERR_PUSH_DATA = 26010; // 杈撳叆鏁版嵁澶辫触
+ int CW_NIRLIV_ERR_NUM_LANDMARKS = 26011; // 杈撳叆鍙鍏夊浘鐗囧拰绾㈠鍥剧墖鍏抽敭鐐逛釜鏁颁笉绛
+ int CW_NIRLIV_ERR_NO_LANDMARKS = 26012; // 杈撳叆绾㈠鍥剧墖娌℃湁浜鸿劯鍏抽敭鐐
+ int CW_NIRLIV_ERR_INPUT_IMAGE = 26013; // 杈撳叆绾㈠鍥剧墖鎴栬呭彲瑙佸厜鍥剧墖涓嶆槸澶氶氶亾
+ int CW_NIRLIV_ERR_UNAUTHORIZED = 26014; // 娌℃湁license锛堟湭鎺堟潈锛
+ int CW_NIRLIV_ERR_FACE_NUM_ERR = 26015; // 鏈紑鍚汉鑴稿尮閰嶅紑鍏虫椂锛屽彲瑙佸厜鎴栫孩澶栧浘鍍忎汉鑴稿ぇ浜1
+ int CW_NIRLIV_ERR_CAM_UNCW = 26016; // 闈炰簯浠庡畾鍒舵憚鍍忓ご
+ int CW_NIRLIV_ERR_UNKNOWN = 26017; // 鏈煡缁撴灉
+ int CW_NIRLIV_ERR_MAXHANDLE = 26018; // 瓒呰繃鏈澶х孩澶栨椿浣撴渶澶ф巿鏉冨彞鏌勬暟
+ int CW_NIRLIV_ERR_NIRIMAGE = 26019; // 杈撳叆绾㈠鍥剧墖鏁版嵁閿欒
+ int CW_NIRLIV_ERR_VISIMAGE = 26020; // 杈撳叆鍙鍏夊浘鐗囨暟鎹敊璇
+ }
+}
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/src/CWSDK/FaceNisLiveParam.java b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/src/CWSDK/FaceNisLiveParam.java
new file mode 100644
index 0000000..15f236e
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/src/CWSDK/FaceNisLiveParam.java
@@ -0,0 +1,16 @@
+package CWSDK;
+
+
+// 绾㈠妫娴嬭緭鍏ヤ汉鑴稿浘鐗囧弬鏁
+public class FaceNisLiveParam {
+
+ public int nLandmarks; // 浜鸿劯鐨勫叧閿偣涓暟
+ public int nirWidth; // 杈撳叆NIR鍥惧儚瀹
+ public int nirHeight; // 杈撳叆NIR鍥惧儚楂
+ public int nirFormat; // 杈撳叆NIR绾㈠鍥惧儚鏍煎紡
+
+ public int visWidth; // 杈撳叆VIS鍥惧儚瀹
+ public int visHeight; // 杈撳叆VIS鍥惧儚楂
+ public int visFormat; // 杈撳叆VIS鍙鍏夊浘鍍忔牸寮
+
+}
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/src/CWSDK/FaceNisLiveResInfo.java b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/src/CWSDK/FaceNisLiveResInfo.java
new file mode 100644
index 0000000..c8956e5
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/src/CWSDK/FaceNisLiveResInfo.java
@@ -0,0 +1,14 @@
+package CWSDK;
+
+
+// 浜鸿劯绾㈠妫娴嬭緭鍑虹殑鍙鍏変汉鑴告椿浣撲俊鎭
+public class FaceNisLiveResInfo {
+ public FaceNisLiveResInfo()
+ {
+
+ }
+
+ public int livRst; // 鏄惁涓烘椿浣撴垨妫娴嬭繃绋嬩腑鐨勭浉鍏抽敊璇爜
+
+ public float score; // 绾㈠娲讳綋妫娴嬪緱鍒
+}
\ No newline at end of file
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/src/CWSDK/FaceNisLiveness.java b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/src/CWSDK/FaceNisLiveness.java
new file mode 100644
index 0000000..aaaf22d
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/src/CWSDK/FaceNisLiveness.java
@@ -0,0 +1,34 @@
+package CWSDK;
+
+public class FaceNisLiveness {
+
+ static FaceNisLiveness nirLive = null;
+
+ public FaceNisLiveness() {
+ FaceCommon.loadLibrarys();
+ }
+
+ public static FaceNisLiveness getInstance() {
+
+ if (null == nirLive) {
+ nirLive = new FaceNisLiveness();
+ }
+ return nirLive;
+ }
+
+ // 浜鸿劯绾㈠妫娴婼DK鍘熷鎺ュ彛
+ static public native int cwCreateNirLivenessHandle(String pNirModelPath,
+ String pRecogModelPath,
+ String pPairFilePath,
+ String pLogPath,
+ float fSkinThresh,
+ String pLicence);
+
+ static public native int cwReleaseNirLivenessHandle(int pHandle);
+
+ static public native int cwFaceNirLivenessDet(int pHandle, FaceNisLiveParam pLivenessDetInfo,
+ byte[] pVisData, float visSkinScore, float visKeyPtScore, float[] visKeypt_x, float[] visKeypt_y,
+ byte[] pNirData, float nirSkinScore, float nirKeyPtScore,float[] nirKeypt_x, float[] nirKeypt_y,
+ FaceNisLiveResInfo pNirLivenessRes);
+
+}
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/src/CWSDK/FaceParam.java b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/src/CWSDK/FaceParam.java
new file mode 100644
index 0000000..af238c1
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/src/CWSDK/FaceParam.java
@@ -0,0 +1,21 @@
+package CWSDK;
+
+
+public class FaceParam {
+ /**
+ * roi鍖哄煙璁剧疆, 榛樿鏁村抚鍥惧儚
+ **/
+ public int roiX;
+ public int roiY;
+ public int roiWidth;
+ public int roiHeight;
+ /**
+ * 浜鸿劯灏哄鑼冨洿-鏈灏忓昂瀵革紝榛樿100
+ **/
+ public int minSize;
+ /**
+ * 浜鸿劯灏哄鑼冨洿-鏈澶у昂瀵革紝榛樿400
+ **/
+ public int maxSize;
+
+}
\ No newline at end of file
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/src/CWSDK/FaceRecog.java b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/src/CWSDK/FaceRecog.java
new file mode 100644
index 0000000..5a4acc4
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/src/CWSDK/FaceRecog.java
@@ -0,0 +1,35 @@
+package CWSDK;
+
+
+
+public class FaceRecog {
+
+ static FaceRecog recog = null;
+
+ public FaceRecog() {
+ FaceCommon.loadLibrarys();
+ }
+
+ public static FaceRecog getInstance() {
+
+ if (null == recog) {
+ recog = new FaceRecog();
+ }
+ return recog;
+ }
+
+
+ // 浜鸿劯鐗瑰緛璇嗗埆SDK
+ static public native int cwCreateRecogHandle(String pConfigurePath,
+ String pLicence,
+ int emRecogPattern);
+
+ static public native int cwReleaseRecogHandle(int pRecogHandle);
+
+ static public native int cwGetFeatureLength(int pRecogHandle);
+
+ static public native int cwGetFaceFeature(int pRecogHandle, byte[] dataAlign, int iWidth, int iHeight, int iChannels, byte[] pFeatureData);
+
+ static public native int cwComputeMatchScore(int pRecogHandle, byte[] pFeaProbe, byte[] pFeaFiled, int iFeaFiledNum, float[] pScores);
+
+}
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/src/CWSDK/FaceVersion.java b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/src/CWSDK/FaceVersion.java
new file mode 100644
index 0000000..32f6ef7
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/src/CWSDK/FaceVersion.java
@@ -0,0 +1,27 @@
+package CWSDK;
+
+
+
+public class FaceVersion {
+
+ static FaceVersion version = null;
+
+ public FaceVersion() {
+ FaceCommon.loadLibrarys();
+ }
+
+ public static FaceVersion getInstance() {
+
+ if (null == version) {
+ version = new FaceVersion();
+ }
+ return version;
+ }
+
+ static public native String cwGetSDKVersion();
+
+ static public native String cwGetDeviceInfo();
+
+ static public native int cwInstallLicence(String sAppKey, String sSecret, String sProductId);
+
+}
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/src/SDKDemo/SDKDemo.java b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/src/SDKDemo/SDKDemo.java
new file mode 100644
index 0000000..d1147be
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava/src/SDKDemo/SDKDemo.java
@@ -0,0 +1,637 @@
+package SDKDemo;
+
+import java.awt.List;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Scanner;
+
+import javax.lang.model.element.NestingKind;
+
+import CWSDK.FaceAttrRet;
+import CWSDK.FaceAttribute;
+import CWSDK.FaceVersion;
+import CWSDK.FaceDetTrack;
+import CWSDK.FaceRecog;
+import CWSDK.FaceInterface;
+import CWSDK.FaceParam;
+import CWSDK.FaceInfo;
+import CWSDK.FaceNisLiveParam;
+import CWSDK.FaceNisLiveResInfo;
+import CWSDK.FaceNirLivBean;
+import CWSDK.NisLiveBean;
+import CWSDK.FaceNisLiveness;
+
+// Lit 20170822
+public class SDKDemo {
+
+ public static final int ERRCODE_MIN = FaceInterface.cw_errcode_t.CW_UNKNOWN_ERR;
+ public final int MAX_FACE_NUM = 20;
+
+ FaceDetTrack mDet;
+ FaceRecog mRecog;
+ FaceVersion mVer;
+ FaceAttribute mAttri;
+ FaceNisLiveness mNir;
+
+ int m_detHandle = ERRCODE_MIN; // 妫娴嬪彞鏌
+ int m_recogHandle = ERRCODE_MIN; // 璇嗗埆鍙ユ焺
+
+ int m_ageHandle = ERRCODE_MIN; // 骞撮緞灞炴у彞鏌
+ int m_genderHandle = ERRCODE_MIN; // 鎬у埆灞炴у彞鏌
+ int m_raceHandle = ERRCODE_MIN; // 绉嶆棌灞炴у彞鏌
+
+ int m_NirLivnessHandle = ERRCODE_MIN; // 绾㈠娲讳綋妫娴嬪彞鏌
+
+ String m_cwLicence = "";
+
+ public static void main(String[] args) {
+ //TODO Auto-generated method stub
+ SDKDemo demo = new SDKDemo();
+ if (!demo.InitSDK()) { // 鍒涘缓鍙ユ焺
+ demo.CloseSDK();
+ return;
+ }
+
+ System.out.println("鍒濆鍖栨垚鍔");
+
+ System.out.println("demo type:");
+ System.out.println("1 Face Detect");
+ System.out.println("2 Face Quality");
+ System.out.println("3 Face Verify");
+ System.out.println("4 Face Recognition");
+ System.out.println("5 Face Attribute");
+ System.out.println("6 Face NirLiveness");
+ System.out.println("7 Exit");
+
+ System.out.println("Please Input Type: ");
+ Scanner scan = new Scanner(System.in);
+ int iDemoType = scan.nextInt();
+ switch (iDemoType) {
+ case 1:
+ demo.DemoFaceDet();
+ break;
+ case 2:
+ demo.DemoFaceQuality();
+ break;
+ case 3:
+ demo.DemoFaceVevify();
+ break;
+ case 4:
+ demo.DemoFaceRecog();
+ break;
+ case 5:
+ demo.DemoFaceAttribute();
+ break;
+ case 6:
+ demo.DemoFaceNirLiveness();
+ default:
+ break;
+ }
+
+ demo.CloseSDK(); // 閿姣佸彞鏌
+ System.out.println("\nDemo鎵ц缁撴潫");
+ }
+
+ @SuppressWarnings("static-access")
+ private Boolean InitSDK() {
+
+ mDet = FaceDetTrack.getInstance();
+ mRecog = FaceRecog.getInstance();
+ mVer = FaceVersion.getInstance();
+ mAttri = FaceAttribute.getInstance();
+ mNir = FaceNisLiveness.getInstance();
+
+ String sVersion = mVer.cwGetSDKVersion();
+ System.out.println("SDK Verison: " + sVersion);
+
+ // 鍒涘缓妫娴嬪彞鏌
+ String sModelFolder = getRootPath(); // CWModels鏂囦欢澶硅矾寰
+ // 32浣嶅拰64浣嶆娴嬫ā鍨嬩笉鑳藉叡鐢紝64浣嶇敤_configs_frontend.xml锛岄潪64浣嶇敤_configs_frontend_x86_arm.xml
+ String sDetModel = sModelFolder + "/_configs_frontend.xml";
+ m_detHandle = mDet.cwCreateDetHandle(sDetModel, m_cwLicence);
+ if (m_detHandle >= ERRCODE_MIN) {
+ System.out.println("鍒涘缓妫娴嬪彞鏌勫け璐ワ紝閿欒鐮侊細" + m_detHandle);
+ return false;
+ }
+
+ // 璁剧疆妫娴嬪弬鏁
+ FaceParam mFaceParam = new FaceParam();
+ mDet.cwGetFaceParam(m_detHandle,mFaceParam);
+ mFaceParam.minSize = 48; // 鏈灏忎汉鑴
+ mFaceParam.maxSize = 600; //鏈澶т汉鑴
+ mDet.cwSetFaceParam(m_detHandle, mFaceParam, sDetModel);
+
+ // 鍒涘缓璇嗗埆鍙ユ焺
+ m_recogHandle = mRecog.cwCreateRecogHandle(sModelFolder + "/CWR_Config_1_1.xml", m_cwLicence, FaceInterface.cw_recog_pattern_t.CW_FEATURE_EXTRACT);
+ if (m_recogHandle >= ERRCODE_MIN) {
+ System.out.println("鍒涘缓璇嗗埆鍙ユ焺澶辫触锛岄敊璇爜锛" + m_recogHandle);
+ return false;
+ }
+
+ // 鍒涘缓灞炴у彞鏌勶紝濡備笉浣跨敤灞炴э紝涓嶈鍒涘缓璇ュ彞鏌
+ m_ageHandle = mAttri.cwCreateAttributeHandle(sModelFolder + "/attribute/ageGroup/cw_age_group_config.xml", m_cwLicence);
+ if (m_ageHandle >= ERRCODE_MIN) {
+ System.out.println("鍒涘缓骞撮緞灞炴у彞鏌勫け璐ワ紝閿欒鐮侊細" + m_ageHandle);
+ return false;
+ }
+
+ m_genderHandle = mAttri.cwCreateAttributeHandle(sModelFolder + "/attribute/faceGender/cw_gender_config.xml", m_cwLicence);
+ if (m_genderHandle >= ERRCODE_MIN) {
+ System.out.println("鍒涘缓鎬у埆灞炴у彞鏌勫け璐ワ紝閿欒鐮侊細" + m_genderHandle);
+ return false;
+ }
+
+ m_raceHandle = mAttri.cwCreateAttributeHandle(sModelFolder + "/attribute/faceRace/cw_race_config.xml", m_cwLicence);
+ if (m_raceHandle >= ERRCODE_MIN) {
+ System.out.println("鍒涘缓绉嶆棌灞炴у彞鏌勫け璐ワ紝閿欒鐮侊細" + m_raceHandle);
+ return false;
+ }
+ //鍒涘缓绾㈠娲讳綋妫娴嬪彞鏌
+ String pNirModelPath = sModelFolder + "/nirLiveness_model_20181102_pc.bin";
+ String pRecogModelPath = sModelFolder + "/hd171019.bin";
+ String pPairFilePath = sModelFolder + "/matrix_para480x640.xml";
+ String pLogPath = "./log";
+ float fSkinThresh = 0.35f;
+ System.out.println("杩涘叆SDK\n");
+ m_NirLivnessHandle = mNir.cwCreateNirLivenessHandle(pNirModelPath, pRecogModelPath, pPairFilePath,pLogPath,fSkinThresh, m_cwLicence);
+ if (m_NirLivnessHandle >= ERRCODE_MIN) {
+ System.out.println("鍒涘缓绾㈠娲讳綋妫娴嬪彞鏌勫け璐ワ紝閿欒鐮侊細" + m_NirLivnessHandle);
+ return false;
+ }
+
+ return true;
+ }
+
+ private void CloseSDK() {
+ // 绋嬪簭閫鍑烘椂锛岄攢姣佸彞鏌
+ if (m_detHandle < ERRCODE_MIN) {
+ mDet.cwReleaseDetHandle(m_detHandle);
+ }
+
+ if (m_recogHandle < ERRCODE_MIN) {
+ mRecog.cwReleaseRecogHandle(m_recogHandle);
+ }
+ if (m_ageHandle < ERRCODE_MIN) {
+ mAttri.cwReleaseAttributeHandle(m_ageHandle);
+ }
+ if (m_genderHandle < ERRCODE_MIN) {
+ mAttri.cwReleaseAttributeHandle(m_genderHandle);
+ }
+ if (m_raceHandle < ERRCODE_MIN) {
+ mAttri.cwReleaseAttributeHandle(m_raceHandle);
+ }
+ if (m_NirLivnessHandle < ERRCODE_MIN) {
+ mNir.cwReleaseNirLivenessHandle(m_NirLivnessHandle);
+ }
+ }
+
+ // 浜鸿劯妫娴婦emo
+ private void DemoFaceDet() {
+
+ System.out.print("Please Input Pic Path: ");
+ Scanner scan = new Scanner(System.in);
+ String sPicPath = scan.nextLine();
+ System.out.println(sPicPath);
+
+ byte[] imgData = null;
+ try {
+ imgData = file2byte(new File(sPicPath));
+ } catch (Exception e) {
+ // e.printStackTrace();
+ }
+
+ if (imgData == null || imgData.length < 1) {
+ System.out.println("鍥剧墖涓虹┖");
+ return;
+ }
+
+ FaceInfo[] faceBuffers = new FaceInfo[MAX_FACE_NUM];
+ for (int i = 0; i < MAX_FACE_NUM; i++) {
+ faceBuffers[i] = new FaceInfo();
+ }
+ // m_detHandle, imgData, 0, 0, FaceInterface.cw_img_form_t.CW_IMAGE_BINARY, 0,
+ // 0,
+ // FaceInterface.cw_op_t.CW_OP_DET, faceBuffers
+ int faceNum = mDet.cwFaceDetection(m_detHandle, imgData, 0, 0, FaceInterface.cw_img_form_t.CW_IMAGE_BINARY, 0,
+ 0, FaceInterface.cw_op_t.CW_OP_DET, faceBuffers);
+ if (faceNum >= ERRCODE_MIN) {
+ System.out.println("妫娴嬪け璐ワ紝閿欒鐮侊細" + faceNum); // 妫娴嬪紓甯
+ } else if (faceNum < 1) {
+ System.out.println("鏈娴嬪埌浜鸿劯"); // 鏈娴嬪埌浜鸿劯
+ } else {
+ System.out.println("Face Num: " + faceNum);
+ // 杈撳嚭浜鸿劯浣嶇疆
+ for (int i = 0; i < faceNum; i++) {
+ System.out.println("Face" + (i + 1) + ": Pos: " + faceBuffers[i].x + "," + faceBuffers[i].y + ","
+ + faceBuffers[i].width + "," + faceBuffers[i].height);
+ }
+ }
+
+ System.out.println("\nFace Detect Completely");
+ }
+
+ // 浜鸿劯璐ㄩ噺Demo
+ private void DemoFaceQuality() {
+ System.out.print("Please Input Pic Path: ");
+ Scanner scan = new Scanner(System.in);
+ String sPicPath = scan.nextLine();
+ System.out.println(sPicPath);
+
+ byte[] imgData = null;
+ try {
+ imgData = file2byte(new File(sPicPath));
+ } catch (Exception e) {
+ // e.printStackTrace();
+ }
+
+ if (imgData == null || imgData.length < 1) {
+ System.out.println("鍥剧墖涓虹┖");
+ return;
+ }
+
+ FaceInfo[] faceBuffers = new FaceInfo[MAX_FACE_NUM];
+ for (int i = 0; i < MAX_FACE_NUM; i++) {
+ faceBuffers[i] = new FaceInfo();
+ }
+ // 鍔犱笂璐ㄩ噺鍒嗗紑鍏矯W_OP_QUALITY
+ int faceNum = mDet.cwFaceDetection(m_detHandle, imgData, 0, 0, FaceInterface.cw_img_form_t.CW_IMAGE_BINARY, 0,
+ 0, FaceInterface.cw_op_t.CW_OP_DET | FaceInterface.cw_op_t.CW_OP_QUALITY, faceBuffers);
+ if (faceNum >= ERRCODE_MIN) {
+ System.out.println("妫娴嬪け璐ワ紝閿欒鐮侊細" + faceNum); // 妫娴嬪紓甯
+ } else if (faceNum < 1) {
+ System.out.println("鏈娴嬪埌浜鸿劯"); // 鏈娴嬪埌浜鸿劯
+ } else {
+ System.out.println("Face Num: " + faceNum);
+ // 杈撳嚭浜鸿劯浣嶇疆
+ for (int i = 0; i < faceNum; i++) {
+ int errQuality = faceBuffers[i].errcode;
+ if (errQuality == FaceInterface.cw_quality_errcode_t.CW_QUALITY_OK) {
+ System.out.println("Face" + (i + 1) + ": Pos: " + faceBuffers[i].x + "," + faceBuffers[i].y + ","
+ + faceBuffers[i].width + "," + faceBuffers[i].height + " Quality Score: "
+ + faceBuffers[i].scores[0]);
+ } else {
+ System.out.println("Face" + (i + 1) + ": Pos: " + faceBuffers[i].x + "," + faceBuffers[i].y + ","
+ + faceBuffers[i].width + "," + faceBuffers[i].height + " Quality Err: " + errQuality);
+ }
+ }
+ }
+
+ System.out.println("\nFace Quality Completely");
+ }
+
+ // 浜鸿劯姣斿Demo(1:1)
+ private void DemoFaceVevify() {
+ System.out.print("Please Input Pic Path1: ");
+ Scanner scan = new Scanner(System.in);
+ String sPicPath1 = scan.nextLine();
+
+ System.out.print("Please Input Pic Path2: ");
+ String sPicPath2 = scan.nextLine();
+
+ byte[] feaFace1 = GetFeatureFromPicPath(sPicPath1);
+ if (feaFace1 == null) {
+ System.out.println(sPicPath1 + " 鎻愮壒寰佸け璐");
+ return;
+ }
+
+ byte[] feaFace2 = GetFeatureFromPicPath(sPicPath2);
+ if (feaFace2 == null) {
+ System.out.println(sPicPath2 + " 鎻愮壒寰佸け璐");
+ return;
+ }
+
+ int iFeaLen = mRecog.cwGetFeatureLength(m_recogHandle);
+ float[] pScores = new float[1];
+ int errCode = mRecog.cwComputeMatchScore(m_recogHandle, feaFace1, feaFace2, 1, pScores);
+ if (errCode != FaceInterface.cw_errcode_t.CW_SDKLIT_OK) {
+ System.out.println("Verify Error: " + errCode);
+ return;
+ }
+
+ System.out.println("Verify Score: " + pScores[0]);
+ System.out.println("\nFace Verify Completely");
+ }
+
+ // 浜鸿劯璇嗗埆Demo(1:n)
+ private void DemoFaceRecog() {
+
+ System.out.print("Please Input Pic Path1: ");
+ Scanner scan = new Scanner(System.in);
+ String sPicPath1 = scan.nextLine();
+
+ System.out.print("Please Input Pic Path2: ");
+ String sPicPath2 = scan.nextLine();
+
+ byte[] feaFace1 = GetFeatureFromPicPath(sPicPath1);
+ if (feaFace1 == null) {
+ System.out.println(sPicPath1 + " 鎻愮壒寰佷汉鑴哥壒寰佸け璐");
+ return;
+ }
+ byte[] feaFace2 = GetFeatureFromPicPath(sPicPath2);
+ if (feaFace2 == null) {
+ System.out.println(sPicPath2 + " 鎻愮壒寰丗iled澶辫触");
+ return;
+ }
+ // 灏2涓猣iled鐗瑰緛缁勫悎鍒颁竴璧
+ int iFeaLen = mRecog.cwGetFeatureLength(m_recogHandle);
+ byte[] feaFiledAll = new byte[2 * iFeaLen];
+ System.arraycopy(feaFace1, 0, feaFiledAll, 0, iFeaLen);
+ System.arraycopy(feaFace2, 0, feaFiledAll, iFeaLen, iFeaLen);
+
+ // 1:2璇嗗埆
+ float[] pScores = new float[2];
+ int errCode = mRecog.cwComputeMatchScore(m_recogHandle, feaFace1, feaFiledAll, 2, pScores);
+ if (errCode != FaceInterface.cw_errcode_t.CW_SDKLIT_OK) {
+ System.out.println("Recog Error: " + errCode);
+ return;
+ }
+
+ System.out.println("Recog Score: \n" + pScores[0] + "\n" + pScores[1]);
+ System.out.println("\nFace Recognise Completely");
+ }
+
+ // 浜鸿劯灞炴ц瘑鍒玠emo
+ private void DemoFaceAttribute() {
+ System.out.print("Please Input Attribute Pic Path: ");
+ Scanner scan = new Scanner(System.in);
+ String sPicPath = scan.nextLine();
+
+ byte[] imgData = null;
+ try {
+ imgData = file2byte(new File(sPicPath));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ if (imgData == null || imgData.length < 1) {
+ System.out.println("鍥剧墖涓虹┖");
+ return;
+ }
+
+ FaceInfo[] faceBuffers = new FaceInfo[MAX_FACE_NUM];
+ for (int i = 0; i < MAX_FACE_NUM; i++) {
+ faceBuffers[i] = new FaceInfo();
+ }
+ // 鍔犱笂浜鸿劯瀵归綈寮鍏矯W_OP_ALIGN锛岀敤瀵归綈鏁版嵁鏉ユ彁鐗瑰緛
+ int faceNum = mDet.cwFaceDetection(m_detHandle, imgData, 0, 0, FaceInterface.cw_img_form_t.CW_IMAGE_BINARY, 0,
+ 0, FaceInterface.cw_op_t.CW_OP_DET | FaceInterface.cw_op_t.CW_OP_ALIGN, faceBuffers);
+ if (faceNum >= ERRCODE_MIN) {
+ System.out.println("妫娴嬪け璐ワ紝閿欒鐮侊細" + faceNum); // 妫娴嬪紓甯
+ return;
+ } else if (faceNum < 1) {
+ System.out.println("鏈娴嬪埌浜鸿劯"); // 鏈娴嬪埌浜鸿劯
+ return;
+ }
+
+ int errCode = FaceInterface.cw_errcode_t.CW_SDKLIT_OK;
+ for (int i = 0; i < faceNum; i++) {
+
+ FaceAttrRet attrAge = new FaceAttrRet();
+ int Age = mAttri.cwGetAgeEval(m_ageHandle, faceBuffers[i].alignedData, faceBuffers[i].alignedW, faceBuffers[i].alignedH, faceBuffers[i].nChannels);
+ System.out.println("Face " + (i + 1) + " Age: " + Age);
+
+ FaceAttrRet attrGen = new FaceAttrRet();
+ errCode = mAttri.cwGetGenderEval(m_genderHandle, faceBuffers[i].alignedData, faceBuffers[i].alignedW,
+ faceBuffers[i].alignedH, faceBuffers[i].nChannels, attrGen);
+ if (errCode == FaceInterface.cw_errcode_t.CW_SDKLIT_OK) {
+ System.out.println(
+ "Face " + (i + 1) + " Gender: " + attrGen.m_iValue + ", GenderConfidence: " + attrGen.m_fConfidence);
+ } else {
+ System.out.println("Face " + (i + 1) + " Attribute Error锛" + errCode);
+ return;
+ }
+
+ FaceAttrRet attrRace = new FaceAttrRet();
+ errCode = mAttri.cwGetRaceEval(m_raceHandle, faceBuffers[i].alignedData, faceBuffers[i].alignedW,
+ faceBuffers[i].alignedH, faceBuffers[i].nChannels, attrRace);
+ if (errCode == FaceInterface.cw_errcode_t.CW_SDKLIT_OK) {
+ System.out.println(
+ "Face " + (i + 1) + " Race: " + attrRace.m_iValue + ", RaceConfidence: " + attrRace.m_fConfidence);
+ } else {
+ System.out.println("Face " + (i + 1) + " Attribute Error锛" + errCode);
+ return;
+ }
+ System.out.println("");
+ }
+
+ System.out.println("\nFace Recognise Completely");
+ }
+
+ // 绾㈠娲讳綋妫娴婦emo
+ private void DemoFaceNirLiveness() {
+ Scanner scan = new Scanner(System.in);
+ System.out.print("Please Input Vis Pic Path: ");
+ String sPicPathVis = scan.nextLine();
+
+ System.out.print("Please Input Nir Pic Path: ");
+ String sPicPathNis = scan.nextLine();
+
+ // 鍙鍏夊浘鐗
+ byte[] imgDataVis = null;
+ try {
+ imgDataVis = file2byte(new File(sPicPathVis));
+ } catch (Exception e) {
+ // e.printStackTrace();
+ }
+ if (imgDataVis == null || imgDataVis.length < 1) {
+ System.out.println("鍙鍏夊浘鐗囦负绌");
+ return;
+ }
+
+ // 绾㈠鍥剧墖
+ byte[] imgDataNir = null;
+ try {
+ imgDataNir = file2byte(new File(sPicPathNis));
+ } catch (Exception e) {
+ // e.printStackTrace();
+ }
+ if (imgDataNir == null || imgDataNir.length < 1) {
+ System.out.println("绾㈠鍥剧墖涓虹┖");
+ return;
+ }
+
+ NisLiveBean nirRet = new NisLiveBean();
+ //鍙鍏変汉鑴哥収鐗囨娴
+ FaceInfo nirRetInfo = new FaceInfo();
+ FaceNirLivBean detBeanNir = GetFaceInfoByImgData(m_detHandle, imgDataNir);
+ if (detBeanNir.ret != 0) {
+ nirRet.ret = detBeanNir.ret;
+ return;
+ } else {
+ if (detBeanNir.faceNum < 1)
+ {
+ nirRet.ret = FaceInterface.cw_nirliveness_err_t.CW_NIRLIV_ERR_NIR_NO_FACE;
+ System.out.println("鍙鍏夋娴嬪け璐 ");
+ return;
+ }
+ }
+ //绾㈠浜鸿劯鐓х墖妫娴,鍙彇绗竴涓汉鑴
+ int iKeyPtNum = detBeanNir.faceInfos[0].keypt_y.length;
+ float[] nirKeypt_x = new float[iKeyPtNum];
+ float[] nirKeypt_y = new float[iKeyPtNum];
+ float nirKeyPtScore = detBeanNir.faceInfos[0].keyptScore;
+ float nirSkinScore = detBeanNir.faceInfos[0].scores[6];
+ System.arraycopy(detBeanNir.faceInfos[0].keypt_x, 0, nirKeypt_x, 0, iKeyPtNum);
+ System.arraycopy(detBeanNir.faceInfos[0].keypt_y, 0, nirKeypt_y, 0, iKeyPtNum);
+
+ FaceInfo visRetInfo = new FaceInfo();
+ FaceNirLivBean detBeanVis = GetFaceInfoByImgData(m_detHandle, imgDataVis);
+ if (detBeanVis.ret != 0) {
+ nirRet.ret = detBeanVis.ret;
+ return;
+ } else {
+ if (detBeanVis.faceNum < 1)
+ {
+ nirRet.ret = FaceInterface.cw_nirliveness_err_t.CW_NIRLIV_ERR_NIR_NO_FACE;
+ System.out.println("鍙鍏夋娴嬪け璐 ");
+ return ;
+ }
+ }
+ //鍙鍏変汉鑴哥収鐗囨娴,鍙彇绗竴涓汉鑴
+
+ float[] visKeypt_x = new float[iKeyPtNum];
+ float[] visKeypt_y = new float[iKeyPtNum];
+ float visKeyPtScore = detBeanVis.faceInfos[0].keyptScore ;
+ float visSkinScore = detBeanVis.faceInfos[0].scores[6];
+ System.arraycopy(detBeanVis.faceInfos[0].keypt_x, 0, visKeypt_x, 0, iKeyPtNum);
+ System.arraycopy(detBeanVis.faceInfos[0].keypt_y, 0, visKeypt_y, 0, iKeyPtNum);
+
+ // 绾㈠妫娴嬪弬鏁拌祴鍊
+ FaceNisLiveParam nirParam = new FaceNisLiveParam();
+ nirParam.nLandmarks = iKeyPtNum; // 鍏抽敭鐐逛釜鏁
+ // 鍙鍏夊浘鐗囪祴鍊
+
+ nirParam.visWidth = detBeanVis.faceInfos[0].width;
+ nirParam.visHeight = detBeanVis.faceInfos[0].height;
+ nirParam.visFormat = FaceInterface.cw_img_form_t.CW_IMAGE_BINARY; // 杩欓噷璇诲彇鍚庨兘鏄3閫氶亾鐨刡gr鍥;
+ // 绾㈠鍥剧墖璧嬪
+ nirParam.nirWidth = detBeanNir.faceInfos[0].width ;
+ nirParam.nirHeight = detBeanNir.faceInfos[0].height;
+ nirParam.nirFormat = FaceInterface.cw_img_form_t.CW_IMAGE_BINARY; // 杩欓噷璇诲彇鍚庨兘鏄3閫氶亾鐨刡gr鍥;
+ nirRet.MemoryFaceNisLive(1);
+ nirRet.ret = mNir.cwFaceNirLivenessDet(m_NirLivnessHandle, nirParam,
+ imgDataVis, visSkinScore, visKeyPtScore, visKeypt_x, visKeypt_y,
+ imgDataNir , nirSkinScore, nirKeyPtScore, nirKeypt_x, nirKeypt_y,
+ nirRet.nirRetInfo);
+ if (nirRet.ret == FaceInterface.cw_nirliveness_err_t.CW_NIRLIV_OK)
+ {
+ System.out.println( "ret: " + nirRet.nirRetInfo.livRst + " score: " + nirRet.nirRetInfo.score );
+ }else{
+ System.out.println( "Face NisLiveness Error: " + nirRet.ret );
+ }
+ System.out.println("\nFace NirLiveness Completely");
+ }
+
+ // 杈撳叆鍥剧墖璺緞锛岃緭鍑虹壒寰
+ private byte[] GetFeatureFromPicPath(String sPicPath) {
+
+ System.out.println(sPicPath + " 鎻愮壒寰");
+ byte[] imgData = null;
+ try {
+ imgData = file2byte(new File(sPicPath));
+ } catch (Exception e) {
+ // e.printStackTrace();
+ }
+
+ if (imgData == null || imgData.length < 1) {
+ System.out.println("鍥剧墖涓虹┖");
+ return null;
+ }
+
+ FaceInfo[] faceBuffers = new FaceInfo[MAX_FACE_NUM];
+ for (int i = 0; i < MAX_FACE_NUM; i++) {
+ faceBuffers[i] = new FaceInfo();
+ }
+ // 鍔犱笂浜鸿劯瀵归綈寮鍏矯W_OP_ALIGN锛岀敤瀵归綈鏁版嵁鏉ユ彁鐗瑰緛
+ int faceNum = mDet.cwFaceDetection(m_detHandle, imgData, 0, 0, FaceInterface.cw_img_form_t.CW_IMAGE_BINARY, 0,
+ 0, FaceInterface.cw_op_t.CW_OP_DET | FaceInterface.cw_op_t.CW_OP_ALIGN, faceBuffers);
+ if (faceNum >= ERRCODE_MIN) {
+ System.out.println("妫娴嬪け璐ワ紝閿欒鐮侊細" + faceNum); // 妫娴嬪紓甯
+ return null;
+ } else if (faceNum < 1) {
+ System.out.println("鏈娴嬪埌浜鸿劯"); // 鏈娴嬪埌浜鸿劯
+ return null;
+ }
+
+ if (faceBuffers[0].alignedData == null) {
+ System.out.println("瀵归綈鏁版嵁涓虹┖锛岃皟鐢ㄦ娴嬫帴鍙f椂璇峰姞涓婂榻愬紑鍏"); // 鍒ゆ柇瀵归綈鏁版嵁
+ return null;
+ }
+
+ int iFeaLen = mRecog.cwGetFeatureLength(m_recogHandle);
+ byte[] feature = new byte[iFeaLen];
+ int errCode = FaceInterface.cw_errcode_t.CW_SDKLIT_OK; // 鎻愮壒寰侀敊璇爜
+ Long startTime = System.currentTimeMillis();
+ errCode = mRecog.cwGetFaceFeature(m_recogHandle, faceBuffers[0].alignedData, faceBuffers[0].alignedW,
+ faceBuffers[0].alignedH, faceBuffers[0].nChannels, feature);
+ System.out.println("鎻愮壒寰佽楁椂(ms):" + (System.currentTimeMillis() - startTime));
+ if (errCode != FaceInterface.cw_errcode_t.CW_SDKLIT_OK) {
+ System.out.println("鎻愮壒寰侀敊璇細" + errCode);
+ return null;
+ }
+
+ return feature;
+ }
+
+ public static String getRootPath() {
+ try {
+ String sCurPath = new File("").getCanonicalPath();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return "../../CWModels";
+ }
+
+ public byte[] file2byte(File file) throws IOException {
+ byte[] bytes = null;
+ if (file != null) {
+ InputStream is = new FileInputStream(file);
+ int length = (int) file.length();
+ if (length > Integer.MAX_VALUE) {// 褰撴枃浠剁殑闀垮害瓒呰繃浜唅nt鐨勬渶澶у
+ System.out.println("this file is max ");
+ is.close();
+ return null;
+ }
+ bytes = new byte[length];
+ int offset = 0;
+ int numRead = 0;
+ while (offset < bytes.length && (numRead = is.read(bytes, offset, bytes.length - offset)) >= 0) {
+ offset += numRead;
+ }
+ is.close();
+ // 濡傛灉寰楀埌鐨勫瓧鑺傞暱搴﹀拰file瀹為檯鐨勯暱搴︿笉涓鑷村氨鍙兘鍑洪敊浜
+ if (offset < bytes.length) {
+ System.out.println("file length is error");
+ return null;
+ }
+ }
+ return bytes;
+ }
+
+ public FaceNirLivBean GetFaceInfoByImgData(int DetHandle, byte[] ImgData){
+ FaceNirLivBean detectBean = new FaceNirLivBean();
+ if (DetHandle == -1||ImgData == null || ImgData.length< 1)
+ {
+ detectBean.ret = (int)FaceInterface.cw_errcode_t.CW_UNINITIALIZED_ERR;
+ return detectBean;
+ }
+ int iFaceNum = 0;
+ // 妫娴嬶紝鍏抽敭鐐逛笌璐ㄩ噺鍒
+
+ int faceNum = mDet.cwFaceDetection(m_detHandle, ImgData, 0, 0, FaceInterface.cw_img_form_t.CW_IMAGE_BINARY, 0,
+ 0, FaceInterface.cw_op_t.CW_OP_DET|FaceInterface.cw_op_t.CW_OP_KEYPT|FaceInterface.cw_op_t.CW_OP_QUALITY , detectBean.faceInfos);
+ if (faceNum >= ERRCODE_MIN) {
+ System.out.println("Face Detector Error锛孋ode 锛" + faceNum); // 妫娴嬪紓甯
+ detectBean.ret = faceNum;
+ } else if (faceNum < 1) {
+ System.out.println("No Face Detected !"); // 鏈娴嬪埌浜鸿劯
+ detectBean.faceNum = faceNum;
+ }
+ detectBean.faceNum = faceNum;
+ return detectBean;
+ }
+
+}
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava浣跨敤璇存槑_Windows.txt b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava浣跨敤璇存槑_Windows.txt
new file mode 100644
index 0000000..66d2a4d
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/DemoJava浣跨敤璇存槑_Windows.txt
@@ -0,0 +1,4 @@
+1. 当前目录里的DemoJava为Eclipse工程,使用的JDK版本为“jdk1.8.0”;
+2. DemoJava中加载的Dll库为“CWFaceSDKJni.dll”,该版本只支持64位的SDK,该库为jni库,依赖对应SDK的库;
+3. 当前目录下“win_x64_jni”中的JNI库,依赖上层目录“build_64\bin”中的SDK库;
+4. 若要调用该Demo,需要将以上jni库和SDK库拷贝到一起,设置环境变量;或者全部拷贝到JDK下的“bin”目录中,目的是让java虚拟机能Load这些SDK库。
\ No newline at end of file
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/demo_java_windows.bat b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/demo_java_windows.bat
new file mode 100644
index 0000000..d418a50
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/demo_java_windows.bat
@@ -0,0 +1,10 @@
+@echo off
+echo 将所有依赖的dll库拷贝到目标路径,再设置环境变量
+set packsrc=..\
+set packdest=win_x64_jni
+
+
+echo 拷贝Windows库
+XCOPY %packsrc%build_64\bin\*.dll %packdest% /Y/i/s
+
+pause
\ No newline at end of file
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/win_x64_jni/CWFaceSDKJni.dll b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/win_x64_jni/CWFaceSDKJni.dll
new file mode 100644
index 0000000..ea5182f
Binary files /dev/null and b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/win_x64_jni/CWFaceSDKJni.dll differ
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/win_x86_jni/CWFaceSDKJni.dll b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/win_x86_jni/CWFaceSDKJni.dll
new file mode 100644
index 0000000..3f2b88e
Binary files /dev/null and b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_Java/win_x86_jni/CWFaceSDKJni.dll differ
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/Demo_MFC.cpp b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/Demo_MFC.cpp
new file mode 100644
index 0000000..9e49bc7
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/Demo_MFC.cpp
@@ -0,0 +1,102 @@
+
+// Demo_MFC.cpp : 定义应用程序的类行为。
+//
+
+#include "stdafx.h"
+#include "Demo_MFC.h"
+#include "Demo_MFCDlg.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+
+// CDemo_MFCApp
+
+BEGIN_MESSAGE_MAP(CDemo_MFCApp, CWinApp)
+ ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
+END_MESSAGE_MAP()
+
+
+// CDemo_MFCApp 构造
+
+CDemo_MFCApp::CDemo_MFCApp()
+{
+ // 支持重新启动管理器
+ m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART;
+
+ // TODO: 在此处添加构造代码,
+ // 将所有重要的初始化放置在 InitInstance 中
+}
+
+
+// 唯一的一个 CDemo_MFCApp 对象
+
+CDemo_MFCApp theApp;
+
+
+// CDemo_MFCApp 初始化
+
+BOOL CDemo_MFCApp::InitInstance()
+{
+ // 如果一个运行在 Windows XP 上的应用程序清单指定要
+ // 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式,
+ //则需要 InitCommonControlsEx()。否则,将无法创建窗口。
+ INITCOMMONCONTROLSEX InitCtrls;
+ InitCtrls.dwSize = sizeof(InitCtrls);
+ // 将它设置为包括所有要在应用程序中使用的
+ // 公共控件类。
+ InitCtrls.dwICC = ICC_WIN95_CLASSES;
+ InitCommonControlsEx(&InitCtrls);
+
+ CWinApp::InitInstance();
+
+
+ AfxEnableControlContainer();
+
+ // 创建 shell 管理器,以防对话框包含
+ // 任何 shell 树视图控件或 shell 列表视图控件。
+ CShellManager *pShellManager = new CShellManager;
+
+ // 激活“Windows Native”视觉管理器,以便在 MFC 控件中启用主题
+ CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));
+
+ // 标准初始化
+ // 如果未使用这些功能并希望减小
+ // 最终可执行文件的大小,则应移除下列
+ // 不需要的特定初始化例程
+ // 更改用于存储设置的注册表项
+ // TODO: 应适当修改该字符串,
+ // 例如修改为公司或组织名
+ SetRegistryKey(_T("应用程序向导生成的本地应用程序"));
+
+ CDemo_MFCDlg dlg;
+ m_pMainWnd = &dlg;
+ INT_PTR nResponse = dlg.DoModal();
+ if (nResponse == IDOK)
+ {
+ // TODO: 在此放置处理何时用
+ // “确定”来关闭对话框的代码
+ }
+ else if (nResponse == IDCANCEL)
+ {
+ // TODO: 在此放置处理何时用
+ // “取消”来关闭对话框的代码
+ }
+ else if (nResponse == -1)
+ {
+ TRACE(traceAppMsg, 0, "警告: 对话框创建失败,应用程序将意外终止。\n");
+ TRACE(traceAppMsg, 0, "警告: 如果您在对话框上使用 MFC 控件,则无法 #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS。\n");
+ }
+
+ // 删除上面创建的 shell 管理器。
+ if (pShellManager != NULL)
+ {
+ delete pShellManager;
+ }
+
+ // 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序,
+ // 而不是启动应用程序的消息泵。
+ return FALSE;
+}
+
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/Demo_MFC.h b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/Demo_MFC.h
new file mode 100644
index 0000000..f995077
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/Demo_MFC.h
@@ -0,0 +1,32 @@
+
+// Demo_MFC.h : PROJECT_NAME 应用程序的主头文件
+//
+
+#pragma once
+
+#ifndef __AFXWIN_H__
+ #error "在包含此文件之前包含“stdafx.h”以生成 PCH 文件"
+#endif
+
+#include "resource.h" // 主符号
+
+
+// CDemo_MFCApp:
+// 有关此类的实现,请参阅 Demo_MFC.cpp
+//
+
+class CDemo_MFCApp : public CWinApp
+{
+public:
+ CDemo_MFCApp();
+
+// 重写
+public:
+ virtual BOOL InitInstance();
+
+// 实现
+
+ DECLARE_MESSAGE_MAP()
+};
+
+extern CDemo_MFCApp theApp;
\ No newline at end of file
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/Demo_MFC.rc b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/Demo_MFC.rc
new file mode 100644
index 0000000..ccb9cef
Binary files /dev/null and b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/Demo_MFC.rc differ
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/Demo_MFC.vcxproj b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/Demo_MFC.vcxproj
new file mode 100644
index 0000000..c0b5ed3
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/Demo_MFC.vcxproj
@@ -0,0 +1,327 @@
+锘
+
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release_Xp
+ Win32
+
+
+ Release_Xp
+ x64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ {D67A3C09-8724-4B0A-8346-8CDEABAEB082}
+ Demo_MFC
+ MFCProj
+
+
+
+ Application
+ true
+ v110
+ Unicode
+ Dynamic
+
+
+ Application
+ true
+ v110
+ Unicode
+ Dynamic
+
+
+ Application
+ false
+ v110
+ true
+ Unicode
+ Dynamic
+
+
+ Application
+ false
+ v110_xp
+ true
+ Unicode
+ Dynamic
+
+
+ Application
+ false
+ v110
+ true
+ Unicode
+ Dynamic
+
+
+ Application
+ false
+ v110
+ true
+ Unicode
+ Dynamic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+ true
+
+
+ false
+ ..\build_32\bin
+
+
+ false
+ ..\build_xp\bin
+
+
+ false
+ ..\build_64\bin
+
+
+ false
+ ..\build_64\bin
+
+
+
+ Use
+ Level3
+ Disabled
+ WIN32;_WINDOWS;_DEBUG;%(PreprocessorDefinitions)
+ true
+
+
+ Windows
+ true
+
+
+ false
+ true
+ _DEBUG;%(PreprocessorDefinitions)
+
+
+ 0x0804
+ _DEBUG;%(PreprocessorDefinitions)
+ $(IntDir);%(AdditionalIncludeDirectories)
+
+
+
+
+ Use
+ Level3
+ Disabled
+ WIN32;_WINDOWS;_DEBUG;%(PreprocessorDefinitions)
+ true
+
+
+ Windows
+ true
+
+
+ false
+ _DEBUG;%(PreprocessorDefinitions)
+
+
+ 0x0804
+ _DEBUG;%(PreprocessorDefinitions)
+ $(IntDir);%(AdditionalIncludeDirectories)
+
+
+
+
+ Level3
+ Use
+ Disabled
+ true
+ true
+ WIN32;_WINDOWS;NDEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+ true
+ opencv310\include;opencv310\include\opencv;opencv310\include\opencv2;..\CWFaceSDK;%(AdditionalIncludeDirectories)
+
+
+ Windows
+ true
+ true
+ true
+ CWFaceSDK.lib;opencv_world310.lib;%(AdditionalDependencies)
+ ../build_32/lib;%(AdditionalLibraryDirectories)
+
+
+ false
+ true
+ NDEBUG;%(PreprocessorDefinitions)
+
+
+ 0x0804
+ NDEBUG;%(PreprocessorDefinitions)
+ $(IntDir);%(AdditionalIncludeDirectories)
+
+
+
+
+ Level3
+ Use
+ Disabled
+ true
+ true
+ WIN32;_WINDOWS;NDEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+ true
+ opencv310\include;opencv310\include\opencv;opencv310\include\opencv2;..\CWFaceSDK;%(AdditionalIncludeDirectories)
+
+
+ Windows
+ true
+ true
+ true
+ CWFaceSDK.lib;opencv_world310.lib;%(AdditionalDependencies)
+ ../build_xp/lib;%(AdditionalLibraryDirectories)
+
+
+ false
+ true
+ NDEBUG;%(PreprocessorDefinitions)
+
+
+ 0x0804
+ NDEBUG;%(PreprocessorDefinitions)
+ $(IntDir);%(AdditionalIncludeDirectories)
+
+
+
+
+ Level3
+ Use
+ Disabled
+ true
+ true
+ WIN32;DEMO_X64;_WINDOWS;NDEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+ true
+ opencv310\include;opencv310\include\opencv;opencv310\include\opencv2;..\CWFaceSDK;%(AdditionalIncludeDirectories)
+
+
+ Windows
+ true
+ true
+ true
+ CWFaceSDK.lib;opencv_world310.lib;%(AdditionalDependencies)
+ ../build_64/lib;%(AdditionalLibraryDirectories)
+
+
+ false
+ NDEBUG;%(PreprocessorDefinitions)
+
+
+ 0x0804
+ NDEBUG;%(PreprocessorDefinitions)
+ $(IntDir);%(AdditionalIncludeDirectories)
+
+
+
+
+ Level3
+ Use
+ Disabled
+ true
+ true
+ WIN32;_WINDOWS;NDEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+ true
+ CxImage;opencv310\include;opencv310\include\opencv;opencv310\include\opencv2;..\CWFaceSDK;%(AdditionalIncludeDirectories)
+
+
+ Windows
+ true
+ true
+ true
+ CWFaceSDK.lib;opencv_world310.lib;cximage.lib;jpeg.lib;libdcr.lib;jasper.lib;libpsd.lib;png.lib;tiff.lib;mng.lib;zlib.lib;jbig.lib;%(AdditionalDependencies)
+ lib64;../build_64/lib;%(AdditionalLibraryDirectories)
+
+
+ false
+ NDEBUG;%(PreprocessorDefinitions)
+
+
+ 0x0804
+ NDEBUG;%(PreprocessorDefinitions)
+ $(IntDir);%(AdditionalIncludeDirectories)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Create
+ Create
+ Create
+ Create
+ Create
+ Create
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/Demo_MFC.vcxproj.filters b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/Demo_MFC.vcxproj.filters
new file mode 100644
index 0000000..b44ca8e
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/Demo_MFC.vcxproj.filters
@@ -0,0 +1,63 @@
+锘
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hpp;hxx;hm;inl;inc;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+
+
+
+ 澶存枃浠
+
+
+ 澶存枃浠
+
+
+ 澶存枃浠
+
+
+ 澶存枃浠
+
+
+ 澶存枃浠
+
+
+
+
+ 婧愭枃浠
+
+
+ 婧愭枃浠
+
+
+ 婧愭枃浠
+
+
+
+
+ 璧勬簮鏂囦欢
+
+
+
+
+ 璧勬簮鏂囦欢
+
+
+
+
+ 璧勬簮鏂囦欢
+
+
+
\ No newline at end of file
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/Demo_MFCDlg.cpp b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/Demo_MFCDlg.cpp
new file mode 100644
index 0000000..6be2844
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/Demo_MFCDlg.cpp
@@ -0,0 +1,772 @@
+
+// Demo_MFCDlg.cpp : 实现文件
+//
+
+#include "stdafx.h"
+#include "Demo_MFC.h"
+#include "Demo_MFCDlg.h"
+#include "afxdialogex.h"
+#include "CWFaceConfig.h"
+#include "CWFaceDetection.h"
+#include "CWFaceRecognition.h"
+#include "CWFaceVersion.h"
+
+
+#define MAX_NUM_FACES 3 // 检测的人脸数
+#define MAX_DET_NUM_FACES 10 // 检测线程的人脸数
+#define VERIFY_SHRELHOD 70 // 比对阈值
+#define CW_LICENCE "" // 云从授权码
+
+#define WM_THREAD_SHOWVIDEO WM_USER + 101 // 自定义消息
+
+//线条颜色,画框的
+static cv::Scalar& color = cv::Scalar(0, 0, 255);
+static cv::Scalar& colorGreen = cv::Scalar(0, 255, 0);
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+
+// CDemo_MFCDlg 对话框
+
+
+
+CDemo_MFCDlg::CDemo_MFCDlg(CWnd* pParent /*=NULL*/)
+ : CDialogEx(CDemo_MFCDlg::IDD, pParent)
+{
+ m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
+ m_pDetHandle = nullptr;
+ m_pDetVerify = nullptr;
+ m_pRecogHandle = nullptr;
+ m_bStartThread = false;
+}
+
+void CDemo_MFCDlg::DoDataExchange(CDataExchange* pDX)
+{
+ CDialogEx::DoDataExchange(pDX);
+ DDX_Control(pDX, IDC_EDIT_SCORE, m_edtVerifyScore);
+ DDX_Control(pDX, IDC_EDIT_RESULT, m_edtVerifyResult);
+ DDX_Control(pDX, IDC_EDIT_TIME, m_edtVerifyTime);
+ DDX_Control(pDX, IDC_STATIC_PIC1, m_staticPic1);
+ DDX_Control(pDX, IDC_STATIC_PIC2, m_staticPic2);
+ DDX_Control(pDX, IDC_EDIT_VERSION, m_edtVersion);
+ DDX_Control(pDX, IDC_STATIC_VIDEO, m_staticVideo);
+ DDX_Control(pDX, IDC_STATIC_PIC3, m_staticPic3);
+ DDX_Control(pDX, IDC_EDIT_FACEBUF, m_edtFaceBuf);
+}
+
+BEGIN_MESSAGE_MAP(CDemo_MFCDlg, CDialogEx)
+ ON_WM_PAINT()
+ ON_WM_QUERYDRAGICON()
+ ON_BN_CLICKED(IDC_BTN_LOAD1, &CDemo_MFCDlg::OnBnClickedBtnLoad1)
+ ON_BN_CLICKED(IDC_BTN_LOAD2, &CDemo_MFCDlg::OnBnClickedBtnLoad2)
+ ON_BN_CLICKED(IDC_BTN_VERIFY, &CDemo_MFCDlg::OnBnClickedBtnVerify)
+ ON_BN_CLICKED(IDC_BTN_INIT, &CDemo_MFCDlg::OnBnClickedBtnInit)
+ ON_BN_CLICKED(IDC_BTN_CAMERA1, &CDemo_MFCDlg::OnBnClickedBtnCamera1)
+ ON_BN_CLICKED(IDC_BTN_CAMERA2, &CDemo_MFCDlg::OnBnClickedBtnCamera2)
+ ON_BN_CLICKED(IDC_BTN_OPENUSB, &CDemo_MFCDlg::OnBnClickedBtnOpenusb)
+ ON_MESSAGE(WM_THREAD_SHOWVIDEO, &CDemo_MFCDlg::OnThreadShowVideo)
+ ON_BN_CLICKED(IDC_BTN_DET, &CDemo_MFCDlg::OnBnClickedBtnDet)
+ ON_BN_CLICKED(IDC_BTN_LOAD3, &CDemo_MFCDlg::OnBnClickedBtnLoad3)
+END_MESSAGE_MAP()
+
+
+// CDemo_MFCDlg 消息处理程序
+
+BOOL CDemo_MFCDlg::OnInitDialog()
+{
+ CDialogEx::OnInitDialog();
+
+ // 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
+ // 执行此操作
+ SetIcon(m_hIcon, TRUE); // 设置大图标
+ SetIcon(m_hIcon, FALSE); // 设置小图标
+
+ // TODO: 在此添加额外的初始化代码
+
+ m_staticPic1.GetClientRect(&m_rectPic1);
+ m_hDCPic1 = m_staticPic1.GetDC()->GetSafeHdc();
+
+ m_staticPic2.GetClientRect(&m_rectPic2);
+ m_hDCPic2 = m_staticPic2.GetDC()->GetSafeHdc();
+
+ m_staticPic3.GetClientRect(&m_rectPic3);
+ m_hDCPic3 = m_staticPic3.GetDC()->GetSafeHdc();
+
+ m_staticVideo.GetClientRect(&m_rectVideo);
+ m_hDCVideo = m_staticVideo.GetDC()->GetSafeHdc();
+
+ return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
+}
+
+// 如果向对话框添加最小化按钮,则需要下面的代码
+// 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
+// 这将由框架自动完成。
+
+void CDemo_MFCDlg::OnPaint()
+{
+ if (IsIconic())
+ {
+ CPaintDC dc(this); // 用于绘制的设备上下文
+
+ SendMessage(WM_ICONERASEBKGND, reinterpret_cast(dc.GetSafeHdc()), 0);
+
+ // 使图标在工作区矩形中居中
+ int cxIcon = GetSystemMetrics(SM_CXICON);
+ int cyIcon = GetSystemMetrics(SM_CYICON);
+ CRect rect;
+ GetClientRect(&rect);
+ int x = (rect.Width() - cxIcon + 1) / 2;
+ int y = (rect.Height() - cyIcon + 1) / 2;
+
+ // 绘制图标
+ dc.DrawIcon(x, y, m_hIcon);
+ }
+ else
+ {
+ CDialogEx::OnPaint();
+ }
+}
+
+//当用户拖动最小化窗口时系统调用此函数取得光标
+//显示。
+HCURSOR CDemo_MFCDlg::OnQueryDragIcon()
+{
+ return static_cast(m_hIcon);
+}
+
+
+// [3/3/2017 Lit]:导入图片1
+void CDemo_MFCDlg::OnBnClickedBtnLoad1()
+{
+ // TODO: 在此添加控件通知处理程序代码
+ CFileDialog dlg(TRUE, _T("jpg|bmp|png"), NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
+ _T("Image Files(*.jpg;*.bmp;*.png)|*.jpg;*.bmp;*.png|All Files(*.*)|*.*||"), this);
+ if (IDOK != dlg.DoModal())
+ {
+ return;
+ }
+
+ m_sPic1Path = dlg.GetPathName();
+ ShowImg(m_sPic1Path, m_hDCPic1, m_rectPic1);
+}
+
+// [3/3/2017 Lit]:导入图片2
+void CDemo_MFCDlg::OnBnClickedBtnLoad2()
+{
+ // TODO: 在此添加控件通知处理程序代码
+ CFileDialog dlg(TRUE, _T("jpg|bmp|png"), NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
+ _T("Image Files(*.jpg;*.bmp;*.png)|*.jpg;*.bmp;*.png|All Files(*.*)|*.*||"), this);
+ if (IDOK != dlg.DoModal())
+ {
+ return;
+ }
+
+ m_sPic2Path = dlg.GetPathName();
+ ShowImg(m_sPic2Path, m_hDCPic2, m_rectPic2);
+}
+
+// [3/30/2017 Lit]:给图片1拍照
+void CDemo_MFCDlg::OnBnClickedBtnCamera1()
+{
+ // TODO: 在此添加控件通知处理程序代码
+ if (!m_bStartThread)
+ {
+ MessageBox(_T("请先打开摄像头"));
+ return;
+ }
+
+ {
+ std::lock_guard lock(m_mutex);
+ if (!m_matFrame.empty())
+ {
+ cv::imwrite("./1.jpg", m_matFrame);
+ }
+ else
+ {
+ return;
+ }
+ }
+
+ m_sPic1Path = "./1.jpg";
+ ShowImg(m_sPic1Path, m_hDCPic1, m_rectPic1);
+}
+
+// [3/30/2017 Lit]:给图片2拍照
+void CDemo_MFCDlg::OnBnClickedBtnCamera2()
+{
+ // TODO: 在此添加控件通知处理程序代码
+ if (!m_bStartThread)
+ {
+ MessageBox(_T("请先打开摄像头"));
+ return;
+ }
+
+ {
+ std::lock_guard lock(m_mutex);
+ if (!m_matFrame.empty())
+ {
+ cv::imwrite("./2.jpg", m_matFrame);
+ }
+ else
+ {
+ return;
+ }
+ }
+
+ m_sPic2Path = "./2.jpg";
+ ShowImg(m_sPic2Path, m_hDCPic2, m_rectPic2);
+}
+
+// [3/14/2017 Lit]:初始化事件
+void CDemo_MFCDlg::OnBnClickedBtnInit()
+{
+ // TODO: 在此添加控件通知处理程序代码
+ char szVersion[100] = {0};
+ cw_errcode_t errCode = cwGetSDKVersion(szVersion, 100);
+ m_edtVersion.SetWindowText((CString)szVersion);
+
+ // [3/3/2017 Lit]:创建句柄
+ if (m_pDetHandle != nullptr && m_pDetVerify != nullptr && m_pRecogHandle != nullptr)
+ {
+ MessageBox(_T("已初始化过,不再初始化"));
+ return;
+ }
+
+ if (CreateFaceHandle())
+ {
+ MessageBox(_T("初始化成功"));
+ }
+}
+
+// [3/30/2017 Lit]:打开摄像头,开启检测线程
+void CDemo_MFCDlg::OnBnClickedBtnOpenusb()
+{
+ // TODO: 在此添加控件通知处理程序代码
+ if (nullptr == m_pDetHandle)
+ {
+ MessageBox(_T("检测句柄为空,请先初始化创建句柄"));
+ return;
+ }
+ if (m_bStartThread)
+ {
+ MessageBox(_T("摄像头已打开"));
+ return;
+ }
+
+ if (!m_capture.open(0))
+ {
+ MessageBox(_T("摄像头打开失败"));
+ return;
+ }
+
+ m_bStartThread = true;
+ m_threadFaceDet = std::thread(&CDemo_MFCDlg::ThreadFaceDet, this);
+ m_threadFaceDet.detach();
+}
+
+void CDemo_MFCDlg::ThreadFaceDet()
+{
+ cv::Mat matImage;
+ cw_face_res_t faceBuffers[MAX_DET_NUM_FACES];
+ while (m_bStartThread)
+ {
+ {
+ std::lock_guard lock(m_mutex);
+ m_capture >> m_matFrame;
+ if (m_matFrame.empty())
+ {
+ continue;
+ }
+ matImage = m_matFrame.clone();
+ }
+
+ // 给图像结构体赋值
+ cw_img_t srcImg;
+ srcImg.frameId = 0;
+ srcImg.data = (char*)matImage.data;
+ srcImg.width = matImage.cols;
+ srcImg.height = matImage.rows;
+ srcImg.angle = CW_IMAGE_ANGLE_0;
+ if (matImage.channels() ==1 )
+ {
+ srcImg.format = CW_IMAGE_GRAY8;
+ }
+ else if (matImage.channels() == 3)
+ {
+ srcImg.format = CW_IMAGE_BGR888;
+ }
+ else if (matImage.channels() == 4)
+ {
+ srcImg.format = CW_IMAGE_BGRA8888;
+ }
+ else
+ {
+ continue;
+ }
+
+ // 人脸检测
+ int iFaceNum = 0;
+ cw_errcode_t errCode = cwFaceDetection(m_pDetHandle, &srcImg, faceBuffers, MAX_DET_NUM_FACES, &iFaceNum, CW_OP_DET);
+ for (int i = 0; i < iFaceNum; i++)
+ {
+ cv::Point dst1(faceBuffers[i].faceRect.x, faceBuffers[i].faceRect.y);
+ cv::Point dst2(faceBuffers[i].faceRect.x + faceBuffers[i].faceRect.width, faceBuffers[i].faceRect.y + faceBuffers[i].faceRect.height);
+ //画框
+ cv::rectangle(matImage, dst1, dst2, color, 3);
+ }
+
+ SendMessage(WM_THREAD_SHOWVIDEO, 0, (LPARAM)&matImage);
+ }
+}
+
+LRESULT CDemo_MFCDlg::OnThreadShowVideo(WPARAM wPapam, LPARAM lPapam)
+{
+ cv::Mat matImage = *((cv::Mat*)lPapam);
+ if (!matImage.empty())
+ {
+ ShowVideo((char*)(matImage.data), matImage.cols, matImage.rows);
+ }
+
+ return 0;
+}
+
+// [3/3/2017 Lit]:人脸比对
+void CDemo_MFCDlg::OnBnClickedBtnVerify()
+{
+ // TODO: 在此添加控件通知处理程序代码
+ if (m_sPic1Path.IsEmpty())
+ {
+ MessageBox(_T("请先导入第一张图"));
+ return;
+ }
+ if (m_sPic2Path.IsEmpty())
+ {
+ MessageBox(_T("请先导入第二张图"));
+ return;
+ }
+
+ if (m_pDetVerify == nullptr)
+ {
+ MessageBox(_T("检测句柄为空,请先初始化创建句柄"));
+ return;
+ }
+ if (m_pRecogHandle == nullptr)
+ {
+ MessageBox(_T("识别句柄为空,请先初始化创建句柄"));
+ return;
+ }
+
+ m_edtVerifyScore.SetWindowText(_T(""));
+ m_edtVerifyResult.SetWindowText(_T(""));
+ m_edtVerifyTime.SetWindowText(_T(""));
+
+ DWORD tmBegin = GetTickCount();
+
+ int iFeaLen = cwGetFeatureLength(m_pRecogHandle);
+ char *pFeaFiled = new char[iFeaLen];
+ if (0 == GetFeatureFromPath(m_sPic1Path, pFeaFiled))
+ {
+ char *pFeaProbe = new char[iFeaLen];
+ if (0 == GetFeatureFromPath(m_sPic2Path, pFeaProbe))
+ {
+ float scores[1] = {0.0};
+ cw_errcode_t errCode = cwComputeMatchScore(m_pRecogHandle, pFeaProbe, pFeaFiled, 1, scores);
+ if (CW_SDKLIT_OK == errCode)
+ {
+ CString sScore, sResult, sTime;
+ sScore.Format(_T("%.6f"), scores[0]);
+ sTime.Format(_T("%d ms"), GetTickCount() - tmBegin);
+ if (int(scores[0] * 100) > VERIFY_SHRELHOD)
+ {
+ sResult = _T("比对通过");
+ }
+ else
+ {
+ sResult = _T("比对不通过");
+ }
+
+ m_edtVerifyScore.SetWindowText(sScore);
+ m_edtVerifyResult.SetWindowText(sResult);
+ m_edtVerifyTime.SetWindowText(sTime);
+ }
+ else
+ {
+ CString sTip;
+ sTip.Format(_T("比对错误:%d"), errCode);
+ MessageBox(sTip);
+ }
+ }
+
+ delete[] pFeaProbe;
+ pFeaProbe = nullptr;
+ }
+
+ delete[] pFeaFiled;
+ pFeaFiled = nullptr;
+}
+
+
+void CDemo_MFCDlg::OnBnClickedBtnLoad3()
+{
+ // TODO: 在此添加控件通知处理程序代码
+ CFileDialog dlg(TRUE, _T("jpg|bmp|png"), NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
+ _T("Image Files(*.jpg;*.bmp;*.png)|*.jpg;*.bmp;*.png|All Files(*.*)|*.*||"), this);
+ if (IDOK != dlg.DoModal())
+ {
+ return;
+ }
+
+ m_sPic3Path = dlg.GetPathName();
+ ShowImg(m_sPic3Path, m_hDCPic3, m_rectPic3);
+}
+
+
+// [7/19/2017 Lit]:人脸检测,关键点,质量分
+void CDemo_MFCDlg::OnBnClickedBtnDet()
+{
+ // TODO: 在此添加控件通知处理程序代码
+ if (m_pDetVerify == nullptr)
+ {
+ MessageBox(_T("检测句柄为空,请先初始化创建句柄"));
+ return;
+ }
+
+ if (m_sPic3Path.IsEmpty())
+ {
+ MessageBox(_T("请先导入人脸图片"));
+ return;
+ }
+
+ cv::Mat matImage = cv::imread((std::string)(_bstr_t)(LPCWSTR)m_sPic3Path);
+ if (matImage.empty())
+ {
+ MessageBox(_T("Pic Not Found"));
+ return;
+ }
+
+ m_edtFaceBuf.SetWindowText(_T(""));
+
+ // 给图像结构体赋值
+ cw_img_t srcImg;
+ srcImg.frameId = 0;
+ srcImg.data = (char*)matImage.data;
+ srcImg.width = matImage.cols;
+ srcImg.height = matImage.rows;
+ srcImg.angle = CW_IMAGE_ANGLE_0;
+ if (matImage.channels()==1)
+ {
+ srcImg.format = CW_IMAGE_GRAY8;
+ }
+ else if (matImage.channels()==3)
+ {
+ srcImg.format = CW_IMAGE_BGR888;
+ }
+ else if (matImage.channels()==4)
+ {
+ srcImg.format = CW_IMAGE_BGRA8888;
+ }
+ else
+ {
+ MessageBox(_T("Pic Error"));
+ return;
+ }
+
+ // 此处最多检测20张人脸
+ cw_face_res_t faceBuffers[20];
+ int iFaceNum = 0;
+ DWORD tmBegin = GetTickCount();
+ // 人脸检测,关键点,质量分
+ cw_errcode_t errCode = cwFaceDetection(m_pDetVerify, &srcImg, faceBuffers, 20, &iFaceNum, CW_OP_DET | CW_OP_QUALITY);
+ if (errCode != CW_SDKLIT_OK)
+ {
+ CString sTip;
+ sTip.Format(_T("Face detect Error, Code: %d"), errCode);
+ MessageBox(sTip);
+ return;
+ }
+ if (iFaceNum < 1)
+ {
+ MessageBox(_T("未检测到人脸"));
+ return;
+ }
+
+ CString sFaceRet;
+ sFaceRet.Format(_T("Face Num: %d; Time: %d ms"), iFaceNum, GetTickCount() - tmBegin);
+
+ // 人脸画框
+ for (int i = 0; i < iFaceNum; i++)
+ {
+ cv::Point dst1(faceBuffers[i].faceRect.x, faceBuffers[i].faceRect.y);
+ cv::Point dst2(faceBuffers[i].faceRect.x + faceBuffers[i].faceRect.width, faceBuffers[i].faceRect.y + faceBuffers[i].faceRect.height);
+ //画框
+ cv::rectangle(matImage, dst1, dst2, colorGreen, 3);
+
+ CString sCurFace;
+ sCurFace.Format(_T("\r\n\r\nFace%d: Rect: %d, %d, %d, %d; Quality: %f"), i + 1, faceBuffers[i].faceRect.x, faceBuffers[i].faceRect.y,
+ faceBuffers[i].faceRect.width, faceBuffers[i].faceRect.height,faceBuffers[i].quality.scores[0]);
+ sFaceRet += sCurFace;
+ }
+
+ m_edtFaceBuf.SetWindowText(sFaceRet);
+
+ cv::imwrite("tempDet.jpg", matImage);
+ ShowImg(_T("tempDet.jpg"), m_hDCPic3, m_rectPic3);
+}
+
+
+// [3/3/2017 Lit]:通过图片路径获取图片特征
+int CDemo_MFCDlg::GetFeatureFromPath(const CString &sPath, void* pFeatueData)
+{
+ cv::Mat matImage = cv::imread((std::string)(_bstr_t)(LPCWSTR)sPath);
+ if (matImage.empty())
+ {
+ MessageBox(_T("Pic Not Found"));
+ return -1;
+ }
+
+ // 给图像结构体赋值
+ cw_img_t srcImg;
+ srcImg.frameId = 0;
+ srcImg.data = (char*)matImage.data;
+ srcImg.width = matImage.cols;
+ srcImg.height = matImage.rows;
+ srcImg.angle = CW_IMAGE_ANGLE_0;
+ if (matImage.channels()==1)
+ {
+ srcImg.format = CW_IMAGE_GRAY8;
+ }
+ else if (matImage.channels()==3)
+ {
+ srcImg.format = CW_IMAGE_BGR888;
+ }
+ else if (matImage.channels()==4)
+ {
+ srcImg.format = CW_IMAGE_BGRA8888;
+ }
+ else
+ {
+ MessageBox(_T("Pic Error"));
+ return -1;
+ }
+
+ cw_face_res_t faceBuffers[MAX_NUM_FACES];
+ int iFaceNum = 0;
+ // 人脸检测,获取对齐人脸
+ cw_errcode_t errCode = cwFaceDetection(m_pDetVerify, &srcImg, faceBuffers, MAX_NUM_FACES, &iFaceNum, CW_OP_DET | CW_OP_ALIGN);
+ if (errCode != CW_SDKLIT_OK)
+ {
+ CString sErrTip;
+ sErrTip.Format(_T("Face detect Error, Code: %d"), errCode);
+ MessageBox(sErrTip);
+ return -1;
+ }
+ if (iFaceNum < 1)
+ {
+ MessageBox(_T("未检测到人脸"));
+ return -1;
+ }
+
+ errCode = cwGetFaceFeature(m_pRecogHandle, &faceBuffers[0].faceAligned, pFeatueData);
+ if (CW_SDKLIT_OK != errCode)
+ {
+ CString sErrTip;
+ sErrTip.Format(_T("Get Feature Error, Code: %d"), errCode);
+ MessageBox(sErrTip);
+ return -1;
+ }
+
+ return 0;
+}
+
+bool CDemo_MFCDlg::CreateFaceHandle()
+{
+ // 32位和64位检测模型不能共用,64位用_configs_frontend.xml,非64位用_configs_frontend_x86_arm.xml
+#ifdef DEMO_X64
+ std::string sModelXmlPath = "../../CWModels/_configs_frontend.xml";
+#else
+ std::string sModelXmlPath = "../../CWModels/_configs_frontend_x86_arm.xml";
+#endif // DEMO_X64
+
+ CString sErrorTip;
+ cw_errcode_t errCode = CW_SDKLIT_OK;
+ if (m_pDetHandle != nullptr)
+ {
+ MessageBox(_T("检测句柄1已创建过,不再创建"));
+ }
+ else
+ {
+ m_pDetHandle = cwCreateDetHandle(&errCode, sModelXmlPath.c_str(), CW_LICENCE);
+ if (CW_SDKLIT_OK != errCode || nullptr == m_pDetHandle)
+ {
+ sErrorTip.Format(_T("创建检测句柄1错误,错误码:%d"), errCode);
+ MessageBox(sErrorTip);
+ return false;
+ }
+
+ cw_det_param_t param;
+ cwGetFaceParam(m_pDetHandle, ¶m);
+ param.minSize = 48;
+ param.maxSize = 600; //摄像头大小
+ param.pConfigFile = sModelXmlPath.c_str(); // 设置接口功能参数
+ cwSetFaceParam(m_pDetHandle, ¶m);
+ }
+
+ if (m_pDetVerify != nullptr)
+ {
+ MessageBox(_T("检测句柄2已创建过,不再创建"));
+ }
+ else
+ {
+ m_pDetVerify = cwCreateDetHandle(&errCode, sModelXmlPath.c_str(), CW_LICENCE);
+ if (CW_SDKLIT_OK != errCode || nullptr == m_pDetVerify)
+ {
+ sErrorTip.Format(_T("创建检测句柄2错误,错误码:%d"), errCode);
+ MessageBox(sErrorTip);
+ return false;
+ }
+
+ cw_det_param_t param;
+ cwGetFaceParam(m_pDetVerify, ¶m);
+ param.minSize = 30;
+ param.maxSize = 1000; //设置人脸大小
+ param.pConfigFile = sModelXmlPath.c_str(); // 设置接口功能参数
+ cwSetFaceParam(m_pDetVerify, ¶m);
+ }
+
+ if (m_pRecogHandle != nullptr)
+ {
+ MessageBox(_T("识别句柄已创建过,不再创建"));
+ }
+ else
+ {
+ m_pRecogHandle = cwCreateRecogHandle(&errCode, "../../CWModels/CWR_Config_1_1.xml", CW_LICENCE, CW_FEATURE_EXTRACT);
+ if (CW_SDKLIT_OK != errCode || nullptr == m_pRecogHandle)
+ {
+ sErrorTip.Format(_T("创建识别句柄错误,错误码:%d"), errCode);
+ MessageBox(sErrorTip);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void CDemo_MFCDlg::ReleaseFaceHandle()
+{
+ m_bStartThread = false;
+ {
+ std::lock_guard lock(m_mutex);
+ m_capture.release();
+ }
+
+/*
+ if (m_threadFaceDet.joinable())
+ {
+ m_threadFaceDet.join();
+ m_capture.release();
+ }*/
+
+ // 程序退出时销毁句柄
+ if (m_pDetHandle != nullptr)
+ {
+ cwReleaseDetHandle(m_pDetHandle);
+ m_pDetHandle = nullptr;
+ }
+ if (m_pDetVerify != nullptr)
+ {
+ cwReleaseDetHandle(m_pDetVerify);
+ m_pDetVerify = nullptr;
+ }
+ if (m_pRecogHandle != nullptr)
+ {
+ cwReleaseRecogHandle(m_pRecogHandle);
+ m_pRecogHandle = nullptr;
+ }
+
+ DeleteDC(m_hDCVideo);
+ DeleteDC(m_hDCPic1);
+ DeleteDC(m_hDCPic2);
+ DeleteDC(m_hDCPic3);
+}
+
+
+void CDemo_MFCDlg::PostNcDestroy()
+{
+ // TODO: 在此添加专用代码和/或调用基类
+ // [3/3/2017 Lit]:程序退出时销毁句柄
+ ReleaseFaceHandle();
+
+ CDialogEx::PostNcDestroy();
+}
+
+/************************************************************************/
+/* 显示视频 */
+/************************************************************************/
+void CDemo_MFCDlg::ShowVideo(char* szFrame, int iImgWidth, int iImgHeight)
+{
+ BITMAPINFO BmpInfo;
+ BmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ BmpInfo.bmiHeader.biWidth = (LONG)iImgWidth;
+ BmpInfo.bmiHeader.biHeight = (LONG)iImgHeight;
+
+ BmpInfo.bmiHeader.biPlanes = 1;
+ BmpInfo.bmiHeader.biBitCount = 24;
+ BmpInfo.bmiHeader.biCompression = BI_RGB;
+ BmpInfo.bmiHeader.biSizeImage = 0;
+ BmpInfo.bmiHeader.biXPelsPerMeter = 0;
+ BmpInfo.bmiHeader.biYPelsPerMeter = 0;
+ BmpInfo.bmiHeader.biClrUsed = 0;
+ BmpInfo.bmiHeader.biClrImportant = 0;
+
+ SetStretchBltMode(m_hDCVideo, COLORONCOLOR);
+ StretchDIBits(m_hDCVideo, 0, (m_rectVideo.bottom - m_rectVideo.top), (m_rectVideo.right - m_rectVideo.left), (m_rectVideo.top - m_rectVideo.bottom),
+ 0, 0, iImgWidth, iImgHeight, szFrame, &BmpInfo, DIB_RGB_COLORS, SRCCOPY);
+}
+
+void CDemo_MFCDlg::ShowImg(CString sPicPath, HDC hDCVideo, RECT rectVideo)
+{
+ cv::Mat matImage = cv::imread((std::string)(_bstr_t)(LPCWSTR)sPicPath);
+ if (matImage.empty())
+ {
+ return;
+ }
+ if (matImage.channels() == 4)
+ {
+ cv::Mat matTemp;
+ cv::cvtColor(matImage, matTemp, CV_BGRA2BGR);
+ matImage = matTemp.clone();
+ }
+
+ // 要显示宽度必须是4的倍数
+ int iWidth = matImage.cols;
+ int iHeight = matImage.rows;
+ if (0 != iWidth % 4)
+ {
+ iWidth = iWidth / 4 * 4;
+ int iWidthCut = matImage.cols - iWidth;
+ int iLeft = iWidthCut / 2;
+ int iRight = iWidth + iLeft;
+ matImage = matImage.colRange(iLeft, iRight).clone();
+ }
+
+ BITMAPINFO BmpInfo;
+ BmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ BmpInfo.bmiHeader.biWidth = (LONG)iWidth;
+ BmpInfo.bmiHeader.biHeight = (LONG)iHeight;
+
+ BmpInfo.bmiHeader.biPlanes = 1;
+ BmpInfo.bmiHeader.biBitCount = 24;
+ BmpInfo.bmiHeader.biCompression = BI_RGB;
+ BmpInfo.bmiHeader.biSizeImage = 0;
+ BmpInfo.bmiHeader.biXPelsPerMeter = 0;
+ BmpInfo.bmiHeader.biYPelsPerMeter = 0;
+ BmpInfo.bmiHeader.biClrUsed = 0;
+ BmpInfo.bmiHeader.biClrImportant = 0;
+
+ SetStretchBltMode(hDCVideo, COLORONCOLOR);
+ StretchDIBits(hDCVideo, 0, (rectVideo.bottom - rectVideo.top), (rectVideo.right - rectVideo.left), (rectVideo.top - rectVideo.bottom),
+ 0, 0, iWidth, iHeight, matImage.data, &BmpInfo, DIB_RGB_COLORS, SRCCOPY);
+}
+
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/Demo_MFCDlg.h b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/Demo_MFCDlg.h
new file mode 100644
index 0000000..7474bf7
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/Demo_MFCDlg.h
@@ -0,0 +1,103 @@
+
+// Demo_MFCDlg.h : 头文件
+//
+
+#pragma once
+#include "afxwin.h"
+#include "opencv.hpp"
+#include
+#include
+
+// CDemo_MFCDlg 对话框
+class CDemo_MFCDlg : public CDialogEx
+{
+// 构造
+public:
+ CDemo_MFCDlg(CWnd* pParent = NULL); // 标准构造函数
+
+// 对话框数据
+ enum { IDD = IDD_DEMO_MFC_DIALOG };
+
+ protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
+
+ virtual void PostNcDestroy();
+
+
+// 实现
+protected:
+ HICON m_hIcon;
+
+ // 生成的消息映射函数
+ virtual BOOL OnInitDialog();
+ afx_msg void OnPaint();
+ afx_msg HCURSOR OnQueryDragIcon();
+
+ afx_msg void OnBnClickedBtnLoad1();
+ afx_msg void OnBnClickedBtnLoad2();
+ afx_msg void OnBnClickedBtnVerify();
+ afx_msg void OnBnClickedBtnInit();
+ afx_msg void OnBnClickedBtnCamera1();
+ afx_msg void OnBnClickedBtnCamera2();
+ afx_msg void OnBnClickedBtnOpenusb();
+ afx_msg void OnBnClickedBtnLoad3();
+ afx_msg void OnBnClickedBtnDet();
+
+ afx_msg LRESULT OnThreadShowVideo(WPARAM wPapam, LPARAM lPapam);
+
+ DECLARE_MESSAGE_MAP()
+
+private:
+ // [3/3/2017 Lit]:通过图片路径获取图片特征
+ int GetFeatureFromPath(const CString &sPath, void* pFeatueData);
+
+ bool CreateFaceHandle();
+
+ void ReleaseFaceHandle();
+
+ void ThreadFaceDet();
+
+ void ShowVideo(char* szFrame,int iImgWidth,int iImgHeight);
+
+ void ShowImg(CString sPicPath, HDC hDCVideo, RECT rectVideo);
+
+
+private:
+
+ void* m_pDetHandle; // 检测线程中的检测句柄
+ void* m_pDetVerify; // 用于比对过程中的检测句柄
+ void* m_pRecogHandle; // 识别句柄
+
+ CEdit m_edtVersion;
+ CEdit m_edtVerifyScore;
+ CEdit m_edtVerifyResult;
+ CEdit m_edtVerifyTime;
+ CEdit m_edtFaceBuf;
+
+ CStatic m_staticVideo; // 显示USB摄像头的控件
+ RECT m_rectVideo;
+ HDC m_hDCVideo;
+
+ CStatic m_staticPic1;
+ RECT m_rectPic1;
+ HDC m_hDCPic1;
+
+ CStatic m_staticPic2;
+ RECT m_rectPic2;
+ HDC m_hDCPic2;
+
+ CStatic m_staticPic3;
+ RECT m_rectPic3;
+ HDC m_hDCPic3;
+
+ cv::VideoCapture m_capture; // 摄像头操作对象
+ cv::Mat m_matFrame; // 当前帧
+ std::thread m_threadFaceDet; // 检测线程
+ std::mutex m_mutex; // 锁
+
+ CString m_sPic1Path; // 图片1路径
+ CString m_sPic2Path; // 图片2路径
+ CString m_sPic3Path; // 图片3路径
+ bool m_bStartThread; // 是否开启检测线程
+
+};
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/ReadMe.txt b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/ReadMe.txt
new file mode 100644
index 0000000..a803183
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/ReadMe.txt
@@ -0,0 +1,70 @@
+锘================================================================================
+ MICROSOFT 鍩虹绫诲簱 : Demo_MFC 椤圭洰姒傝堪
+===============================================================================
+
+搴旂敤绋嬪簭鍚戝宸蹭负鎮ㄥ垱寤轰簡姝 Demo_MFC 搴旂敤绋嬪簭銆傛搴旂敤绋嬪簭涓嶄粎婕旂ず Microsoft 鍩虹绫荤殑鍩烘湰浣跨敤鏂规硶锛岃繕鍙綔涓烘偍缂栧啓搴旂敤绋嬪簭鐨勮捣鐐广
+
+鏈枃浠舵瑕佷粙缁嶇粍鎴 Demo_MFC 搴旂敤绋嬪簭鐨勬瘡涓枃浠剁殑鍐呭銆
+
+Demo_MFC.vcxproj
+ 杩欐槸浣跨敤搴旂敤绋嬪簭鍚戝鐢熸垚鐨 VC++ 椤圭洰鐨勪富椤圭洰鏂囦欢锛屽叾涓寘鍚敓鎴愯鏂囦欢鐨 Visual C++ 鐨勭増鏈俊鎭紝浠ュ強鏈夊叧浣跨敤搴旂敤绋嬪簭鍚戝閫夋嫨鐨勫钩鍙般侀厤缃拰椤圭洰鍔熻兘鐨勪俊鎭
+
+Demo_MFC.vcxproj.filters
+ 杩欐槸浣跨敤鈥滃簲鐢ㄧ▼搴忓悜瀵尖濈敓鎴愮殑 VC++ 椤圭洰绛涢夊櫒鏂囦欢銆傚畠鍖呭惈鏈夊叧椤圭洰鏂囦欢涓庣瓫閫夊櫒涔嬮棿鐨勫叧鑱斾俊鎭傚湪 IDE 涓紝閫氳繃杩欑鍏宠仈锛屽湪鐗瑰畾鑺傜偣涓嬩互鍒嗙粍褰㈠紡鏄剧ず鍏锋湁鐩镐技鎵╁睍鍚嶇殑鏂囦欢銆備緥濡傦紝鈥.cpp鈥濇枃浠朵笌鈥滄簮鏂囦欢鈥濈瓫閫夊櫒鍏宠仈銆
+
+Demo_MFC.h
+ 杩欐槸搴旂敤绋嬪簭鐨勪富澶存枃浠躲
+ 鍏朵腑鍖呮嫭鍏朵粬椤圭洰鐗瑰畾鐨勬爣澶达紙鍖呮嫭 Resource.h锛夛紝骞跺0鏄 CDemo_MFCApp 搴旂敤绋嬪簭绫汇
+
+Demo_MFC.cpp
+ 杩欐槸鍖呭惈搴旂敤绋嬪簭绫 CDemo_MFCApp 鐨勪富搴旂敤绋嬪簭婧愭枃浠躲
+
+Demo_MFC.rc
+ 杩欐槸绋嬪簭浣跨敤鐨勬墍鏈 Microsoft Windows 璧勬簮鐨勫垪琛ㄣ傚畠鍖呮嫭 RES 瀛愮洰褰曚腑瀛樺偍鐨勫浘鏍囥佷綅鍥惧拰鍏夋爣銆傛鏂囦欢鍙互鐩存帴鍦 Microsoft Visual C++ 涓繘琛岀紪杈戙傞」鐩祫婧愬寘鍚湪 2052 涓
+
+res\Demo_MFC.ico
+ 杩欐槸鐢ㄤ綔搴旂敤绋嬪簭鍥炬爣鐨勫浘鏍囨枃浠躲傛鍥炬爣鍖呮嫭鍦ㄤ富璧勬簮鏂囦欢 Demo_MFC.rc 涓
+
+res\Demo_MFC.rc2
+ 姝ゆ枃浠跺寘鍚笉鍦 Microsoft Visual C++ 涓繘琛岀紪杈戠殑璧勬簮銆傛偍搴旇灏嗕笉鍙敱璧勬簮缂栬緫鍣ㄧ紪杈戠殑鎵鏈夎祫婧愭斁鍦ㄦ鏂囦欢涓
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+搴旂敤绋嬪簭鍚戝鍒涘缓涓涓璇濇绫伙細
+
+Demo_MFCDlg.h銆丏emo_MFCDlg.cpp - 瀵硅瘽妗
+ 杩欎簺鏂囦欢鍖呭惈 CDemo_MFCDlg 绫汇傛绫诲畾涔夊簲鐢ㄧ▼搴忕殑涓诲璇濇鐨勮涓恒傚璇濇妯℃澘鍖呭惈鍦 Demo_MFC.rc 涓紝璇ユ枃浠跺彲浠ュ湪 Microsoft Visual C++ 涓紪杈戙
+
+/////////////////////////////////////////////////////////////////////////////
+
+鍏朵粬鍔熻兘锛
+
+ActiveX 鎺т欢
+ 璇ュ簲鐢ㄧ▼搴忓寘鍚浣跨敤 ActiveX 鎺т欢鐨勬敮鎸併
+
+鎵撳嵃鍜屾墦鍗伴瑙堟敮鎸
+ 搴旂敤绋嬪簭鍚戝閫氳繃浠 MFC 搴撹皟鐢 CView 绫讳腑鐨勬垚鍛樺嚱鏁扮敓鎴愪唬鐮侊紝鏉ュ鐞嗘墦鍗般佹墦鍗拌缃拰鎵撳嵃棰勮鍛戒护銆
+
+/////////////////////////////////////////////////////////////////////////////
+
+鍏朵粬鏍囧噯鏂囦欢:
+
+StdAfx.h, StdAfx.cpp
+ 杩欎簺鏂囦欢鐢ㄤ簬鐢熸垚鍚嶄负 Demo_MFC.pch 鐨勯缂栬瘧澶 (PCH) 鏂囦欢鍜屽悕涓 StdAfx.obj 鐨勯缂栬瘧绫诲瀷鏂囦欢銆
+
+Resource.h
+ 杩欐槸鏍囧噯澶存枃浠讹紝鍙敤浜庡畾涔夋柊鐨勮祫婧 ID銆侻icrosoft Visual C++ 灏嗚鍙栧苟鏇存柊姝ゆ枃浠躲
+
+Demo_MFC.manifest
+ Windows XP 浣跨敤搴旂敤绋嬪簭娓呭崟鏂囦欢鏉ユ弿杩扮壒瀹氱増鏈殑骞惰绋嬪簭闆嗙殑搴旂敤绋嬪簭渚濊禆椤广傚姞杞界▼搴忎娇鐢ㄨ繖浜涗俊鎭潵浠庣▼搴忛泦缂撳瓨涓姞杞界浉搴旂殑绋嬪簭闆嗭紝骞朵繚鎶ゅ叾涓嶈搴旂敤绋嬪簭璁块棶銆傚簲鐢ㄧ▼搴忔竻鍗曞彲鑳戒細鍖呭惈鍦ㄥ唴锛屼互浣滀负涓庡簲鐢ㄧ▼搴忓彲鎵ц鏂囦欢瀹夎鍦ㄥ悓涓鏂囦欢澶逛腑鐨勫閮 .manifest 鏂囦欢杩涜閲嶆柊鍒嗗彂锛屽畠杩樺彲鑳戒互璧勬簮鐨勫舰寮忓寘鍚湪鍙墽琛屾枃浠朵腑銆
+/////////////////////////////////////////////////////////////////////////////
+
+鍏朵粬娉ㄩ噴:
+
+搴旂敤绋嬪簭鍚戝浣跨敤鈥淭ODO:鈥濇潵鎸囩ず搴旀坊鍔犳垨鑷畾涔夌殑婧愪唬鐮侀儴鍒嗐
+
+濡傛灉搴旂敤绋嬪簭浣跨敤鍏变韩 DLL 涓殑 MFC锛屾偍灏嗛渶瑕侀噸鏂板垎鍙 MFC DLL銆傚鏋滃簲鐢ㄧ▼搴忔墍浣跨敤鐨勮瑷涓庢搷浣滅郴缁熺殑鍖哄煙璁剧疆涓嶅悓锛屽垯杩橀渶瑕侀噸鏂板垎鍙戠浉搴旂殑鏈湴鍖栬祫婧 mfc110XXX.DLL銆
+鏈夊叧涓婅堪璇濋鐨勬洿澶氫俊鎭紝璇峰弬瑙 MSDN 鏂囨。涓湁鍏抽噸鏂板垎鍙 Visual C++ 搴旂敤绋嬪簭鐨勯儴鍒嗐
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/opencv310/include/opencv/cv.h b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/opencv310/include/opencv/cv.h
new file mode 100644
index 0000000..0aefc6d
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/opencv310/include/opencv/cv.h
@@ -0,0 +1,73 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef __OPENCV_OLD_CV_H__
+#define __OPENCV_OLD_CV_H__
+
+#if defined(_MSC_VER)
+ #define CV_DO_PRAGMA(x) __pragma(x)
+ #define __CVSTR2__(x) #x
+ #define __CVSTR1__(x) __CVSTR2__(x)
+ #define __CVMSVCLOC__ __FILE__ "("__CVSTR1__(__LINE__)") : "
+ #define CV_MSG_PRAGMA(_msg) CV_DO_PRAGMA(message (__CVMSVCLOC__ _msg))
+#elif defined(__GNUC__)
+ #define CV_DO_PRAGMA(x) _Pragma (#x)
+ #define CV_MSG_PRAGMA(_msg) CV_DO_PRAGMA(message (_msg))
+#else
+ #define CV_DO_PRAGMA(x)
+ #define CV_MSG_PRAGMA(_msg)
+#endif
+#define CV_WARNING(x) CV_MSG_PRAGMA("Warning: " #x)
+
+//CV_WARNING("This is a deprecated opencv header provided for compatibility. Please include a header from a corresponding opencv module")
+
+#include "opencv2/core/core_c.h"
+#include "opencv2/imgproc/imgproc_c.h"
+#include "opencv2/photo/photo_c.h"
+#include "opencv2/video/tracking_c.h"
+#include "opencv2/objdetect/objdetect_c.h"
+
+#if !defined(CV_IMPL)
+#define CV_IMPL extern "C"
+#endif //CV_IMPL
+
+#endif // __OPENCV_OLD_CV_H_
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/opencv310/include/opencv/cv.hpp b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/opencv310/include/opencv/cv.hpp
new file mode 100644
index 0000000..e498d7a
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/opencv310/include/opencv/cv.hpp
@@ -0,0 +1,60 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef __OPENCV_OLD_CV_HPP__
+#define __OPENCV_OLD_CV_HPP__
+
+//#if defined(__GNUC__)
+//#warning "This is a deprecated opencv header provided for compatibility. Please include a header from a corresponding opencv module"
+//#endif
+
+#include "cv.h"
+#include "opencv2/core.hpp"
+#include "opencv2/imgproc.hpp"
+#include "opencv2/photo.hpp"
+#include "opencv2/video.hpp"
+#include "opencv2/highgui.hpp"
+#include "opencv2/features2d.hpp"
+#include "opencv2/calib3d.hpp"
+#include "opencv2/objdetect.hpp"
+
+#endif
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/opencv310/include/opencv/cvaux.h b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/opencv310/include/opencv/cvaux.h
new file mode 100644
index 0000000..fe86c5d
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/opencv310/include/opencv/cvaux.h
@@ -0,0 +1,57 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// Intel License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000, Intel Corporation, all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of Intel Corporation may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef __OPENCV_OLD_AUX_H__
+#define __OPENCV_OLD_AUX_H__
+
+//#if defined(__GNUC__)
+//#warning "This is a deprecated opencv header provided for compatibility. Please include a header from a corresponding opencv module"
+//#endif
+
+#include "opencv2/core/core_c.h"
+#include "opencv2/imgproc/imgproc_c.h"
+#include "opencv2/photo/photo_c.h"
+#include "opencv2/video/tracking_c.h"
+#include "opencv2/objdetect/objdetect_c.h"
+
+#endif
+
+/* End of file. */
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/opencv310/include/opencv/cvaux.hpp b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/opencv310/include/opencv/cvaux.hpp
new file mode 100644
index 0000000..b0e60a3
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/opencv310/include/opencv/cvaux.hpp
@@ -0,0 +1,52 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// Intel License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000, Intel Corporation, all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of Intel Corporation may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef __OPENCV_OLD_AUX_HPP__
+#define __OPENCV_OLD_AUX_HPP__
+
+//#if defined(__GNUC__)
+//#warning "This is a deprecated opencv header provided for compatibility. Please include a header from a corresponding opencv module"
+//#endif
+
+#include "cvaux.h"
+#include "opencv2/core/utility.hpp"
+
+#endif
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/opencv310/include/opencv/cvwimage.h b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/opencv310/include/opencv/cvwimage.h
new file mode 100644
index 0000000..de89c92
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/opencv310/include/opencv/cvwimage.h
@@ -0,0 +1,46 @@
+///////////////////////////////////////////////////////////////////////////////
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to
+// this license. If you do not agree to this license, do not download,
+// install, copy or use the software.
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2008, Google, all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of Intel Corporation or contributors may not be used to endorse
+// or promote products derived from this software without specific
+// prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is"
+// and any express or implied warranties, including, but not limited to, the
+// implied warranties of merchantability and fitness for a particular purpose
+// are disclaimed. In no event shall the Intel Corporation or contributors be
+// liable for any direct, indirect, incidental, special, exemplary, or
+// consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+
+
+#ifndef __OPENCV_OLD_WIMAGE_HPP__
+#define __OPENCV_OLD_WIMAGE_HPP__
+
+#include "opencv2/core/wimage.hpp"
+
+#endif
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/opencv310/include/opencv/cxcore.h b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/opencv310/include/opencv/cxcore.h
new file mode 100644
index 0000000..0982bd7
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/opencv310/include/opencv/cxcore.h
@@ -0,0 +1,52 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef __OPENCV_OLD_CXCORE_H__
+#define __OPENCV_OLD_CXCORE_H__
+
+//#if defined(__GNUC__)
+//#warning "This is a deprecated opencv header provided for compatibility. Please include a header from a corresponding opencv module"
+//#endif
+
+#include "opencv2/core/core_c.h"
+
+#endif
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/opencv310/include/opencv/cxcore.hpp b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/opencv310/include/opencv/cxcore.hpp
new file mode 100644
index 0000000..9af4ac7
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/opencv310/include/opencv/cxcore.hpp
@@ -0,0 +1,53 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef __OPENCV_OLD_CXCORE_HPP__
+#define __OPENCV_OLD_CXCORE_HPP__
+
+//#if defined(__GNUC__)
+//#warning "This is a deprecated opencv header provided for compatibility. Please include a header from a corresponding opencv module"
+//#endif
+
+#include "cxcore.h"
+#include "opencv2/core.hpp"
+
+#endif
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/opencv310/include/opencv/cxeigen.hpp b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/opencv310/include/opencv/cxeigen.hpp
new file mode 100644
index 0000000..1f04d1a
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/opencv310/include/opencv/cxeigen.hpp
@@ -0,0 +1,48 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef __OPENCV_OLD_EIGEN_HPP__
+#define __OPENCV_OLD_EIGEN_HPP__
+
+#include "opencv2/core/eigen.hpp"
+
+#endif
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/opencv310/include/opencv/cxmisc.h b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/opencv310/include/opencv/cxmisc.h
new file mode 100644
index 0000000..6c93a0c
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/opencv310/include/opencv/cxmisc.h
@@ -0,0 +1,8 @@
+#ifndef __OPENCV_OLD_CXMISC_H__
+#define __OPENCV_OLD_CXMISC_H__
+
+#ifdef __cplusplus
+# include "opencv2/core/utility.hpp"
+#endif
+
+#endif
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/opencv310/include/opencv/highgui.h b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/opencv310/include/opencv/highgui.h
new file mode 100644
index 0000000..0261029
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/opencv310/include/opencv/highgui.h
@@ -0,0 +1,48 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// Intel License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000, Intel Corporation, all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of Intel Corporation may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef __OPENCV_OLD_HIGHGUI_H__
+#define __OPENCV_OLD_HIGHGUI_H__
+
+#include "opencv2/core/core_c.h"
+#include "opencv2/highgui/highgui_c.h"
+
+#endif
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/opencv310/include/opencv/ml.h b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/opencv310/include/opencv/ml.h
new file mode 100644
index 0000000..d8e967f
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/opencv310/include/opencv/ml.h
@@ -0,0 +1,47 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// Intel License Agreement
+//
+// Copyright (C) 2000, Intel Corporation, all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of Intel Corporation may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef __OPENCV_OLD_ML_H__
+#define __OPENCV_OLD_ML_H__
+
+#include "opencv2/core/core_c.h"
+#include "opencv2/ml.hpp"
+
+#endif
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/opencv310/include/opencv2/calib3d.hpp b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/opencv310/include/opencv2/calib3d.hpp
new file mode 100644
index 0000000..ddffffe
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/opencv310/include/opencv2/calib3d.hpp
@@ -0,0 +1,2001 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef __OPENCV_CALIB3D_HPP__
+#define __OPENCV_CALIB3D_HPP__
+
+#include "opencv2/core.hpp"
+#include "opencv2/features2d.hpp"
+#include "opencv2/core/affine.hpp"
+
+/**
+ @defgroup calib3d Camera Calibration and 3D Reconstruction
+
+The functions in this section use a so-called pinhole camera model. In this model, a scene view is
+formed by projecting 3D points into the image plane using a perspective transformation.
+
+\f[s \; m' = A [R|t] M'\f]
+
+or
+
+\f[s \vecthree{u}{v}{1} = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}
+\begin{bmatrix}
+r_{11} & r_{12} & r_{13} & t_1 \\
+r_{21} & r_{22} & r_{23} & t_2 \\
+r_{31} & r_{32} & r_{33} & t_3
+\end{bmatrix}
+\begin{bmatrix}
+X \\
+Y \\
+Z \\
+1
+\end{bmatrix}\f]
+
+where:
+
+- \f$(X, Y, Z)\f$ are the coordinates of a 3D point in the world coordinate space
+- \f$(u, v)\f$ are the coordinates of the projection point in pixels
+- \f$A\f$ is a camera matrix, or a matrix of intrinsic parameters
+- \f$(cx, cy)\f$ is a principal point that is usually at the image center
+- \f$fx, fy\f$ are the focal lengths expressed in pixel units.
+
+Thus, if an image from the camera is scaled by a factor, all of these parameters should be scaled
+(multiplied/divided, respectively) by the same factor. The matrix of intrinsic parameters does not
+depend on the scene viewed. So, once estimated, it can be re-used as long as the focal length is
+fixed (in case of zoom lens). The joint rotation-translation matrix \f$[R|t]\f$ is called a matrix of
+extrinsic parameters. It is used to describe the camera motion around a static scene, or vice versa,
+rigid motion of an object in front of a still camera. That is, \f$[R|t]\f$ translates coordinates of a
+point \f$(X, Y, Z)\f$ to a coordinate system, fixed with respect to the camera. The transformation above
+is equivalent to the following (when \f$z \ne 0\f$ ):
+
+\f[\begin{array}{l}
+\vecthree{x}{y}{z} = R \vecthree{X}{Y}{Z} + t \\
+x' = x/z \\
+y' = y/z \\
+u = f_x*x' + c_x \\
+v = f_y*y' + c_y
+\end{array}\f]
+
+Real lenses usually have some distortion, mostly radial distortion and slight tangential distortion.
+So, the above model is extended as:
+
+\f[\begin{array}{l}
+\vecthree{x}{y}{z} = R \vecthree{X}{Y}{Z} + t \\
+x' = x/z \\
+y' = y/z \\
+x'' = x' \frac{1 + k_1 r^2 + k_2 r^4 + k_3 r^6}{1 + k_4 r^2 + k_5 r^4 + k_6 r^6} + 2 p_1 x' y' + p_2(r^2 + 2 x'^2) + s_1 r^2 + s_2 r^4 \\
+y'' = y' \frac{1 + k_1 r^2 + k_2 r^4 + k_3 r^6}{1 + k_4 r^2 + k_5 r^4 + k_6 r^6} + p_1 (r^2 + 2 y'^2) + 2 p_2 x' y' + s_3 r^2 + s_4 r^4 \\
+\text{where} \quad r^2 = x'^2 + y'^2 \\
+u = f_x*x'' + c_x \\
+v = f_y*y'' + c_y
+\end{array}\f]
+
+\f$k_1\f$, \f$k_2\f$, \f$k_3\f$, \f$k_4\f$, \f$k_5\f$, and \f$k_6\f$ are radial distortion coefficients. \f$p_1\f$ and \f$p_2\f$ are
+tangential distortion coefficients. \f$s_1\f$, \f$s_2\f$, \f$s_3\f$, and \f$s_4\f$, are the thin prism distortion
+coefficients. Higher-order coefficients are not considered in OpenCV.
+
+In some cases the image sensor may be tilted in order to focus an oblique plane in front of the
+camera (Scheimpfug condition). This can be useful for particle image velocimetry (PIV) or
+triangulation with a laser fan. The tilt causes a perspective distortion of \f$x''\f$ and
+\f$y''\f$. This distortion can be modelled in the following way, see e.g. @cite Louhichi07.
+
+\f[\begin{array}{l}
+s\vecthree{x'''}{y'''}{1} =
+\vecthreethree{R_{33}(\tau_x, \tau_y)}{0}{-R_{13}(\tau_x, \tau_y)}
+{0}{R_{33}(\tau_x, \tau_y)}{-R_{23}(\tau_x, \tau_y)}
+{0}{0}{1} R(\tau_x, \tau_y) \vecthree{x''}{y''}{1}\\
+u = f_x*x''' + c_x \\
+v = f_y*y''' + c_y
+\end{array}\f]
+
+where the matrix \f$R(\tau_x, \tau_y)\f$ is defined by two rotations with angular parameter \f$\tau_x\f$
+and \f$\tau_y\f$, respectively,
+
+\f[
+R(\tau_x, \tau_y) =
+\vecthreethree{\cos(\tau_y)}{0}{-\sin(\tau_y)}{0}{1}{0}{\sin(\tau_y)}{0}{\cos(\tau_y)}
+\vecthreethree{1}{0}{0}{0}{\cos(\tau_x)}{\sin(\tau_x)}{0}{-\sin(\tau_x)}{\cos(\tau_x)} =
+\vecthreethree{\cos(\tau_y)}{\sin(\tau_y)\sin(\tau_x)}{-\sin(\tau_y)\cos(\tau_x)}
+{0}{\cos(\tau_x)}{\sin(\tau_x)}
+{\sin(\tau_y)}{-\cos(\tau_y)\sin(\tau_x)}{\cos(\tau_y)\cos(\tau_x)}.
+\f]
+
+In the functions below the coefficients are passed or returned as
+
+\f[(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6 [, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\f]
+
+vector. That is, if the vector contains four elements, it means that \f$k_3=0\f$ . The distortion
+coefficients do not depend on the scene viewed. Thus, they also belong to the intrinsic camera
+parameters. And they remain the same regardless of the captured image resolution. If, for example, a
+camera has been calibrated on images of 320 x 240 resolution, absolutely the same distortion
+coefficients can be used for 640 x 480 images from the same camera while \f$f_x\f$, \f$f_y\f$, \f$c_x\f$, and
+\f$c_y\f$ need to be scaled appropriately.
+
+The functions below use the above model to do the following:
+
+- Project 3D points to the image plane given intrinsic and extrinsic parameters.
+- Compute extrinsic parameters given intrinsic parameters, a few 3D points, and their
+projections.
+- Estimate intrinsic and extrinsic camera parameters from several views of a known calibration
+pattern (every view is described by several 3D-2D point correspondences).
+- Estimate the relative position and orientation of the stereo camera "heads" and compute the
+*rectification* transformation that makes the camera optical axes parallel.
+
+@note
+ - A calibration sample for 3 cameras in horizontal position can be found at
+ opencv_source_code/samples/cpp/3calibration.cpp
+ - A calibration sample based on a sequence of images can be found at
+ opencv_source_code/samples/cpp/calibration.cpp
+ - A calibration sample in order to do 3D reconstruction can be found at
+ opencv_source_code/samples/cpp/build3dmodel.cpp
+ - A calibration sample of an artificially generated camera and chessboard patterns can be
+ found at opencv_source_code/samples/cpp/calibration_artificial.cpp
+ - A calibration example on stereo calibration can be found at
+ opencv_source_code/samples/cpp/stereo_calib.cpp
+ - A calibration example on stereo matching can be found at
+ opencv_source_code/samples/cpp/stereo_match.cpp
+ - (Python) A camera calibration sample can be found at
+ opencv_source_code/samples/python/calibrate.py
+
+ @{
+ @defgroup calib3d_fisheye Fisheye camera model
+
+ Definitions: Let P be a point in 3D of coordinates X in the world reference frame (stored in the
+ matrix X) The coordinate vector of P in the camera reference frame is:
+
+ \f[Xc = R X + T\f]
+
+ where R is the rotation matrix corresponding to the rotation vector om: R = rodrigues(om); call x, y
+ and z the 3 coordinates of Xc:
+
+ \f[x = Xc_1 \\ y = Xc_2 \\ z = Xc_3\f]
+
+ The pinehole projection coordinates of P is [a; b] where
+
+ \f[a = x / z \ and \ b = y / z \\ r^2 = a^2 + b^2 \\ \theta = atan(r)\f]
+
+ Fisheye distortion:
+
+ \f[\theta_d = \theta (1 + k_1 \theta^2 + k_2 \theta^4 + k_3 \theta^6 + k_4 \theta^8)\f]
+
+ The distorted point coordinates are [x'; y'] where
+
+ \f[x' = (\theta_d / r) x \\ y' = (\theta_d / r) y \f]
+
+ Finally, conversion into pixel coordinates: The final pixel coordinates vector [u; v] where:
+
+ \f[u = f_x (x' + \alpha y') + c_x \\
+ v = f_y yy + c_y\f]
+
+ @defgroup calib3d_c C API
+
+ @}
+ */
+
+namespace cv
+{
+
+//! @addtogroup calib3d
+//! @{
+
+//! type of the robust estimation algorithm
+enum { LMEDS = 4, //!< least-median algorithm
+ RANSAC = 8, //!< RANSAC algorithm
+ RHO = 16 //!< RHO algorithm
+ };
+
+enum { SOLVEPNP_ITERATIVE = 0,
+ SOLVEPNP_EPNP = 1, //!< EPnP: Efficient Perspective-n-Point Camera Pose Estimation @cite lepetit2009epnp
+ SOLVEPNP_P3P = 2, //!< Complete Solution Classification for the Perspective-Three-Point Problem @cite gao2003complete
+ SOLVEPNP_DLS = 3, //!< A Direct Least-Squares (DLS) Method for PnP @cite hesch2011direct
+ SOLVEPNP_UPNP = 4 //!< Exhaustive Linearization for Robust Camera Pose and Focal Length Estimation @cite penate2013exhaustive
+
+};
+
+enum { CALIB_CB_ADAPTIVE_THRESH = 1,
+ CALIB_CB_NORMALIZE_IMAGE = 2,
+ CALIB_CB_FILTER_QUADS = 4,
+ CALIB_CB_FAST_CHECK = 8
+ };
+
+enum { CALIB_CB_SYMMETRIC_GRID = 1,
+ CALIB_CB_ASYMMETRIC_GRID = 2,
+ CALIB_CB_CLUSTERING = 4
+ };
+
+enum { CALIB_USE_INTRINSIC_GUESS = 0x00001,
+ CALIB_FIX_ASPECT_RATIO = 0x00002,
+ CALIB_FIX_PRINCIPAL_POINT = 0x00004,
+ CALIB_ZERO_TANGENT_DIST = 0x00008,
+ CALIB_FIX_FOCAL_LENGTH = 0x00010,
+ CALIB_FIX_K1 = 0x00020,
+ CALIB_FIX_K2 = 0x00040,
+ CALIB_FIX_K3 = 0x00080,
+ CALIB_FIX_K4 = 0x00800,
+ CALIB_FIX_K5 = 0x01000,
+ CALIB_FIX_K6 = 0x02000,
+ CALIB_RATIONAL_MODEL = 0x04000,
+ CALIB_THIN_PRISM_MODEL = 0x08000,
+ CALIB_FIX_S1_S2_S3_S4 = 0x10000,
+ CALIB_TILTED_MODEL = 0x40000,
+ CALIB_FIX_TAUX_TAUY = 0x80000,
+ // only for stereo
+ CALIB_FIX_INTRINSIC = 0x00100,
+ CALIB_SAME_FOCAL_LENGTH = 0x00200,
+ // for stereo rectification
+ CALIB_ZERO_DISPARITY = 0x00400,
+ CALIB_USE_LU = (1 << 17), //!< use LU instead of SVD decomposition for solving. much faster but potentially less precise
+ };
+
+//! the algorithm for finding fundamental matrix
+enum { FM_7POINT = 1, //!< 7-point algorithm
+ FM_8POINT = 2, //!< 8-point algorithm
+ FM_LMEDS = 4, //!< least-median algorithm
+ FM_RANSAC = 8 //!< RANSAC algorithm
+ };
+
+
+
+/** @brief Converts a rotation matrix to a rotation vector or vice versa.
+
+@param src Input rotation vector (3x1 or 1x3) or rotation matrix (3x3).
+@param dst Output rotation matrix (3x3) or rotation vector (3x1 or 1x3), respectively.
+@param jacobian Optional output Jacobian matrix, 3x9 or 9x3, which is a matrix of partial
+derivatives of the output array components with respect to the input array components.
+
+\f[\begin{array}{l} \theta \leftarrow norm(r) \\ r \leftarrow r/ \theta \\ R = \cos{\theta} I + (1- \cos{\theta} ) r r^T + \sin{\theta} \vecthreethree{0}{-r_z}{r_y}{r_z}{0}{-r_x}{-r_y}{r_x}{0} \end{array}\f]
+
+Inverse transformation can be also done easily, since
+
+\f[\sin ( \theta ) \vecthreethree{0}{-r_z}{r_y}{r_z}{0}{-r_x}{-r_y}{r_x}{0} = \frac{R - R^T}{2}\f]
+
+A rotation vector is a convenient and most compact representation of a rotation matrix (since any
+rotation matrix has just 3 degrees of freedom). The representation is used in the global 3D geometry
+optimization procedures like calibrateCamera, stereoCalibrate, or solvePnP .
+ */
+CV_EXPORTS_W void Rodrigues( InputArray src, OutputArray dst, OutputArray jacobian = noArray() );
+
+/** @brief Finds a perspective transformation between two planes.
+
+@param srcPoints Coordinates of the points in the original plane, a matrix of the type CV_32FC2
+or vector\ .
+@param dstPoints Coordinates of the points in the target plane, a matrix of the type CV_32FC2 or
+a vector\ .
+@param method Method used to computed a homography matrix. The following methods are possible:
+- **0** - a regular method using all the points
+- **RANSAC** - RANSAC-based robust method
+- **LMEDS** - Least-Median robust method
+- **RHO** - PROSAC-based robust method
+@param ransacReprojThreshold Maximum allowed reprojection error to treat a point pair as an inlier
+(used in the RANSAC and RHO methods only). That is, if
+\f[\| \texttt{dstPoints} _i - \texttt{convertPointsHomogeneous} ( \texttt{H} * \texttt{srcPoints} _i) \| > \texttt{ransacReprojThreshold}\f]
+then the point \f$i\f$ is considered an outlier. If srcPoints and dstPoints are measured in pixels,
+it usually makes sense to set this parameter somewhere in the range of 1 to 10.
+@param mask Optional output mask set by a robust method ( RANSAC or LMEDS ). Note that the input
+mask values are ignored.
+@param maxIters The maximum number of RANSAC iterations, 2000 is the maximum it can be.
+@param confidence Confidence level, between 0 and 1.
+
+The functions find and return the perspective transformation \f$H\f$ between the source and the
+destination planes:
+
+\f[s_i \vecthree{x'_i}{y'_i}{1} \sim H \vecthree{x_i}{y_i}{1}\f]
+
+so that the back-projection error
+
+\f[\sum _i \left ( x'_i- \frac{h_{11} x_i + h_{12} y_i + h_{13}}{h_{31} x_i + h_{32} y_i + h_{33}} \right )^2+ \left ( y'_i- \frac{h_{21} x_i + h_{22} y_i + h_{23}}{h_{31} x_i + h_{32} y_i + h_{33}} \right )^2\f]
+
+is minimized. If the parameter method is set to the default value 0, the function uses all the point
+pairs to compute an initial homography estimate with a simple least-squares scheme.
+
+However, if not all of the point pairs ( \f$srcPoints_i\f$, \f$dstPoints_i\f$ ) fit the rigid perspective
+transformation (that is, there are some outliers), this initial estimate will be poor. In this case,
+you can use one of the three robust methods. The methods RANSAC, LMeDS and RHO try many different
+random subsets of the corresponding point pairs (of four pairs each), estimate the homography matrix
+using this subset and a simple least-square algorithm, and then compute the quality/goodness of the
+computed homography (which is the number of inliers for RANSAC or the median re-projection error for
+LMeDs). The best subset is then used to produce the initial estimate of the homography matrix and
+the mask of inliers/outliers.
+
+Regardless of the method, robust or not, the computed homography matrix is refined further (using
+inliers only in case of a robust method) with the Levenberg-Marquardt method to reduce the
+re-projection error even more.
+
+The methods RANSAC and RHO can handle practically any ratio of outliers but need a threshold to
+distinguish inliers from outliers. The method LMeDS does not need any threshold but it works
+correctly only when there are more than 50% of inliers. Finally, if there are no outliers and the
+noise is rather small, use the default method (method=0).
+
+The function is used to find initial intrinsic and extrinsic matrices. Homography matrix is
+determined up to a scale. Thus, it is normalized so that \f$h_{33}=1\f$. Note that whenever an H matrix
+cannot be estimated, an empty one will be returned.
+
+@sa
+ getAffineTransform, getPerspectiveTransform, estimateRigidTransform, warpPerspective,
+ perspectiveTransform
+
+@note
+ - A example on calculating a homography for image matching can be found at
+ opencv_source_code/samples/cpp/video_homography.cpp
+
+ */
+CV_EXPORTS_W Mat findHomography( InputArray srcPoints, InputArray dstPoints,
+ int method = 0, double ransacReprojThreshold = 3,
+ OutputArray mask=noArray(), const int maxIters = 2000,
+ const double confidence = 0.995);
+
+/** @overload */
+CV_EXPORTS Mat findHomography( InputArray srcPoints, InputArray dstPoints,
+ OutputArray mask, int method = 0, double ransacReprojThreshold = 3 );
+
+/** @brief Computes an RQ decomposition of 3x3 matrices.
+
+@param src 3x3 input matrix.
+@param mtxR Output 3x3 upper-triangular matrix.
+@param mtxQ Output 3x3 orthogonal matrix.
+@param Qx Optional output 3x3 rotation matrix around x-axis.
+@param Qy Optional output 3x3 rotation matrix around y-axis.
+@param Qz Optional output 3x3 rotation matrix around z-axis.
+
+The function computes a RQ decomposition using the given rotations. This function is used in
+decomposeProjectionMatrix to decompose the left 3x3 submatrix of a projection matrix into a camera
+and a rotation matrix.
+
+It optionally returns three rotation matrices, one for each axis, and the three Euler angles in
+degrees (as the return value) that could be used in OpenGL. Note, there is always more than one
+sequence of rotations about the three principle axes that results in the same orientation of an
+object, eg. see @cite Slabaugh . Returned tree rotation matrices and corresponding three Euler angules
+are only one of the possible solutions.
+ */
+CV_EXPORTS_W Vec3d RQDecomp3x3( InputArray src, OutputArray mtxR, OutputArray mtxQ,
+ OutputArray Qx = noArray(),
+ OutputArray Qy = noArray(),
+ OutputArray Qz = noArray());
+
+/** @brief Decomposes a projection matrix into a rotation matrix and a camera matrix.
+
+@param projMatrix 3x4 input projection matrix P.
+@param cameraMatrix Output 3x3 camera matrix K.
+@param rotMatrix Output 3x3 external rotation matrix R.
+@param transVect Output 4x1 translation vector T.
+@param rotMatrixX Optional 3x3 rotation matrix around x-axis.
+@param rotMatrixY Optional 3x3 rotation matrix around y-axis.
+@param rotMatrixZ Optional 3x3 rotation matrix around z-axis.
+@param eulerAngles Optional three-element vector containing three Euler angles of rotation in
+degrees.
+
+The function computes a decomposition of a projection matrix into a calibration and a rotation
+matrix and the position of a camera.
+
+It optionally returns three rotation matrices, one for each axis, and three Euler angles that could
+be used in OpenGL. Note, there is always more than one sequence of rotations about the three
+principle axes that results in the same orientation of an object, eg. see @cite Slabaugh . Returned
+tree rotation matrices and corresponding three Euler angules are only one of the possible solutions.
+
+The function is based on RQDecomp3x3 .
+ */
+CV_EXPORTS_W void decomposeProjectionMatrix( InputArray projMatrix, OutputArray cameraMatrix,
+ OutputArray rotMatrix, OutputArray transVect,
+ OutputArray rotMatrixX = noArray(),
+ OutputArray rotMatrixY = noArray(),
+ OutputArray rotMatrixZ = noArray(),
+ OutputArray eulerAngles =noArray() );
+
+/** @brief Computes partial derivatives of the matrix product for each multiplied matrix.
+
+@param A First multiplied matrix.
+@param B Second multiplied matrix.
+@param dABdA First output derivative matrix d(A\*B)/dA of size
+\f$\texttt{A.rows*B.cols} \times {A.rows*A.cols}\f$ .
+@param dABdB Second output derivative matrix d(A\*B)/dB of size
+\f$\texttt{A.rows*B.cols} \times {B.rows*B.cols}\f$ .
+
+The function computes partial derivatives of the elements of the matrix product \f$A*B\f$ with regard to
+the elements of each of the two input matrices. The function is used to compute the Jacobian
+matrices in stereoCalibrate but can also be used in any other similar optimization function.
+ */
+CV_EXPORTS_W void matMulDeriv( InputArray A, InputArray B, OutputArray dABdA, OutputArray dABdB );
+
+/** @brief Combines two rotation-and-shift transformations.
+
+@param rvec1 First rotation vector.
+@param tvec1 First translation vector.
+@param rvec2 Second rotation vector.
+@param tvec2 Second translation vector.
+@param rvec3 Output rotation vector of the superposition.
+@param tvec3 Output translation vector of the superposition.
+@param dr3dr1
+@param dr3dt1
+@param dr3dr2
+@param dr3dt2
+@param dt3dr1
+@param dt3dt1
+@param dt3dr2
+@param dt3dt2 Optional output derivatives of rvec3 or tvec3 with regard to rvec1, rvec2, tvec1 and
+tvec2, respectively.
+
+The functions compute:
+
+\f[\begin{array}{l} \texttt{rvec3} = \mathrm{rodrigues} ^{-1} \left ( \mathrm{rodrigues} ( \texttt{rvec2} ) \cdot \mathrm{rodrigues} ( \texttt{rvec1} ) \right ) \\ \texttt{tvec3} = \mathrm{rodrigues} ( \texttt{rvec2} ) \cdot \texttt{tvec1} + \texttt{tvec2} \end{array} ,\f]
+
+where \f$\mathrm{rodrigues}\f$ denotes a rotation vector to a rotation matrix transformation, and
+\f$\mathrm{rodrigues}^{-1}\f$ denotes the inverse transformation. See Rodrigues for details.
+
+Also, the functions can compute the derivatives of the output vectors with regards to the input
+vectors (see matMulDeriv ). The functions are used inside stereoCalibrate but can also be used in
+your own code where Levenberg-Marquardt or another gradient-based solver is used to optimize a
+function that contains a matrix multiplication.
+ */
+CV_EXPORTS_W void composeRT( InputArray rvec1, InputArray tvec1,
+ InputArray rvec2, InputArray tvec2,
+ OutputArray rvec3, OutputArray tvec3,
+ OutputArray dr3dr1 = noArray(), OutputArray dr3dt1 = noArray(),
+ OutputArray dr3dr2 = noArray(), OutputArray dr3dt2 = noArray(),
+ OutputArray dt3dr1 = noArray(), OutputArray dt3dt1 = noArray(),
+ OutputArray dt3dr2 = noArray(), OutputArray dt3dt2 = noArray() );
+
+/** @brief Projects 3D points to an image plane.
+
+@param objectPoints Array of object points, 3xN/Nx3 1-channel or 1xN/Nx1 3-channel (or
+vector\ ), where N is the number of points in the view.
+@param rvec Rotation vector. See Rodrigues for details.
+@param tvec Translation vector.
+@param cameraMatrix Camera matrix \f$A = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{_1}\f$ .
+@param distCoeffs Input vector of distortion coefficients
+\f$(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6 [, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\f$ of
+4, 5, 8, 12 or 14 elements. If the vector is empty, the zero distortion coefficients are assumed.
+@param imagePoints Output array of image points, 2xN/Nx2 1-channel or 1xN/Nx1 2-channel, or
+vector\ .
+@param jacobian Optional output 2Nx(10+\) jacobian matrix of derivatives of image
+points with respect to components of the rotation vector, translation vector, focal lengths,
+coordinates of the principal point and the distortion coefficients. In the old interface different
+components of the jacobian are returned via different output parameters.
+@param aspectRatio Optional "fixed aspect ratio" parameter. If the parameter is not 0, the
+function assumes that the aspect ratio (*fx/fy*) is fixed and correspondingly adjusts the jacobian
+matrix.
+
+The function computes projections of 3D points to the image plane given intrinsic and extrinsic
+camera parameters. Optionally, the function computes Jacobians - matrices of partial derivatives of
+image points coordinates (as functions of all the input parameters) with respect to the particular
+parameters, intrinsic and/or extrinsic. The Jacobians are used during the global optimization in
+calibrateCamera, solvePnP, and stereoCalibrate . The function itself can also be used to compute a
+re-projection error given the current intrinsic and extrinsic parameters.
+
+@note By setting rvec=tvec=(0,0,0) or by setting cameraMatrix to a 3x3 identity matrix, or by
+passing zero distortion coefficients, you can get various useful partial cases of the function. This
+means that you can compute the distorted coordinates for a sparse set of points or apply a
+perspective transformation (and also compute the derivatives) in the ideal zero-distortion setup.
+ */
+CV_EXPORTS_W void projectPoints( InputArray objectPoints,
+ InputArray rvec, InputArray tvec,
+ InputArray cameraMatrix, InputArray distCoeffs,
+ OutputArray imagePoints,
+ OutputArray jacobian = noArray(),
+ double aspectRatio = 0 );
+
+/** @brief Finds an object pose from 3D-2D point correspondences.
+
+@param objectPoints Array of object points in the object coordinate space, 3xN/Nx3 1-channel or
+1xN/Nx1 3-channel, where N is the number of points. vector\ can be also passed here.
+@param imagePoints Array of corresponding image points, 2xN/Nx2 1-channel or 1xN/Nx1 2-channel,
+where N is the number of points. vector\ can be also passed here.
+@param cameraMatrix Input camera matrix \f$A = \vecthreethree{fx}{0}{cx}{0}{fy}{cy}{0}{0}{1}\f$ .
+@param distCoeffs Input vector of distortion coefficients
+\f$(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6 [, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\f$ of
+4, 5, 8, 12 or 14 elements. If the vector is NULL/empty, the zero distortion coefficients are
+assumed.
+@param rvec Output rotation vector (see Rodrigues ) that, together with tvec , brings points from
+the model coordinate system to the camera coordinate system.
+@param tvec Output translation vector.
+@param useExtrinsicGuess Parameter used for SOLVEPNP_ITERATIVE. If true (1), the function uses
+the provided rvec and tvec values as initial approximations of the rotation and translation
+vectors, respectively, and further optimizes them.
+@param flags Method for solving a PnP problem:
+- **SOLVEPNP_ITERATIVE** Iterative method is based on Levenberg-Marquardt optimization. In
+this case the function finds such a pose that minimizes reprojection error, that is the sum
+of squared distances between the observed projections imagePoints and the projected (using
+projectPoints ) objectPoints .
+- **SOLVEPNP_P3P** Method is based on the paper of X.S. Gao, X.-R. Hou, J. Tang, H.-F. Chang
+"Complete Solution Classification for the Perspective-Three-Point Problem". In this case the
+function requires exactly four object and image points.
+- **SOLVEPNP_EPNP** Method has been introduced by F.Moreno-Noguer, V.Lepetit and P.Fua in the
+paper "EPnP: Efficient Perspective-n-Point Camera Pose Estimation".
+- **SOLVEPNP_DLS** Method is based on the paper of Joel A. Hesch and Stergios I. Roumeliotis.
+"A Direct Least-Squares (DLS) Method for PnP".
+- **SOLVEPNP_UPNP** Method is based on the paper of A.Penate-Sanchez, J.Andrade-Cetto,
+F.Moreno-Noguer. "Exhaustive Linearization for Robust Camera Pose and Focal Length
+Estimation". In this case the function also estimates the parameters \f$f_x\f$ and \f$f_y\f$
+assuming that both have the same value. Then the cameraMatrix is updated with the estimated
+focal length.
+
+The function estimates the object pose given a set of object points, their corresponding image
+projections, as well as the camera matrix and the distortion coefficients.
+
+@note
+ - An example of how to use solvePnP for planar augmented reality can be found at
+ opencv_source_code/samples/python/plane_ar.py
+ - If you are using Python:
+ - Numpy array slices won't work as input because solvePnP requires contiguous
+ arrays (enforced by the assertion using cv::Mat::checkVector() around line 55 of
+ modules/calib3d/src/solvepnp.cpp version 2.4.9)
+ - The P3P algorithm requires image points to be in an array of shape (N,1,2) due
+ to its calling of cv::undistortPoints (around line 75 of modules/calib3d/src/solvepnp.cpp version 2.4.9)
+ which requires 2-channel information.
+ - Thus, given some data D = np.array(...) where D.shape = (N,M), in order to use a subset of
+ it as, e.g., imagePoints, one must effectively copy it into a new array: imagePoints =
+ np.ascontiguousarray(D[:,:2]).reshape((N,1,2))
+ */
+CV_EXPORTS_W bool solvePnP( InputArray objectPoints, InputArray imagePoints,
+ InputArray cameraMatrix, InputArray distCoeffs,
+ OutputArray rvec, OutputArray tvec,
+ bool useExtrinsicGuess = false, int flags = SOLVEPNP_ITERATIVE );
+
+/** @brief Finds an object pose from 3D-2D point correspondences using the RANSAC scheme.
+
+@param objectPoints Array of object points in the object coordinate space, 3xN/Nx3 1-channel or
+1xN/Nx1 3-channel, where N is the number of points. vector\ can be also passed here.
+@param imagePoints Array of corresponding image points, 2xN/Nx2 1-channel or 1xN/Nx1 2-channel,
+where N is the number of points. vector\ can be also passed here.
+@param cameraMatrix Input camera matrix \f$A = \vecthreethree{fx}{0}{cx}{0}{fy}{cy}{0}{0}{1}\f$ .
+@param distCoeffs Input vector of distortion coefficients
+\f$(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6 [, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\f$ of
+4, 5, 8, 12 or 14 elements. If the vector is NULL/empty, the zero distortion coefficients are
+assumed.
+@param rvec Output rotation vector (see Rodrigues ) that, together with tvec , brings points from
+the model coordinate system to the camera coordinate system.
+@param tvec Output translation vector.
+@param useExtrinsicGuess Parameter used for SOLVEPNP_ITERATIVE. If true (1), the function uses
+the provided rvec and tvec values as initial approximations of the rotation and translation
+vectors, respectively, and further optimizes them.
+@param iterationsCount Number of iterations.
+@param reprojectionError Inlier threshold value used by the RANSAC procedure. The parameter value
+is the maximum allowed distance between the observed and computed point projections to consider it
+an inlier.
+@param confidence The probability that the algorithm produces a useful result.
+@param inliers Output vector that contains indices of inliers in objectPoints and imagePoints .
+@param flags Method for solving a PnP problem (see solvePnP ).
+
+The function estimates an object pose given a set of object points, their corresponding image
+projections, as well as the camera matrix and the distortion coefficients. This function finds such
+a pose that minimizes reprojection error, that is, the sum of squared distances between the observed
+projections imagePoints and the projected (using projectPoints ) objectPoints. The use of RANSAC
+makes the function resistant to outliers.
+
+@note
+ - An example of how to use solvePNPRansac for object detection can be found at
+ opencv_source_code/samples/cpp/tutorial_code/calib3d/real_time_pose_estimation/
+ */
+CV_EXPORTS_W bool solvePnPRansac( InputArray objectPoints, InputArray imagePoints,
+ InputArray cameraMatrix, InputArray distCoeffs,
+ OutputArray rvec, OutputArray tvec,
+ bool useExtrinsicGuess = false, int iterationsCount = 100,
+ float reprojectionError = 8.0, double confidence = 0.99,
+ OutputArray inliers = noArray(), int flags = SOLVEPNP_ITERATIVE );
+
+/** @brief Finds an initial camera matrix from 3D-2D point correspondences.
+
+@param objectPoints Vector of vectors of the calibration pattern points in the calibration pattern
+coordinate space. In the old interface all the per-view vectors are concatenated. See
+calibrateCamera for details.
+@param imagePoints Vector of vectors of the projections of the calibration pattern points. In the
+old interface all the per-view vectors are concatenated.
+@param imageSize Image size in pixels used to initialize the principal point.
+@param aspectRatio If it is zero or negative, both \f$f_x\f$ and \f$f_y\f$ are estimated independently.
+Otherwise, \f$f_x = f_y * \texttt{aspectRatio}\f$ .
+
+The function estimates and returns an initial camera matrix for the camera calibration process.
+Currently, the function only supports planar calibration patterns, which are patterns where each
+object point has z-coordinate =0.
+ */
+CV_EXPORTS_W Mat initCameraMatrix2D( InputArrayOfArrays objectPoints,
+ InputArrayOfArrays imagePoints,
+ Size imageSize, double aspectRatio = 1.0 );
+
+/** @brief Finds the positions of internal corners of the chessboard.
+
+@param image Source chessboard view. It must be an 8-bit grayscale or color image.
+@param patternSize Number of inner corners per a chessboard row and column
+( patternSize = cvSize(points_per_row,points_per_colum) = cvSize(columns,rows) ).
+@param corners Output array of detected corners.
+@param flags Various operation flags that can be zero or a combination of the following values:
+- **CV_CALIB_CB_ADAPTIVE_THRESH** Use adaptive thresholding to convert the image to black
+and white, rather than a fixed threshold level (computed from the average image brightness).
+- **CV_CALIB_CB_NORMALIZE_IMAGE** Normalize the image gamma with equalizeHist before
+applying fixed or adaptive thresholding.
+- **CV_CALIB_CB_FILTER_QUADS** Use additional criteria (like contour area, perimeter,
+square-like shape) to filter out false quads extracted at the contour retrieval stage.
+- **CALIB_CB_FAST_CHECK** Run a fast check on the image that looks for chessboard corners,
+and shortcut the call if none is found. This can drastically speed up the call in the
+degenerate condition when no chessboard is observed.
+
+The function attempts to determine whether the input image is a view of the chessboard pattern and
+locate the internal chessboard corners. The function returns a non-zero value if all of the corners
+are found and they are placed in a certain order (row by row, left to right in every row).
+Otherwise, if the function fails to find all the corners or reorder them, it returns 0. For example,
+a regular chessboard has 8 x 8 squares and 7 x 7 internal corners, that is, points where the black
+squares touch each other. The detected coordinates are approximate, and to determine their positions
+more accurately, the function calls cornerSubPix. You also may use the function cornerSubPix with
+different parameters if returned coordinates are not accurate enough.
+
+Sample usage of detecting and drawing chessboard corners: :
+@code
+ Size patternsize(8,6); //interior number of corners
+ Mat gray = ....; //source image
+ vector corners; //this will be filled by the detected corners
+
+ //CALIB_CB_FAST_CHECK saves a lot of time on images
+ //that do not contain any chessboard corners
+ bool patternfound = findChessboardCorners(gray, patternsize, corners,
+ CALIB_CB_ADAPTIVE_THRESH + CALIB_CB_NORMALIZE_IMAGE
+ + CALIB_CB_FAST_CHECK);
+
+ if(patternfound)
+ cornerSubPix(gray, corners, Size(11, 11), Size(-1, -1),
+ TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 30, 0.1));
+
+ drawChessboardCorners(img, patternsize, Mat(corners), patternfound);
+@endcode
+@note The function requires white space (like a square-thick border, the wider the better) around
+the board to make the detection more robust in various environments. Otherwise, if there is no
+border and the background is dark, the outer black squares cannot be segmented properly and so the
+square grouping and ordering algorithm fails.
+ */
+CV_EXPORTS_W bool findChessboardCorners( InputArray image, Size patternSize, OutputArray corners,
+ int flags = CALIB_CB_ADAPTIVE_THRESH + CALIB_CB_NORMALIZE_IMAGE );
+
+//! finds subpixel-accurate positions of the chessboard corners
+CV_EXPORTS bool find4QuadCornerSubpix( InputArray img, InputOutputArray corners, Size region_size );
+
+/** @brief Renders the detected chessboard corners.
+
+@param image Destination image. It must be an 8-bit color image.
+@param patternSize Number of inner corners per a chessboard row and column
+(patternSize = cv::Size(points_per_row,points_per_column)).
+@param corners Array of detected corners, the output of findChessboardCorners.
+@param patternWasFound Parameter indicating whether the complete board was found or not. The
+return value of findChessboardCorners should be passed here.
+
+The function draws individual chessboard corners detected either as red circles if the board was not
+found, or as colored corners connected with lines if the board was found.
+ */
+CV_EXPORTS_W void drawChessboardCorners( InputOutputArray image, Size patternSize,
+ InputArray corners, bool patternWasFound );
+
+/** @brief Finds centers in the grid of circles.
+
+@param image grid view of input circles; it must be an 8-bit grayscale or color image.
+@param patternSize number of circles per row and column
+( patternSize = Size(points_per_row, points_per_colum) ).
+@param centers output array of detected centers.
+@param flags various operation flags that can be one of the following values:
+- **CALIB_CB_SYMMETRIC_GRID** uses symmetric pattern of circles.
+- **CALIB_CB_ASYMMETRIC_GRID** uses asymmetric pattern of circles.
+- **CALIB_CB_CLUSTERING** uses a special algorithm for grid detection. It is more robust to
+perspective distortions but much more sensitive to background clutter.
+@param blobDetector feature detector that finds blobs like dark circles on light background.
+
+The function attempts to determine whether the input image contains a grid of circles. If it is, the
+function locates centers of the circles. The function returns a non-zero value if all of the centers
+have been found and they have been placed in a certain order (row by row, left to right in every
+row). Otherwise, if the function fails to find all the corners or reorder them, it returns 0.
+
+Sample usage of detecting and drawing the centers of circles: :
+@code
+ Size patternsize(7,7); //number of centers
+ Mat gray = ....; //source image
+ vector centers; //this will be filled by the detected centers
+
+ bool patternfound = findCirclesGrid(gray, patternsize, centers);
+
+ drawChessboardCorners(img, patternsize, Mat(centers), patternfound);
+@endcode
+@note The function requires white space (like a square-thick border, the wider the better) around
+the board to make the detection more robust in various environments.
+ */
+CV_EXPORTS_W bool findCirclesGrid( InputArray image, Size patternSize,
+ OutputArray centers, int flags = CALIB_CB_SYMMETRIC_GRID,
+ const Ptr &blobDetector = SimpleBlobDetector::create());
+
+/** @brief Finds the camera intrinsic and extrinsic parameters from several views of a calibration pattern.
+
+@param objectPoints In the new interface it is a vector of vectors of calibration pattern points in
+the calibration pattern coordinate space (e.g. std::vector>). The outer
+vector contains as many elements as the number of the pattern views. If the same calibration pattern
+is shown in each view and it is fully visible, all the vectors will be the same. Although, it is
+possible to use partially occluded patterns, or even different patterns in different views. Then,
+the vectors will be different. The points are 3D, but since they are in a pattern coordinate system,
+then, if the rig is planar, it may make sense to put the model to a XY coordinate plane so that
+Z-coordinate of each input object point is 0.
+In the old interface all the vectors of object points from different views are concatenated
+together.
+@param imagePoints In the new interface it is a vector of vectors of the projections of calibration
+pattern points (e.g. std::vector>). imagePoints.size() and
+objectPoints.size() and imagePoints[i].size() must be equal to objectPoints[i].size() for each i.
+In the old interface all the vectors of object points from different views are concatenated
+together.
+@param imageSize Size of the image used only to initialize the intrinsic camera matrix.
+@param cameraMatrix Output 3x3 floating-point camera matrix
+\f$A = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\f$ . If CV\_CALIB\_USE\_INTRINSIC\_GUESS
+and/or CV_CALIB_FIX_ASPECT_RATIO are specified, some or all of fx, fy, cx, cy must be
+initialized before calling the function.
+@param distCoeffs Output vector of distortion coefficients
+\f$(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6 [, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\f$ of
+4, 5, 8, 12 or 14 elements.
+@param rvecs Output vector of rotation vectors (see Rodrigues ) estimated for each pattern view
+(e.g. std::vector>). That is, each k-th rotation vector together with the corresponding
+k-th translation vector (see the next output parameter description) brings the calibration pattern
+from the model coordinate space (in which object points are specified) to the world coordinate
+space, that is, a real position of the calibration pattern in the k-th pattern view (k=0.. *M* -1).
+@param tvecs Output vector of translation vectors estimated for each pattern view.
+@param flags Different flags that may be zero or a combination of the following values:
+- **CV_CALIB_USE_INTRINSIC_GUESS** cameraMatrix contains valid initial values of
+fx, fy, cx, cy that are optimized further. Otherwise, (cx, cy) is initially set to the image
+center ( imageSize is used), and focal distances are computed in a least-squares fashion.
+Note, that if intrinsic parameters are known, there is no need to use this function just to
+estimate extrinsic parameters. Use solvePnP instead.
+- **CV_CALIB_FIX_PRINCIPAL_POINT** The principal point is not changed during the global
+optimization. It stays at the center or at a different location specified when
+CV_CALIB_USE_INTRINSIC_GUESS is set too.
+- **CV_CALIB_FIX_ASPECT_RATIO** The functions considers only fy as a free parameter. The
+ratio fx/fy stays the same as in the input cameraMatrix . When
+CV_CALIB_USE_INTRINSIC_GUESS is not set, the actual input values of fx and fy are
+ignored, only their ratio is computed and used further.
+- **CV_CALIB_ZERO_TANGENT_DIST** Tangential distortion coefficients \f$(p_1, p_2)\f$ are set
+to zeros and stay zero.
+- **CV_CALIB_FIX_K1,...,CV_CALIB_FIX_K6** The corresponding radial distortion
+coefficient is not changed during the optimization. If CV_CALIB_USE_INTRINSIC_GUESS is
+set, the coefficient from the supplied distCoeffs matrix is used. Otherwise, it is set to 0.
+- **CV_CALIB_RATIONAL_MODEL** Coefficients k4, k5, and k6 are enabled. To provide the
+backward compatibility, this extra flag should be explicitly specified to make the
+calibration function use the rational model and return 8 coefficients. If the flag is not
+set, the function computes and returns only 5 distortion coefficients.
+- **CALIB_THIN_PRISM_MODEL** Coefficients s1, s2, s3 and s4 are enabled. To provide the
+backward compatibility, this extra flag should be explicitly specified to make the
+calibration function use the thin prism model and return 12 coefficients. If the flag is not
+set, the function computes and returns only 5 distortion coefficients.
+- **CALIB_FIX_S1_S2_S3_S4** The thin prism distortion coefficients are not changed during
+the optimization. If CV_CALIB_USE_INTRINSIC_GUESS is set, the coefficient from the
+supplied distCoeffs matrix is used. Otherwise, it is set to 0.
+- **CALIB_TILTED_MODEL** Coefficients tauX and tauY are enabled. To provide the
+backward compatibility, this extra flag should be explicitly specified to make the
+calibration function use the tilted sensor model and return 14 coefficients. If the flag is not
+set, the function computes and returns only 5 distortion coefficients.
+- **CALIB_FIX_TAUX_TAUY** The coefficients of the tilted sensor model are not changed during
+the optimization. If CV_CALIB_USE_INTRINSIC_GUESS is set, the coefficient from the
+supplied distCoeffs matrix is used. Otherwise, it is set to 0.
+@param criteria Termination criteria for the iterative optimization algorithm.
+
+The function estimates the intrinsic camera parameters and extrinsic parameters for each of the
+views. The algorithm is based on @cite Zhang2000 and @cite BouguetMCT . The coordinates of 3D object
+points and their corresponding 2D projections in each view must be specified. That may be achieved
+by using an object with a known geometry and easily detectable feature points. Such an object is
+called a calibration rig or calibration pattern, and OpenCV has built-in support for a chessboard as
+a calibration rig (see findChessboardCorners ). Currently, initialization of intrinsic parameters
+(when CV_CALIB_USE_INTRINSIC_GUESS is not set) is only implemented for planar calibration
+patterns (where Z-coordinates of the object points must be all zeros). 3D calibration rigs can also
+be used as long as initial cameraMatrix is provided.
+
+The algorithm performs the following steps:
+
+- Compute the initial intrinsic parameters (the option only available for planar calibration
+ patterns) or read them from the input parameters. The distortion coefficients are all set to
+ zeros initially unless some of CV_CALIB_FIX_K? are specified.
+
+- Estimate the initial camera pose as if the intrinsic parameters have been already known. This is
+ done using solvePnP .
+
+- Run the global Levenberg-Marquardt optimization algorithm to minimize the reprojection error,
+ that is, the total sum of squared distances between the observed feature points imagePoints and
+ the projected (using the current estimates for camera parameters and the poses) object points
+ objectPoints. See projectPoints for details.
+
+The function returns the final re-projection error.
+
+@note
+ If you use a non-square (=non-NxN) grid and findChessboardCorners for calibration, and
+ calibrateCamera returns bad values (zero distortion coefficients, an image center very far from
+ (w/2-0.5,h/2-0.5), and/or large differences between \f$f_x\f$ and \f$f_y\f$ (ratios of 10:1 or more)),
+ then you have probably used patternSize=cvSize(rows,cols) instead of using
+ patternSize=cvSize(cols,rows) in findChessboardCorners .
+
+@sa
+ findChessboardCorners, solvePnP, initCameraMatrix2D, stereoCalibrate, undistort
+ */
+CV_EXPORTS_W double calibrateCamera( InputArrayOfArrays objectPoints,
+ InputArrayOfArrays imagePoints, Size imageSize,
+ InputOutputArray cameraMatrix, InputOutputArray distCoeffs,
+ OutputArrayOfArrays rvecs, OutputArrayOfArrays tvecs,
+ int flags = 0, TermCriteria criteria = TermCriteria(
+ TermCriteria::COUNT + TermCriteria::EPS, 30, DBL_EPSILON) );
+
+/** @brief Computes useful camera characteristics from the camera matrix.
+
+@param cameraMatrix Input camera matrix that can be estimated by calibrateCamera or
+stereoCalibrate .
+@param imageSize Input image size in pixels.
+@param apertureWidth Physical width in mm of the sensor.
+@param apertureHeight Physical height in mm of the sensor.
+@param fovx Output field of view in degrees along the horizontal sensor axis.
+@param fovy Output field of view in degrees along the vertical sensor axis.
+@param focalLength Focal length of the lens in mm.
+@param principalPoint Principal point in mm.
+@param aspectRatio \f$f_y/f_x\f$
+
+The function computes various useful camera characteristics from the previously estimated camera
+matrix.
+
+@note
+ Do keep in mind that the unity measure 'mm' stands for whatever unit of measure one chooses for
+ the chessboard pitch (it can thus be any value).
+ */
+CV_EXPORTS_W void calibrationMatrixValues( InputArray cameraMatrix, Size imageSize,
+ double apertureWidth, double apertureHeight,
+ CV_OUT double& fovx, CV_OUT double& fovy,
+ CV_OUT double& focalLength, CV_OUT Point2d& principalPoint,
+ CV_OUT double& aspectRatio );
+
+/** @brief Calibrates the stereo camera.
+
+@param objectPoints Vector of vectors of the calibration pattern points.
+@param imagePoints1 Vector of vectors of the projections of the calibration pattern points,
+observed by the first camera.
+@param imagePoints2 Vector of vectors of the projections of the calibration pattern points,
+observed by the second camera.
+@param cameraMatrix1 Input/output first camera matrix:
+\f$\vecthreethree{f_x^{(j)}}{0}{c_x^{(j)}}{0}{f_y^{(j)}}{c_y^{(j)}}{0}{0}{1}\f$ , \f$j = 0,\, 1\f$ . If
+any of CV_CALIB_USE_INTRINSIC_GUESS , CV_CALIB_FIX_ASPECT_RATIO ,
+CV_CALIB_FIX_INTRINSIC , or CV_CALIB_FIX_FOCAL_LENGTH are specified, some or all of the
+matrix components must be initialized. See the flags description for details.
+@param distCoeffs1 Input/output vector of distortion coefficients
+\f$(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6 [, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\f$ of
+4, 5, 8, 12 or 14 elements. The output vector length depends on the flags.
+@param cameraMatrix2 Input/output second camera matrix. The parameter is similar to cameraMatrix1
+@param distCoeffs2 Input/output lens distortion coefficients for the second camera. The parameter
+is similar to distCoeffs1 .
+@param imageSize Size of the image used only to initialize intrinsic camera matrix.
+@param R Output rotation matrix between the 1st and the 2nd camera coordinate systems.
+@param T Output translation vector between the coordinate systems of the cameras.
+@param E Output essential matrix.
+@param F Output fundamental matrix.
+@param flags Different flags that may be zero or a combination of the following values:
+- **CV_CALIB_FIX_INTRINSIC** Fix cameraMatrix? and distCoeffs? so that only R, T, E , and F
+matrices are estimated.
+- **CV_CALIB_USE_INTRINSIC_GUESS** Optimize some or all of the intrinsic parameters
+according to the specified flags. Initial values are provided by the user.
+- **CV_CALIB_FIX_PRINCIPAL_POINT** Fix the principal points during the optimization.
+- **CV_CALIB_FIX_FOCAL_LENGTH** Fix \f$f^{(j)}_x\f$ and \f$f^{(j)}_y\f$ .
+- **CV_CALIB_FIX_ASPECT_RATIO** Optimize \f$f^{(j)}_y\f$ . Fix the ratio \f$f^{(j)}_x/f^{(j)}_y\f$
+.
+- **CV_CALIB_SAME_FOCAL_LENGTH** Enforce \f$f^{(0)}_x=f^{(1)}_x\f$ and \f$f^{(0)}_y=f^{(1)}_y\f$ .
+- **CV_CALIB_ZERO_TANGENT_DIST** Set tangential distortion coefficients for each camera to
+zeros and fix there.
+- **CV_CALIB_FIX_K1,...,CV_CALIB_FIX_K6** Do not change the corresponding radial
+distortion coefficient during the optimization. If CV_CALIB_USE_INTRINSIC_GUESS is set,
+the coefficient from the supplied distCoeffs matrix is used. Otherwise, it is set to 0.
+- **CV_CALIB_RATIONAL_MODEL** Enable coefficients k4, k5, and k6. To provide the backward
+compatibility, this extra flag should be explicitly specified to make the calibration
+function use the rational model and return 8 coefficients. If the flag is not set, the
+function computes and returns only 5 distortion coefficients.
+- **CALIB_THIN_PRISM_MODEL** Coefficients s1, s2, s3 and s4 are enabled. To provide the
+backward compatibility, this extra flag should be explicitly specified to make the
+calibration function use the thin prism model and return 12 coefficients. If the flag is not
+set, the function computes and returns only 5 distortion coefficients.
+- **CALIB_FIX_S1_S2_S3_S4** The thin prism distortion coefficients are not changed during
+the optimization. If CV_CALIB_USE_INTRINSIC_GUESS is set, the coefficient from the
+supplied distCoeffs matrix is used. Otherwise, it is set to 0.
+- **CALIB_TILTED_MODEL** Coefficients tauX and tauY are enabled. To provide the
+backward compatibility, this extra flag should be explicitly specified to make the
+calibration function use the tilted sensor model and return 14 coefficients. If the flag is not
+set, the function computes and returns only 5 distortion coefficients.
+- **CALIB_FIX_TAUX_TAUY** The coefficients of the tilted sensor model are not changed during
+the optimization. If CV_CALIB_USE_INTRINSIC_GUESS is set, the coefficient from the
+supplied distCoeffs matrix is used. Otherwise, it is set to 0.
+@param criteria Termination criteria for the iterative optimization algorithm.
+
+The function estimates transformation between two cameras making a stereo pair. If you have a stereo
+camera where the relative position and orientation of two cameras is fixed, and if you computed
+poses of an object relative to the first camera and to the second camera, (R1, T1) and (R2, T2),
+respectively (this can be done with solvePnP ), then those poses definitely relate to each other.
+This means that, given ( \f$R_1\f$,\f$T_1\f$ ), it should be possible to compute ( \f$R_2\f$,\f$T_2\f$ ). You only
+need to know the position and orientation of the second camera relative to the first camera. This is
+what the described function does. It computes ( \f$R\f$,\f$T\f$ ) so that:
+
+\f[R_2=R*R_1
+T_2=R*T_1 + T,\f]
+
+Optionally, it computes the essential matrix E:
+
+\f[E= \vecthreethree{0}{-T_2}{T_1}{T_2}{0}{-T_0}{-T_1}{T_0}{0} *R\f]
+
+where \f$T_i\f$ are components of the translation vector \f$T\f$ : \f$T=[T_0, T_1, T_2]^T\f$ . And the function
+can also compute the fundamental matrix F:
+
+\f[F = cameraMatrix2^{-T} E cameraMatrix1^{-1}\f]
+
+Besides the stereo-related information, the function can also perform a full calibration of each of
+two cameras. However, due to the high dimensionality of the parameter space and noise in the input
+data, the function can diverge from the correct solution. If the intrinsic parameters can be
+estimated with high accuracy for each of the cameras individually (for example, using
+calibrateCamera ), you are recommended to do so and then pass CV_CALIB_FIX_INTRINSIC flag to the
+function along with the computed intrinsic parameters. Otherwise, if all the parameters are
+estimated at once, it makes sense to restrict some parameters, for example, pass
+CV_CALIB_SAME_FOCAL_LENGTH and CV_CALIB_ZERO_TANGENT_DIST flags, which is usually a
+reasonable assumption.
+
+Similarly to calibrateCamera , the function minimizes the total re-projection error for all the
+points in all the available views from both cameras. The function returns the final value of the
+re-projection error.
+ */
+CV_EXPORTS_W double stereoCalibrate( InputArrayOfArrays objectPoints,
+ InputArrayOfArrays imagePoints1, InputArrayOfArrays imagePoints2,
+ InputOutputArray cameraMatrix1, InputOutputArray distCoeffs1,
+ InputOutputArray cameraMatrix2, InputOutputArray distCoeffs2,
+ Size imageSize, OutputArray R,OutputArray T, OutputArray E, OutputArray F,
+ int flags = CALIB_FIX_INTRINSIC,
+ TermCriteria criteria = TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, 1e-6) );
+
+
+/** @brief Computes rectification transforms for each head of a calibrated stereo camera.
+
+@param cameraMatrix1 First camera matrix.
+@param distCoeffs1 First camera distortion parameters.
+@param cameraMatrix2 Second camera matrix.
+@param distCoeffs2 Second camera distortion parameters.
+@param imageSize Size of the image used for stereo calibration.
+@param R Rotation matrix between the coordinate systems of the first and the second cameras.
+@param T Translation vector between coordinate systems of the cameras.
+@param R1 Output 3x3 rectification transform (rotation matrix) for the first camera.
+@param R2 Output 3x3 rectification transform (rotation matrix) for the second camera.
+@param P1 Output 3x4 projection matrix in the new (rectified) coordinate systems for the first
+camera.
+@param P2 Output 3x4 projection matrix in the new (rectified) coordinate systems for the second
+camera.
+@param Q Output \f$4 \times 4\f$ disparity-to-depth mapping matrix (see reprojectImageTo3D ).
+@param flags Operation flags that may be zero or CV_CALIB_ZERO_DISPARITY . If the flag is set,
+the function makes the principal points of each camera have the same pixel coordinates in the
+rectified views. And if the flag is not set, the function may still shift the images in the
+horizontal or vertical direction (depending on the orientation of epipolar lines) to maximize the
+useful image area.
+@param alpha Free scaling parameter. If it is -1 or absent, the function performs the default
+scaling. Otherwise, the parameter should be between 0 and 1. alpha=0 means that the rectified
+images are zoomed and shifted so that only valid pixels are visible (no black areas after
+rectification). alpha=1 means that the rectified image is decimated and shifted so that all the
+pixels from the original images from the cameras are retained in the rectified images (no source
+image pixels are lost). Obviously, any intermediate value yields an intermediate result between
+those two extreme cases.
+@param newImageSize New image resolution after rectification. The same size should be passed to
+initUndistortRectifyMap (see the stereo_calib.cpp sample in OpenCV samples directory). When (0,0)
+is passed (default), it is set to the original imageSize . Setting it to larger value can help you
+preserve details in the original image, especially when there is a big radial distortion.
+@param validPixROI1 Optional output rectangles inside the rectified images where all the pixels
+are valid. If alpha=0 , the ROIs cover the whole images. Otherwise, they are likely to be smaller
+(see the picture below).
+@param validPixROI2 Optional output rectangles inside the rectified images where all the pixels
+are valid. If alpha=0 , the ROIs cover the whole images. Otherwise, they are likely to be smaller
+(see the picture below).
+
+The function computes the rotation matrices for each camera that (virtually) make both camera image
+planes the same plane. Consequently, this makes all the epipolar lines parallel and thus simplifies
+the dense stereo correspondence problem. The function takes the matrices computed by stereoCalibrate
+as input. As output, it provides two rotation matrices and also two projection matrices in the new
+coordinates. The function distinguishes the following two cases:
+
+- **Horizontal stereo**: the first and the second camera views are shifted relative to each other
+ mainly along the x axis (with possible small vertical shift). In the rectified images, the
+ corresponding epipolar lines in the left and right cameras are horizontal and have the same
+ y-coordinate. P1 and P2 look like:
+
+ \f[\texttt{P1} = \begin{bmatrix} f & 0 & cx_1 & 0 \\ 0 & f & cy & 0 \\ 0 & 0 & 1 & 0 \end{bmatrix}\f]
+
+ \f[\texttt{P2} = \begin{bmatrix} f & 0 & cx_2 & T_x*f \\ 0 & f & cy & 0 \\ 0 & 0 & 1 & 0 \end{bmatrix} ,\f]
+
+ where \f$T_x\f$ is a horizontal shift between the cameras and \f$cx_1=cx_2\f$ if
+ CV_CALIB_ZERO_DISPARITY is set.
+
+- **Vertical stereo**: the first and the second camera views are shifted relative to each other
+ mainly in vertical direction (and probably a bit in the horizontal direction too). The epipolar
+ lines in the rectified images are vertical and have the same x-coordinate. P1 and P2 look like:
+
+ \f[\texttt{P1} = \begin{bmatrix} f & 0 & cx & 0 \\ 0 & f & cy_1 & 0 \\ 0 & 0 & 1 & 0 \end{bmatrix}\f]
+
+ \f[\texttt{P2} = \begin{bmatrix} f & 0 & cx & 0 \\ 0 & f & cy_2 & T_y*f \\ 0 & 0 & 1 & 0 \end{bmatrix} ,\f]
+
+ where \f$T_y\f$ is a vertical shift between the cameras and \f$cy_1=cy_2\f$ if CALIB_ZERO_DISPARITY is
+ set.
+
+As you can see, the first three columns of P1 and P2 will effectively be the new "rectified" camera
+matrices. The matrices, together with R1 and R2 , can then be passed to initUndistortRectifyMap to
+initialize the rectification map for each camera.
+
+See below the screenshot from the stereo_calib.cpp sample. Some red horizontal lines pass through
+the corresponding image regions. This means that the images are well rectified, which is what most
+stereo correspondence algorithms rely on. The green rectangles are roi1 and roi2 . You see that
+their interiors are all valid pixels.
+
+
+ */
+CV_EXPORTS_W void stereoRectify( InputArray cameraMatrix1, InputArray distCoeffs1,
+ InputArray cameraMatrix2, InputArray distCoeffs2,
+ Size imageSize, InputArray R, InputArray T,
+ OutputArray R1, OutputArray R2,
+ OutputArray P1, OutputArray P2,
+ OutputArray Q, int flags = CALIB_ZERO_DISPARITY,
+ double alpha = -1, Size newImageSize = Size(),
+ CV_OUT Rect* validPixROI1 = 0, CV_OUT Rect* validPixROI2 = 0 );
+
+/** @brief Computes a rectification transform for an uncalibrated stereo camera.
+
+@param points1 Array of feature points in the first image.
+@param points2 The corresponding points in the second image. The same formats as in
+findFundamentalMat are supported.
+@param F Input fundamental matrix. It can be computed from the same set of point pairs using
+findFundamentalMat .
+@param imgSize Size of the image.
+@param H1 Output rectification homography matrix for the first image.
+@param H2 Output rectification homography matrix for the second image.
+@param threshold Optional threshold used to filter out the outliers. If the parameter is greater
+than zero, all the point pairs that do not comply with the epipolar geometry (that is, the points
+for which \f$|\texttt{points2[i]}^T*\texttt{F}*\texttt{points1[i]}|>\texttt{threshold}\f$ ) are
+rejected prior to computing the homographies. Otherwise,all the points are considered inliers.
+
+The function computes the rectification transformations without knowing intrinsic parameters of the
+cameras and their relative position in the space, which explains the suffix "uncalibrated". Another
+related difference from stereoRectify is that the function outputs not the rectification
+transformations in the object (3D) space, but the planar perspective transformations encoded by the
+homography matrices H1 and H2 . The function implements the algorithm @cite Hartley99 .
+
+@note
+ While the algorithm does not need to know the intrinsic parameters of the cameras, it heavily
+ depends on the epipolar geometry. Therefore, if the camera lenses have a significant distortion,
+ it would be better to correct it before computing the fundamental matrix and calling this
+ function. For example, distortion coefficients can be estimated for each head of stereo camera
+ separately by using calibrateCamera . Then, the images can be corrected using undistort , or
+ just the point coordinates can be corrected with undistortPoints .
+ */
+CV_EXPORTS_W bool stereoRectifyUncalibrated( InputArray points1, InputArray points2,
+ InputArray F, Size imgSize,
+ OutputArray H1, OutputArray H2,
+ double threshold = 5 );
+
+//! computes the rectification transformations for 3-head camera, where all the heads are on the same line.
+CV_EXPORTS_W float rectify3Collinear( InputArray cameraMatrix1, InputArray distCoeffs1,
+ InputArray cameraMatrix2, InputArray distCoeffs2,
+ InputArray cameraMatrix3, InputArray distCoeffs3,
+ InputArrayOfArrays imgpt1, InputArrayOfArrays imgpt3,
+ Size imageSize, InputArray R12, InputArray T12,
+ InputArray R13, InputArray T13,
+ OutputArray R1, OutputArray R2, OutputArray R3,
+ OutputArray P1, OutputArray P2, OutputArray P3,
+ OutputArray Q, double alpha, Size newImgSize,
+ CV_OUT Rect* roi1, CV_OUT Rect* roi2, int flags );
+
+/** @brief Returns the new camera matrix based on the free scaling parameter.
+
+@param cameraMatrix Input camera matrix.
+@param distCoeffs Input vector of distortion coefficients
+\f$(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6 [, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\f$ of
+4, 5, 8, 12 or 14 elements. If the vector is NULL/empty, the zero distortion coefficients are
+assumed.
+@param imageSize Original image size.
+@param alpha Free scaling parameter between 0 (when all the pixels in the undistorted image are
+valid) and 1 (when all the source image pixels are retained in the undistorted image). See
+stereoRectify for details.
+@param newImgSize Image size after rectification. By default,it is set to imageSize .
+@param validPixROI Optional output rectangle that outlines all-good-pixels region in the
+undistorted image. See roi1, roi2 description in stereoRectify .
+@param centerPrincipalPoint Optional flag that indicates whether in the new camera matrix the
+principal point should be at the image center or not. By default, the principal point is chosen to
+best fit a subset of the source image (determined by alpha) to the corrected image.
+@return new_camera_matrix Output new camera matrix.
+
+The function computes and returns the optimal new camera matrix based on the free scaling parameter.
+By varying this parameter, you may retrieve only sensible pixels alpha=0 , keep all the original
+image pixels if there is valuable information in the corners alpha=1 , or get something in between.
+When alpha\>0 , the undistortion result is likely to have some black pixels corresponding to
+"virtual" pixels outside of the captured distorted image. The original camera matrix, distortion
+coefficients, the computed new camera matrix, and newImageSize should be passed to
+initUndistortRectifyMap to produce the maps for remap .
+ */
+CV_EXPORTS_W Mat getOptimalNewCameraMatrix( InputArray cameraMatrix, InputArray distCoeffs,
+ Size imageSize, double alpha, Size newImgSize = Size(),
+ CV_OUT Rect* validPixROI = 0,
+ bool centerPrincipalPoint = false);
+
+/** @brief Converts points from Euclidean to homogeneous space.
+
+@param src Input vector of N-dimensional points.
+@param dst Output vector of N+1-dimensional points.
+
+The function converts points from Euclidean to homogeneous space by appending 1's to the tuple of
+point coordinates. That is, each point (x1, x2, ..., xn) is converted to (x1, x2, ..., xn, 1).
+ */
+CV_EXPORTS_W void convertPointsToHomogeneous( InputArray src, OutputArray dst );
+
+/** @brief Converts points from homogeneous to Euclidean space.
+
+@param src Input vector of N-dimensional points.
+@param dst Output vector of N-1-dimensional points.
+
+The function converts points homogeneous to Euclidean space using perspective projection. That is,
+each point (x1, x2, ... x(n-1), xn) is converted to (x1/xn, x2/xn, ..., x(n-1)/xn). When xn=0, the
+output point coordinates will be (0,0,0,...).
+ */
+CV_EXPORTS_W void convertPointsFromHomogeneous( InputArray src, OutputArray dst );
+
+/** @brief Converts points to/from homogeneous coordinates.
+
+@param src Input array or vector of 2D, 3D, or 4D points.
+@param dst Output vector of 2D, 3D, or 4D points.
+
+The function converts 2D or 3D points from/to homogeneous coordinates by calling either
+convertPointsToHomogeneous or convertPointsFromHomogeneous.
+
+@note The function is obsolete. Use one of the previous two functions instead.
+ */
+CV_EXPORTS void convertPointsHomogeneous( InputArray src, OutputArray dst );
+
+/** @brief Calculates a fundamental matrix from the corresponding points in two images.
+
+@param points1 Array of N points from the first image. The point coordinates should be
+floating-point (single or double precision).
+@param points2 Array of the second image points of the same size and format as points1 .
+@param method Method for computing a fundamental matrix.
+- **CV_FM_7POINT** for a 7-point algorithm. \f$N = 7\f$
+- **CV_FM_8POINT** for an 8-point algorithm. \f$N \ge 8\f$
+- **CV_FM_RANSAC** for the RANSAC algorithm. \f$N \ge 8\f$
+- **CV_FM_LMEDS** for the LMedS algorithm. \f$N \ge 8\f$
+@param param1 Parameter used for RANSAC. It is the maximum distance from a point to an epipolar
+line in pixels, beyond which the point is considered an outlier and is not used for computing the
+final fundamental matrix. It can be set to something like 1-3, depending on the accuracy of the
+point localization, image resolution, and the image noise.
+@param param2 Parameter used for the RANSAC or LMedS methods only. It specifies a desirable level
+of confidence (probability) that the estimated matrix is correct.
+@param mask
+
+The epipolar geometry is described by the following equation:
+
+\f[[p_2; 1]^T F [p_1; 1] = 0\f]
+
+where \f$F\f$ is a fundamental matrix, \f$p_1\f$ and \f$p_2\f$ are corresponding points in the first and the
+second images, respectively.
+
+The function calculates the fundamental matrix using one of four methods listed above and returns
+the found fundamental matrix. Normally just one matrix is found. But in case of the 7-point
+algorithm, the function may return up to 3 solutions ( \f$9 \times 3\f$ matrix that stores all 3
+matrices sequentially).
+
+The calculated fundamental matrix may be passed further to computeCorrespondEpilines that finds the
+epipolar lines corresponding to the specified points. It can also be passed to
+stereoRectifyUncalibrated to compute the rectification transformation. :
+@code
+ // Example. Estimation of fundamental matrix using the RANSAC algorithm
+ int point_count = 100;
+ vector points1(point_count);
+ vector points2(point_count);
+
+ // initialize the points here ...
+ for( int i = 0; i < point_count; i++ )
+ {
+ points1[i] = ...;
+ points2[i] = ...;
+ }
+
+ Mat fundamental_matrix =
+ findFundamentalMat(points1, points2, FM_RANSAC, 3, 0.99);
+@endcode
+ */
+CV_EXPORTS_W Mat findFundamentalMat( InputArray points1, InputArray points2,
+ int method = FM_RANSAC,
+ double param1 = 3., double param2 = 0.99,
+ OutputArray mask = noArray() );
+
+/** @overload */
+CV_EXPORTS Mat findFundamentalMat( InputArray points1, InputArray points2,
+ OutputArray mask, int method = FM_RANSAC,
+ double param1 = 3., double param2 = 0.99 );
+
+/** @brief Calculates an essential matrix from the corresponding points in two images.
+
+@param points1 Array of N (N \>= 5) 2D points from the first image. The point coordinates should
+be floating-point (single or double precision).
+@param points2 Array of the second image points of the same size and format as points1 .
+@param cameraMatrix Camera matrix \f$K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\f$ .
+Note that this function assumes that points1 and points2 are feature points from cameras with the
+same camera matrix.
+@param method Method for computing a fundamental matrix.
+- **RANSAC** for the RANSAC algorithm.
+- **MEDS** for the LMedS algorithm.
+@param threshold Parameter used for RANSAC. It is the maximum distance from a point to an epipolar
+line in pixels, beyond which the point is considered an outlier and is not used for computing the
+final fundamental matrix. It can be set to something like 1-3, depending on the accuracy of the
+point localization, image resolution, and the image noise.
+@param prob Parameter used for the RANSAC or LMedS methods only. It specifies a desirable level of
+confidence (probability) that the estimated matrix is correct.
+@param mask Output array of N elements, every element of which is set to 0 for outliers and to 1
+for the other points. The array is computed only in the RANSAC and LMedS methods.
+
+This function estimates essential matrix based on the five-point algorithm solver in @cite Nister03 .
+@cite SteweniusCFS is also a related. The epipolar geometry is described by the following equation:
+
+\f[[p_2; 1]^T K^{-T} E K^{-1} [p_1; 1] = 0\f]
+
+where \f$E\f$ is an essential matrix, \f$p_1\f$ and \f$p_2\f$ are corresponding points in the first and the
+second images, respectively. The result of this function may be passed further to
+decomposeEssentialMat or recoverPose to recover the relative pose between cameras.
+ */
+CV_EXPORTS_W Mat findEssentialMat( InputArray points1, InputArray points2,
+ InputArray cameraMatrix, int method = RANSAC,
+ double prob = 0.999, double threshold = 1.0,
+ OutputArray mask = noArray() );
+
+/** @overload
+@param points1 Array of N (N \>= 5) 2D points from the first image. The point coordinates should
+be floating-point (single or double precision).
+@param points2 Array of the second image points of the same size and format as points1 .
+@param focal focal length of the camera. Note that this function assumes that points1 and points2
+are feature points from cameras with same focal length and principle point.
+@param pp principle point of the camera.
+@param method Method for computing a fundamental matrix.
+- **RANSAC** for the RANSAC algorithm.
+- **LMEDS** for the LMedS algorithm.
+@param threshold Parameter used for RANSAC. It is the maximum distance from a point to an epipolar
+line in pixels, beyond which the point is considered an outlier and is not used for computing the
+final fundamental matrix. It can be set to something like 1-3, depending on the accuracy of the
+point localization, image resolution, and the image noise.
+@param prob Parameter used for the RANSAC or LMedS methods only. It specifies a desirable level of
+confidence (probability) that the estimated matrix is correct.
+@param mask Output array of N elements, every element of which is set to 0 for outliers and to 1
+for the other points. The array is computed only in the RANSAC and LMedS methods.
+
+This function differs from the one above that it computes camera matrix from focal length and
+principal point:
+
+\f[K =
+\begin{bmatrix}
+f & 0 & x_{pp} \\
+0 & f & y_{pp} \\
+0 & 0 & 1
+\end{bmatrix}\f]
+ */
+CV_EXPORTS_W Mat findEssentialMat( InputArray points1, InputArray points2,
+ double focal = 1.0, Point2d pp = Point2d(0, 0),
+ int method = RANSAC, double prob = 0.999,
+ double threshold = 1.0, OutputArray mask = noArray() );
+
+/** @brief Decompose an essential matrix to possible rotations and translation.
+
+@param E The input essential matrix.
+@param R1 One possible rotation matrix.
+@param R2 Another possible rotation matrix.
+@param t One possible translation.
+
+This function decompose an essential matrix E using svd decomposition @cite HartleyZ00 . Generally 4
+possible poses exists for a given E. They are \f$[R_1, t]\f$, \f$[R_1, -t]\f$, \f$[R_2, t]\f$, \f$[R_2, -t]\f$. By
+decomposing E, you can only get the direction of the translation, so the function returns unit t.
+ */
+CV_EXPORTS_W void decomposeEssentialMat( InputArray E, OutputArray R1, OutputArray R2, OutputArray t );
+
+/** @brief Recover relative camera rotation and translation from an estimated essential matrix and the
+corresponding points in two images, using cheirality check. Returns the number of inliers which pass
+the check.
+
+@param E The input essential matrix.
+@param points1 Array of N 2D points from the first image. The point coordinates should be
+floating-point (single or double precision).
+@param points2 Array of the second image points of the same size and format as points1 .
+@param cameraMatrix Camera matrix \f$K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\f$ .
+Note that this function assumes that points1 and points2 are feature points from cameras with the
+same camera matrix.
+@param R Recovered relative rotation.
+@param t Recoverd relative translation.
+@param mask Input/output mask for inliers in points1 and points2.
+: If it is not empty, then it marks inliers in points1 and points2 for then given essential
+matrix E. Only these inliers will be used to recover pose. In the output mask only inliers
+which pass the cheirality check.
+This function decomposes an essential matrix using decomposeEssentialMat and then verifies possible
+pose hypotheses by doing cheirality check. The cheirality check basically means that the
+triangulated 3D points should have positive depth. Some details can be found in @cite Nister03 .
+
+This function can be used to process output E and mask from findEssentialMat. In this scenario,
+points1 and points2 are the same input for findEssentialMat. :
+@code
+ // Example. Estimation of fundamental matrix using the RANSAC algorithm
+ int point_count = 100;
+ vector points1(point_count);
+ vector points2(point_count);
+
+ // initialize the points here ...
+ for( int i = 0; i < point_count; i++ )
+ {
+ points1[i] = ...;
+ points2[i] = ...;
+ }
+
+ // cametra matrix with both focal lengths = 1, and principal point = (0, 0)
+ Mat cameraMatrix = Mat::eye(3, 3, CV_64F);
+
+ Mat E, R, t, mask;
+
+ E = findEssentialMat(points1, points2, cameraMatrix, RANSAC, 0.999, 1.0, mask);
+ recoverPose(E, points1, points2, cameraMatrix, R, t, mask);
+@endcode
+ */
+CV_EXPORTS_W int recoverPose( InputArray E, InputArray points1, InputArray points2,
+ InputArray cameraMatrix, OutputArray R, OutputArray t,
+ InputOutputArray mask = noArray() );
+
+/** @overload
+@param E The input essential matrix.
+@param points1 Array of N 2D points from the first image. The point coordinates should be
+floating-point (single or double precision).
+@param points2 Array of the second image points of the same size and format as points1 .
+@param R Recovered relative rotation.
+@param t Recoverd relative translation.
+@param focal Focal length of the camera. Note that this function assumes that points1 and points2
+are feature points from cameras with same focal length and principle point.
+@param pp Principle point of the camera.
+@param mask Input/output mask for inliers in points1 and points2.
+: If it is not empty, then it marks inliers in points1 and points2 for then given essential
+matrix E. Only these inliers will be used to recover pose. In the output mask only inliers
+which pass the cheirality check.
+
+This function differs from the one above that it computes camera matrix from focal length and
+principal point:
+
+\f[K =
+\begin{bmatrix}
+f & 0 & x_{pp} \\
+0 & f & y_{pp} \\
+0 & 0 & 1
+\end{bmatrix}\f]
+ */
+CV_EXPORTS_W int recoverPose( InputArray E, InputArray points1, InputArray points2,
+ OutputArray R, OutputArray t,
+ double focal = 1.0, Point2d pp = Point2d(0, 0),
+ InputOutputArray mask = noArray() );
+
+/** @brief For points in an image of a stereo pair, computes the corresponding epilines in the other image.
+
+@param points Input points. \f$N \times 1\f$ or \f$1 \times N\f$ matrix of type CV_32FC2 or
+vector\ .
+@param whichImage Index of the image (1 or 2) that contains the points .
+@param F Fundamental matrix that can be estimated using findFundamentalMat or stereoRectify .
+@param lines Output vector of the epipolar lines corresponding to the points in the other image.
+Each line \f$ax + by + c=0\f$ is encoded by 3 numbers \f$(a, b, c)\f$ .
+
+For every point in one of the two images of a stereo pair, the function finds the equation of the
+corresponding epipolar line in the other image.
+
+From the fundamental matrix definition (see findFundamentalMat ), line \f$l^{(2)}_i\f$ in the second
+image for the point \f$p^{(1)}_i\f$ in the first image (when whichImage=1 ) is computed as:
+
+\f[l^{(2)}_i = F p^{(1)}_i\f]
+
+And vice versa, when whichImage=2, \f$l^{(1)}_i\f$ is computed from \f$p^{(2)}_i\f$ as:
+
+\f[l^{(1)}_i = F^T p^{(2)}_i\f]
+
+Line coefficients are defined up to a scale. They are normalized so that \f$a_i^2+b_i^2=1\f$ .
+ */
+CV_EXPORTS_W void computeCorrespondEpilines( InputArray points, int whichImage,
+ InputArray F, OutputArray lines );
+
+/** @brief Reconstructs points by triangulation.
+
+@param projMatr1 3x4 projection matrix of the first camera.
+@param projMatr2 3x4 projection matrix of the second camera.
+@param projPoints1 2xN array of feature points in the first image. In case of c++ version it can
+be also a vector of feature points or two-channel matrix of size 1xN or Nx1.
+@param projPoints2 2xN array of corresponding points in the second image. In case of c++ version
+it can be also a vector of feature points or two-channel matrix of size 1xN or Nx1.
+@param points4D 4xN array of reconstructed points in homogeneous coordinates.
+
+The function reconstructs 3-dimensional points (in homogeneous coordinates) by using their
+observations with a stereo camera. Projections matrices can be obtained from stereoRectify.
+
+@note
+ Keep in mind that all input data should be of float type in order for this function to work.
+
+@sa
+ reprojectImageTo3D
+ */
+CV_EXPORTS_W void triangulatePoints( InputArray projMatr1, InputArray projMatr2,
+ InputArray projPoints1, InputArray projPoints2,
+ OutputArray points4D );
+
+/** @brief Refines coordinates of corresponding points.
+
+@param F 3x3 fundamental matrix.
+@param points1 1xN array containing the first set of points.
+@param points2 1xN array containing the second set of points.
+@param newPoints1 The optimized points1.
+@param newPoints2 The optimized points2.
+
+The function implements the Optimal Triangulation Method (see Multiple View Geometry for details).
+For each given point correspondence points1[i] \<-\> points2[i], and a fundamental matrix F, it
+computes the corrected correspondences newPoints1[i] \<-\> newPoints2[i] that minimize the geometric
+error \f$d(points1[i], newPoints1[i])^2 + d(points2[i],newPoints2[i])^2\f$ (where \f$d(a,b)\f$ is the
+geometric distance between points \f$a\f$ and \f$b\f$ ) subject to the epipolar constraint
+\f$newPoints2^T * F * newPoints1 = 0\f$ .
+ */
+CV_EXPORTS_W void correctMatches( InputArray F, InputArray points1, InputArray points2,
+ OutputArray newPoints1, OutputArray newPoints2 );
+
+/** @brief Filters off small noise blobs (speckles) in the disparity map
+
+@param img The input 16-bit signed disparity image
+@param newVal The disparity value used to paint-off the speckles
+@param maxSpeckleSize The maximum speckle size to consider it a speckle. Larger blobs are not
+affected by the algorithm
+@param maxDiff Maximum difference between neighbor disparity pixels to put them into the same
+blob. Note that since StereoBM, StereoSGBM and may be other algorithms return a fixed-point
+disparity map, where disparity values are multiplied by 16, this scale factor should be taken into
+account when specifying this parameter value.
+@param buf The optional temporary buffer to avoid memory allocation within the function.
+ */
+CV_EXPORTS_W void filterSpeckles( InputOutputArray img, double newVal,
+ int maxSpeckleSize, double maxDiff,
+ InputOutputArray buf = noArray() );
+
+//! computes valid disparity ROI from the valid ROIs of the rectified images (that are returned by cv::stereoRectify())
+CV_EXPORTS_W Rect getValidDisparityROI( Rect roi1, Rect roi2,
+ int minDisparity, int numberOfDisparities,
+ int SADWindowSize );
+
+//! validates disparity using the left-right check. The matrix "cost" should be computed by the stereo correspondence algorithm
+CV_EXPORTS_W void validateDisparity( InputOutputArray disparity, InputArray cost,
+ int minDisparity, int numberOfDisparities,
+ int disp12MaxDisp = 1 );
+
+/** @brief Reprojects a disparity image to 3D space.
+
+@param disparity Input single-channel 8-bit unsigned, 16-bit signed, 32-bit signed or 32-bit
+floating-point disparity image. If 16-bit signed format is used, the values are assumed to have no
+fractional bits.
+@param _3dImage Output 3-channel floating-point image of the same size as disparity . Each
+element of _3dImage(x,y) contains 3D coordinates of the point (x,y) computed from the disparity
+map.
+@param Q \f$4 \times 4\f$ perspective transformation matrix that can be obtained with stereoRectify.
+@param handleMissingValues Indicates, whether the function should handle missing values (i.e.
+points where the disparity was not computed). If handleMissingValues=true, then pixels with the
+minimal disparity that corresponds to the outliers (see StereoMatcher::compute ) are transformed
+to 3D points with a very large Z value (currently set to 10000).
+@param ddepth The optional output array depth. If it is -1, the output image will have CV_32F
+depth. ddepth can also be set to CV_16S, CV_32S or CV_32F.
+
+The function transforms a single-channel disparity map to a 3-channel image representing a 3D
+surface. That is, for each pixel (x,y) andthe corresponding disparity d=disparity(x,y) , it
+computes:
+
+\f[\begin{array}{l} [X \; Y \; Z \; W]^T = \texttt{Q} *[x \; y \; \texttt{disparity} (x,y) \; 1]^T \\ \texttt{\_3dImage} (x,y) = (X/W, \; Y/W, \; Z/W) \end{array}\f]
+
+The matrix Q can be an arbitrary \f$4 \times 4\f$ matrix (for example, the one computed by
+stereoRectify). To reproject a sparse set of points {(x,y,d),...} to 3D space, use
+perspectiveTransform .
+ */
+CV_EXPORTS_W void reprojectImageTo3D( InputArray disparity,
+ OutputArray _3dImage, InputArray Q,
+ bool handleMissingValues = false,
+ int ddepth = -1 );
+
+/** @brief Calculates the Sampson Distance between two points.
+
+The function sampsonDistance calculates and returns the first order approximation of the geometric error as:
+\f[sd( \texttt{pt1} , \texttt{pt2} )= \frac{(\texttt{pt2}^t \cdot \texttt{F} \cdot \texttt{pt1})^2}{(\texttt{F} \cdot \texttt{pt1})(0) + (\texttt{F} \cdot \texttt{pt1})(1) + (\texttt{F}^t \cdot \texttt{pt2})(0) + (\texttt{F}^t \cdot \texttt{pt2})(1)}\f]
+The fundamental matrix may be calculated using the cv::findFundamentalMat function. See HZ 11.4.3 for details.
+@param pt1 first homogeneous 2d point
+@param pt2 second homogeneous 2d point
+@param F fundamental matrix
+*/
+CV_EXPORTS_W double sampsonDistance(InputArray pt1, InputArray pt2, InputArray F);
+
+/** @brief Computes an optimal affine transformation between two 3D point sets.
+
+@param src First input 3D point set.
+@param dst Second input 3D point set.
+@param out Output 3D affine transformation matrix \f$3 \times 4\f$ .
+@param inliers Output vector indicating which points are inliers.
+@param ransacThreshold Maximum reprojection error in the RANSAC algorithm to consider a point as
+an inlier.
+@param confidence Confidence level, between 0 and 1, for the estimated transformation. Anything
+between 0.95 and 0.99 is usually good enough. Values too close to 1 can slow down the estimation
+significantly. Values lower than 0.8-0.9 can result in an incorrectly estimated transformation.
+
+The function estimates an optimal 3D affine transformation between two 3D point sets using the
+RANSAC algorithm.
+ */
+CV_EXPORTS_W int estimateAffine3D(InputArray src, InputArray dst,
+ OutputArray out, OutputArray inliers,
+ double ransacThreshold = 3, double confidence = 0.99);
+
+/** @brief Decompose a homography matrix to rotation(s), translation(s) and plane normal(s).
+
+@param H The input homography matrix between two images.
+@param K The input intrinsic camera calibration matrix.
+@param rotations Array of rotation matrices.
+@param translations Array of translation matrices.
+@param normals Array of plane normal matrices.
+
+This function extracts relative camera motion between two views observing a planar object from the
+homography H induced by the plane. The intrinsic camera matrix K must also be provided. The function
+may return up to four mathematical solution sets. At least two of the solutions may further be
+invalidated if point correspondences are available by applying positive depth constraint (all points
+must be in front of the camera). The decomposition method is described in detail in @cite Malis .
+ */
+CV_EXPORTS_W int decomposeHomographyMat(InputArray H,
+ InputArray K,
+ OutputArrayOfArrays rotations,
+ OutputArrayOfArrays translations,
+ OutputArrayOfArrays normals);
+
+/** @brief The base class for stereo correspondence algorithms.
+ */
+class CV_EXPORTS_W StereoMatcher : public Algorithm
+{
+public:
+ enum { DISP_SHIFT = 4,
+ DISP_SCALE = (1 << DISP_SHIFT)
+ };
+
+ /** @brief Computes disparity map for the specified stereo pair
+
+ @param left Left 8-bit single-channel image.
+ @param right Right image of the same size and the same type as the left one.
+ @param disparity Output disparity map. It has the same size as the input images. Some algorithms,
+ like StereoBM or StereoSGBM compute 16-bit fixed-point disparity map (where each disparity value
+ has 4 fractional bits), whereas other algorithms output 32-bit floating-point disparity map.
+ */
+ CV_WRAP virtual void compute( InputArray left, InputArray right,
+ OutputArray disparity ) = 0;
+
+ CV_WRAP virtual int getMinDisparity() const = 0;
+ CV_WRAP virtual void setMinDisparity(int minDisparity) = 0;
+
+ CV_WRAP virtual int getNumDisparities() const = 0;
+ CV_WRAP virtual void setNumDisparities(int numDisparities) = 0;
+
+ CV_WRAP virtual int getBlockSize() const = 0;
+ CV_WRAP virtual void setBlockSize(int blockSize) = 0;
+
+ CV_WRAP virtual int getSpeckleWindowSize() const = 0;
+ CV_WRAP virtual void setSpeckleWindowSize(int speckleWindowSize) = 0;
+
+ CV_WRAP virtual int getSpeckleRange() const = 0;
+ CV_WRAP virtual void setSpeckleRange(int speckleRange) = 0;
+
+ CV_WRAP virtual int getDisp12MaxDiff() const = 0;
+ CV_WRAP virtual void setDisp12MaxDiff(int disp12MaxDiff) = 0;
+};
+
+
+/** @brief Class for computing stereo correspondence using the block matching algorithm, introduced and
+contributed to OpenCV by K. Konolige.
+ */
+class CV_EXPORTS_W StereoBM : public StereoMatcher
+{
+public:
+ enum { PREFILTER_NORMALIZED_RESPONSE = 0,
+ PREFILTER_XSOBEL = 1
+ };
+
+ CV_WRAP virtual int getPreFilterType() const = 0;
+ CV_WRAP virtual void setPreFilterType(int preFilterType) = 0;
+
+ CV_WRAP virtual int getPreFilterSize() const = 0;
+ CV_WRAP virtual void setPreFilterSize(int preFilterSize) = 0;
+
+ CV_WRAP virtual int getPreFilterCap() const = 0;
+ CV_WRAP virtual void setPreFilterCap(int preFilterCap) = 0;
+
+ CV_WRAP virtual int getTextureThreshold() const = 0;
+ CV_WRAP virtual void setTextureThreshold(int textureThreshold) = 0;
+
+ CV_WRAP virtual int getUniquenessRatio() const = 0;
+ CV_WRAP virtual void setUniquenessRatio(int uniquenessRatio) = 0;
+
+ CV_WRAP virtual int getSmallerBlockSize() const = 0;
+ CV_WRAP virtual void setSmallerBlockSize(int blockSize) = 0;
+
+ CV_WRAP virtual Rect getROI1() const = 0;
+ CV_WRAP virtual void setROI1(Rect roi1) = 0;
+
+ CV_WRAP virtual Rect getROI2() const = 0;
+ CV_WRAP virtual void setROI2(Rect roi2) = 0;
+
+ /** @brief Creates StereoBM object
+
+ @param numDisparities the disparity search range. For each pixel algorithm will find the best
+ disparity from 0 (default minimum disparity) to numDisparities. The search range can then be
+ shifted by changing the minimum disparity.
+ @param blockSize the linear size of the blocks compared by the algorithm. The size should be odd
+ (as the block is centered at the current pixel). Larger block size implies smoother, though less
+ accurate disparity map. Smaller block size gives more detailed disparity map, but there is higher
+ chance for algorithm to find a wrong correspondence.
+
+ The function create StereoBM object. You can then call StereoBM::compute() to compute disparity for
+ a specific stereo pair.
+ */
+ CV_WRAP static Ptr create(int numDisparities = 0, int blockSize = 21);
+};
+
+/** @brief The class implements the modified H. Hirschmuller algorithm @cite HH08 that differs from the original
+one as follows:
+
+- By default, the algorithm is single-pass, which means that you consider only 5 directions
+instead of 8. Set mode=StereoSGBM::MODE_HH in createStereoSGBM to run the full variant of the
+algorithm but beware that it may consume a lot of memory.
+- The algorithm matches blocks, not individual pixels. Though, setting blockSize=1 reduces the
+blocks to single pixels.
+- Mutual information cost function is not implemented. Instead, a simpler Birchfield-Tomasi
+sub-pixel metric from @cite BT98 is used. Though, the color images are supported as well.
+- Some pre- and post- processing steps from K. Konolige algorithm StereoBM are included, for
+example: pre-filtering (StereoBM::PREFILTER_XSOBEL type) and post-filtering (uniqueness
+check, quadratic interpolation and speckle filtering).
+
+@note
+ - (Python) An example illustrating the use of the StereoSGBM matching algorithm can be found
+ at opencv_source_code/samples/python/stereo_match.py
+ */
+class CV_EXPORTS_W StereoSGBM : public StereoMatcher
+{
+public:
+ enum
+ {
+ MODE_SGBM = 0,
+ MODE_HH = 1,
+ MODE_SGBM_3WAY = 2
+ };
+
+ CV_WRAP virtual int getPreFilterCap() const = 0;
+ CV_WRAP virtual void setPreFilterCap(int preFilterCap) = 0;
+
+ CV_WRAP virtual int getUniquenessRatio() const = 0;
+ CV_WRAP virtual void setUniquenessRatio(int uniquenessRatio) = 0;
+
+ CV_WRAP virtual int getP1() const = 0;
+ CV_WRAP virtual void setP1(int P1) = 0;
+
+ CV_WRAP virtual int getP2() const = 0;
+ CV_WRAP virtual void setP2(int P2) = 0;
+
+ CV_WRAP virtual int getMode() const = 0;
+ CV_WRAP virtual void setMode(int mode) = 0;
+
+ /** @brief Creates StereoSGBM object
+
+ @param minDisparity Minimum possible disparity value. Normally, it is zero but sometimes
+ rectification algorithms can shift images, so this parameter needs to be adjusted accordingly.
+ @param numDisparities Maximum disparity minus minimum disparity. The value is always greater than
+ zero. In the current implementation, this parameter must be divisible by 16.
+ @param blockSize Matched block size. It must be an odd number \>=1 . Normally, it should be
+ somewhere in the 3..11 range.
+ @param P1 The first parameter controlling the disparity smoothness. See below.
+ @param P2 The second parameter controlling the disparity smoothness. The larger the values are,
+ the smoother the disparity is. P1 is the penalty on the disparity change by plus or minus 1
+ between neighbor pixels. P2 is the penalty on the disparity change by more than 1 between neighbor
+ pixels. The algorithm requires P2 \> P1 . See stereo_match.cpp sample where some reasonably good
+ P1 and P2 values are shown (like 8\*number_of_image_channels\*SADWindowSize\*SADWindowSize and
+ 32\*number_of_image_channels\*SADWindowSize\*SADWindowSize , respectively).
+ @param disp12MaxDiff Maximum allowed difference (in integer pixel units) in the left-right
+ disparity check. Set it to a non-positive value to disable the check.
+ @param preFilterCap Truncation value for the prefiltered image pixels. The algorithm first
+ computes x-derivative at each pixel and clips its value by [-preFilterCap, preFilterCap] interval.
+ The result values are passed to the Birchfield-Tomasi pixel cost function.
+ @param uniquenessRatio Margin in percentage by which the best (minimum) computed cost function
+ value should "win" the second best value to consider the found match correct. Normally, a value
+ within the 5-15 range is good enough.
+ @param speckleWindowSize Maximum size of smooth disparity regions to consider their noise speckles
+ and invalidate. Set it to 0 to disable speckle filtering. Otherwise, set it somewhere in the
+ 50-200 range.
+ @param speckleRange Maximum disparity variation within each connected component. If you do speckle
+ filtering, set the parameter to a positive value, it will be implicitly multiplied by 16.
+ Normally, 1 or 2 is good enough.
+ @param mode Set it to StereoSGBM::MODE_HH to run the full-scale two-pass dynamic programming
+ algorithm. It will consume O(W\*H\*numDisparities) bytes, which is large for 640x480 stereo and
+ huge for HD-size pictures. By default, it is set to false .
+
+ The first constructor initializes StereoSGBM with all the default parameters. So, you only have to
+ set StereoSGBM::numDisparities at minimum. The second constructor enables you to set each parameter
+ to a custom value.
+ */
+ CV_WRAP static Ptr create(int minDisparity, int numDisparities, int blockSize,
+ int P1 = 0, int P2 = 0, int disp12MaxDiff = 0,
+ int preFilterCap = 0, int uniquenessRatio = 0,
+ int speckleWindowSize = 0, int speckleRange = 0,
+ int mode = StereoSGBM::MODE_SGBM);
+};
+
+//! @} calib3d
+
+/** @brief The methods in this namespace use a so-called fisheye camera model.
+ @ingroup calib3d_fisheye
+*/
+namespace fisheye
+{
+//! @addtogroup calib3d_fisheye
+//! @{
+
+ enum{
+ CALIB_USE_INTRINSIC_GUESS = 1,
+ CALIB_RECOMPUTE_EXTRINSIC = 2,
+ CALIB_CHECK_COND = 4,
+ CALIB_FIX_SKEW = 8,
+ CALIB_FIX_K1 = 16,
+ CALIB_FIX_K2 = 32,
+ CALIB_FIX_K3 = 64,
+ CALIB_FIX_K4 = 128,
+ CALIB_FIX_INTRINSIC = 256
+ };
+
+ /** @brief Projects points using fisheye model
+
+ @param objectPoints Array of object points, 1xN/Nx1 3-channel (or vector\ ), where N is
+ the number of points in the view.
+ @param imagePoints Output array of image points, 2xN/Nx2 1-channel or 1xN/Nx1 2-channel, or
+ vector\.
+ @param affine
+ @param K Camera matrix \f$K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{_1}\f$.
+ @param D Input vector of distortion coefficients \f$(k_1, k_2, k_3, k_4)\f$.
+ @param alpha The skew coefficient.
+ @param jacobian Optional output 2Nx15 jacobian matrix of derivatives of image points with respect
+ to components of the focal lengths, coordinates of the principal point, distortion coefficients,
+ rotation vector, translation vector, and the skew. In the old interface different components of
+ the jacobian are returned via different output parameters.
+
+ The function computes projections of 3D points to the image plane given intrinsic and extrinsic
+ camera parameters. Optionally, the function computes Jacobians - matrices of partial derivatives of
+ image points coordinates (as functions of all the input parameters) with respect to the particular
+ parameters, intrinsic and/or extrinsic.
+ */
+ CV_EXPORTS void projectPoints(InputArray objectPoints, OutputArray imagePoints, const Affine3d& affine,
+ InputArray K, InputArray D, double alpha = 0, OutputArray jacobian = noArray());
+
+ /** @overload */
+ CV_EXPORTS_W void projectPoints(InputArray objectPoints, OutputArray imagePoints, InputArray rvec, InputArray tvec,
+ InputArray K, InputArray D, double alpha = 0, OutputArray jacobian = noArray());
+
+ /** @brief Distorts 2D points using fisheye model.
+
+ @param undistorted Array of object points, 1xN/Nx1 2-channel (or vector\ ), where N is
+ the number of points in the view.
+ @param K Camera matrix \f$K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{_1}\f$.
+ @param D Input vector of distortion coefficients \f$(k_1, k_2, k_3, k_4)\f$.
+ @param alpha The skew coefficient.
+ @param distorted Output array of image points, 1xN/Nx1 2-channel, or vector\ .
+ */
+ CV_EXPORTS_W void distortPoints(InputArray undistorted, OutputArray distorted, InputArray K, InputArray D, double alpha = 0);
+
+ /** @brief Undistorts 2D points using fisheye model
+
+ @param distorted Array of object points, 1xN/Nx1 2-channel (or vector\ ), where N is the
+ number of points in the view.
+ @param K Camera matrix \f$K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{_1}\f$.
+ @param D Input vector of distortion coefficients \f$(k_1, k_2, k_3, k_4)\f$.
+ @param R Rectification transformation in the object space: 3x3 1-channel, or vector: 3x1/1x3
+ 1-channel or 1x1 3-channel
+ @param P New camera matrix (3x3) or new projection matrix (3x4)
+ @param undistorted Output array of image points, 1xN/Nx1 2-channel, or vector\ .
+ */
+ CV_EXPORTS_W void undistortPoints(InputArray distorted, OutputArray undistorted,
+ InputArray K, InputArray D, InputArray R = noArray(), InputArray P = noArray());
+
+ /** @brief Computes undistortion and rectification maps for image transform by cv::remap(). If D is empty zero
+ distortion is used, if R or P is empty identity matrixes are used.
+
+ @param K Camera matrix \f$K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{_1}\f$.
+ @param D Input vector of distortion coefficients \f$(k_1, k_2, k_3, k_4)\f$.
+ @param R Rectification transformation in the object space: 3x3 1-channel, or vector: 3x1/1x3
+ 1-channel or 1x1 3-channel
+ @param P New camera matrix (3x3) or new projection matrix (3x4)
+ @param size Undistorted image size.
+ @param m1type Type of the first output map that can be CV_32FC1 or CV_16SC2 . See convertMaps()
+ for details.
+ @param map1 The first output map.
+ @param map2 The second output map.
+ */
+ CV_EXPORTS_W void initUndistortRectifyMap(InputArray K, InputArray D, InputArray R, InputArray P,
+ const cv::Size& size, int m1type, OutputArray map1, OutputArray map2);
+
+ /** @brief Transforms an image to compensate for fisheye lens distortion.
+
+ @param distorted image with fisheye lens distortion.
+ @param undistorted Output image with compensated fisheye lens distortion.
+ @param K Camera matrix \f$K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{_1}\f$.
+ @param D Input vector of distortion coefficients \f$(k_1, k_2, k_3, k_4)\f$.
+ @param Knew Camera matrix of the distorted image. By default, it is the identity matrix but you
+ may additionally scale and shift the result by using a different matrix.
+ @param new_size
+
+ The function transforms an image to compensate radial and tangential lens distortion.
+
+ The function is simply a combination of fisheye::initUndistortRectifyMap (with unity R ) and remap
+ (with bilinear interpolation). See the former function for details of the transformation being
+ performed.
+
+ See below the results of undistortImage.
+ - a\) result of undistort of perspective camera model (all possible coefficients (k_1, k_2, k_3,
+ k_4, k_5, k_6) of distortion were optimized under calibration)
+ - b\) result of fisheye::undistortImage of fisheye camera model (all possible coefficients (k_1, k_2,
+ k_3, k_4) of fisheye distortion were optimized under calibration)
+ - c\) original image was captured with fisheye lens
+
+ Pictures a) and b) almost the same. But if we consider points of image located far from the center
+ of image, we can notice that on image a) these points are distorted.
+
+ 
+ */
+ CV_EXPORTS_W void undistortImage(InputArray distorted, OutputArray undistorted,
+ InputArray K, InputArray D, InputArray Knew = cv::noArray(), const Size& new_size = Size());
+
+ /** @brief Estimates new camera matrix for undistortion or rectification.
+
+ @param K Camera matrix \f$K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{_1}\f$.
+ @param image_size
+ @param D Input vector of distortion coefficients \f$(k_1, k_2, k_3, k_4)\f$.
+ @param R Rectification transformation in the object space: 3x3 1-channel, or vector: 3x1/1x3
+ 1-channel or 1x1 3-channel
+ @param P New camera matrix (3x3) or new projection matrix (3x4)
+ @param balance Sets the new focal length in range between the min focal length and the max focal
+ length. Balance is in range of [0, 1].
+ @param new_size
+ @param fov_scale Divisor for new focal length.
+ */
+ CV_EXPORTS_W void estimateNewCameraMatrixForUndistortRectify(InputArray K, InputArray D, const Size &image_size, InputArray R,
+ OutputArray P, double balance = 0.0, const Size& new_size = Size(), double fov_scale = 1.0);
+
+ /** @brief Performs camera calibaration
+
+ @param objectPoints vector of vectors of calibration pattern points in the calibration pattern
+ coordinate space.
+ @param imagePoints vector of vectors of the projections of calibration pattern points.
+ imagePoints.size() and objectPoints.size() and imagePoints[i].size() must be equal to
+ objectPoints[i].size() for each i.
+ @param image_size Size of the image used only to initialize the intrinsic camera matrix.
+ @param K Output 3x3 floating-point camera matrix
+ \f$A = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\f$ . If
+ fisheye::CALIB_USE_INTRINSIC_GUESS/ is specified, some or all of fx, fy, cx, cy must be
+ initialized before calling the function.
+ @param D Output vector of distortion coefficients \f$(k_1, k_2, k_3, k_4)\f$.
+ @param rvecs Output vector of rotation vectors (see Rodrigues ) estimated for each pattern view.
+ That is, each k-th rotation vector together with the corresponding k-th translation vector (see
+ the next output parameter description) brings the calibration pattern from the model coordinate
+ space (in which object points are specified) to the world coordinate space, that is, a real
+ position of the calibration pattern in the k-th pattern view (k=0.. *M* -1).
+ @param tvecs Output vector of translation vectors estimated for each pattern view.
+ @param flags Different flags that may be zero or a combination of the following values:
+ - **fisheye::CALIB_USE_INTRINSIC_GUESS** cameraMatrix contains valid initial values of
+ fx, fy, cx, cy that are optimized further. Otherwise, (cx, cy) is initially set to the image
+ center ( imageSize is used), and focal distances are computed in a least-squares fashion.
+ - **fisheye::CALIB_RECOMPUTE_EXTRINSIC** Extrinsic will be recomputed after each iteration
+ of intrinsic optimization.
+ - **fisheye::CALIB_CHECK_COND** The functions will check validity of condition number.
+ - **fisheye::CALIB_FIX_SKEW** Skew coefficient (alpha) is set to zero and stay zero.
+ - **fisheye::CALIB_FIX_K1..4** Selected distortion coefficients are set to zeros and stay
+ zero.
+ @param criteria Termination criteria for the iterative optimization algorithm.
+ */
+ CV_EXPORTS_W double calibrate(InputArrayOfArrays objectPoints, InputArrayOfArrays imagePoints, const Size& image_size,
+ InputOutputArray K, InputOutputArray D, OutputArrayOfArrays rvecs, OutputArrayOfArrays tvecs, int flags = 0,
+ TermCriteria criteria = TermCriteria(TermCriteria::COUNT + TermCriteria::EPS, 100, DBL_EPSILON));
+
+ /** @brief Stereo rectification for fisheye camera model
+
+ @param K1 First camera matrix.
+ @param D1 First camera distortion parameters.
+ @param K2 Second camera matrix.
+ @param D2 Second camera distortion parameters.
+ @param imageSize Size of the image used for stereo calibration.
+ @param R Rotation matrix between the coordinate systems of the first and the second
+ cameras.
+ @param tvec Translation vector between coordinate systems of the cameras.
+ @param R1 Output 3x3 rectification transform (rotation matrix) for the first camera.
+ @param R2 Output 3x3 rectification transform (rotation matrix) for the second camera.
+ @param P1 Output 3x4 projection matrix in the new (rectified) coordinate systems for the first
+ camera.
+ @param P2 Output 3x4 projection matrix in the new (rectified) coordinate systems for the second
+ camera.
+ @param Q Output \f$4 \times 4\f$ disparity-to-depth mapping matrix (see reprojectImageTo3D ).
+ @param flags Operation flags that may be zero or CV_CALIB_ZERO_DISPARITY . If the flag is set,
+ the function makes the principal points of each camera have the same pixel coordinates in the
+ rectified views. And if the flag is not set, the function may still shift the images in the
+ horizontal or vertical direction (depending on the orientation of epipolar lines) to maximize the
+ useful image area.
+ @param newImageSize New image resolution after rectification. The same size should be passed to
+ initUndistortRectifyMap (see the stereo_calib.cpp sample in OpenCV samples directory). When (0,0)
+ is passed (default), it is set to the original imageSize . Setting it to larger value can help you
+ preserve details in the original image, especially when there is a big radial distortion.
+ @param balance Sets the new focal length in range between the min focal length and the max focal
+ length. Balance is in range of [0, 1].
+ @param fov_scale Divisor for new focal length.
+ */
+ CV_EXPORTS_W void stereoRectify(InputArray K1, InputArray D1, InputArray K2, InputArray D2, const Size &imageSize, InputArray R, InputArray tvec,
+ OutputArray R1, OutputArray R2, OutputArray P1, OutputArray P2, OutputArray Q, int flags, const Size &newImageSize = Size(),
+ double balance = 0.0, double fov_scale = 1.0);
+
+ /** @brief Performs stereo calibration
+
+ @param objectPoints Vector of vectors of the calibration pattern points.
+ @param imagePoints1 Vector of vectors of the projections of the calibration pattern points,
+ observed by the first camera.
+ @param imagePoints2 Vector of vectors of the projections of the calibration pattern points,
+ observed by the second camera.
+ @param K1 Input/output first camera matrix:
+ \f$\vecthreethree{f_x^{(j)}}{0}{c_x^{(j)}}{0}{f_y^{(j)}}{c_y^{(j)}}{0}{0}{1}\f$ , \f$j = 0,\, 1\f$ . If
+ any of fisheye::CALIB_USE_INTRINSIC_GUESS , fisheye::CV_CALIB_FIX_INTRINSIC are specified,
+ some or all of the matrix components must be initialized.
+ @param D1 Input/output vector of distortion coefficients \f$(k_1, k_2, k_3, k_4)\f$ of 4 elements.
+ @param K2 Input/output second camera matrix. The parameter is similar to K1 .
+ @param D2 Input/output lens distortion coefficients for the second camera. The parameter is
+ similar to D1 .
+ @param imageSize Size of the image used only to initialize intrinsic camera matrix.
+ @param R Output rotation matrix between the 1st and the 2nd camera coordinate systems.
+ @param T Output translation vector between the coordinate systems of the cameras.
+ @param flags Different flags that may be zero or a combination of the following values:
+ - **fisheye::CV_CALIB_FIX_INTRINSIC** Fix K1, K2? and D1, D2? so that only R, T matrices
+ are estimated.
+ - **fisheye::CALIB_USE_INTRINSIC_GUESS** K1, K2 contains valid initial values of
+ fx, fy, cx, cy that are optimized further. Otherwise, (cx, cy) is initially set to the image
+ center (imageSize is used), and focal distances are computed in a least-squares fashion.
+ - **fisheye::CALIB_RECOMPUTE_EXTRINSIC** Extrinsic will be recomputed after each iteration
+ of intrinsic optimization.
+ - **fisheye::CALIB_CHECK_COND** The functions will check validity of condition number.
+ - **fisheye::CALIB_FIX_SKEW** Skew coefficient (alpha) is set to zero and stay zero.
+ - **fisheye::CALIB_FIX_K1..4** Selected distortion coefficients are set to zeros and stay
+ zero.
+ @param criteria Termination criteria for the iterative optimization algorithm.
+ */
+ CV_EXPORTS_W double stereoCalibrate(InputArrayOfArrays objectPoints, InputArrayOfArrays imagePoints1, InputArrayOfArrays imagePoints2,
+ InputOutputArray K1, InputOutputArray D1, InputOutputArray K2, InputOutputArray D2, Size imageSize,
+ OutputArray R, OutputArray T, int flags = fisheye::CALIB_FIX_INTRINSIC,
+ TermCriteria criteria = TermCriteria(TermCriteria::COUNT + TermCriteria::EPS, 100, DBL_EPSILON));
+
+//! @} calib3d_fisheye
+}
+
+} // cv
+
+#ifndef DISABLE_OPENCV_24_COMPATIBILITY
+#include "opencv2/calib3d/calib3d_c.h"
+#endif
+
+#endif
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/opencv310/include/opencv2/calib3d/calib3d.hpp b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/opencv310/include/opencv2/calib3d/calib3d.hpp
new file mode 100644
index 0000000..b3da45e
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/opencv310/include/opencv2/calib3d/calib3d.hpp
@@ -0,0 +1,48 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifdef __OPENCV_BUILD
+#error this is a compatibility header which should not be used inside the OpenCV library
+#endif
+
+#include "opencv2/calib3d.hpp"
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/opencv310/include/opencv2/calib3d/calib3d_c.h b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/opencv310/include/opencv2/calib3d/calib3d_c.h
new file mode 100644
index 0000000..0e77aa8
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/opencv310/include/opencv2/calib3d/calib3d_c.h
@@ -0,0 +1,425 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef __OPENCV_CALIB3D_C_H__
+#define __OPENCV_CALIB3D_C_H__
+
+#include "opencv2/core/core_c.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @addtogroup calib3d_c
+ @{
+ */
+
+/****************************************************************************************\
+* Camera Calibration, Pose Estimation and Stereo *
+\****************************************************************************************/
+
+typedef struct CvPOSITObject CvPOSITObject;
+
+/* Allocates and initializes CvPOSITObject structure before doing cvPOSIT */
+CVAPI(CvPOSITObject*) cvCreatePOSITObject( CvPoint3D32f* points, int point_count );
+
+
+/* Runs POSIT (POSe from ITeration) algorithm for determining 3d position of
+ an object given its model and projection in a weak-perspective case */
+CVAPI(void) cvPOSIT( CvPOSITObject* posit_object, CvPoint2D32f* image_points,
+ double focal_length, CvTermCriteria criteria,
+ float* rotation_matrix, float* translation_vector);
+
+/* Releases CvPOSITObject structure */
+CVAPI(void) cvReleasePOSITObject( CvPOSITObject** posit_object );
+
+/* updates the number of RANSAC iterations */
+CVAPI(int) cvRANSACUpdateNumIters( double p, double err_prob,
+ int model_points, int max_iters );
+
+CVAPI(void) cvConvertPointsHomogeneous( const CvMat* src, CvMat* dst );
+
+/* Calculates fundamental matrix given a set of corresponding points */
+#define CV_FM_7POINT 1
+#define CV_FM_8POINT 2
+
+#define CV_LMEDS 4
+#define CV_RANSAC 8
+
+#define CV_FM_LMEDS_ONLY CV_LMEDS
+#define CV_FM_RANSAC_ONLY CV_RANSAC
+#define CV_FM_LMEDS CV_LMEDS
+#define CV_FM_RANSAC CV_RANSAC
+
+enum
+{
+ CV_ITERATIVE = 0,
+ CV_EPNP = 1, // F.Moreno-Noguer, V.Lepetit and P.Fua "EPnP: Efficient Perspective-n-Point Camera Pose Estimation"
+ CV_P3P = 2, // X.S. Gao, X.-R. Hou, J. Tang, H.-F. Chang; "Complete Solution Classification for the Perspective-Three-Point Problem"
+ CV_DLS = 3 // Joel A. Hesch and Stergios I. Roumeliotis. "A Direct Least-Squares (DLS) Method for PnP"
+};
+
+CVAPI(int) cvFindFundamentalMat( const CvMat* points1, const CvMat* points2,
+ CvMat* fundamental_matrix,
+ int method CV_DEFAULT(CV_FM_RANSAC),
+ double param1 CV_DEFAULT(3.), double param2 CV_DEFAULT(0.99),
+ CvMat* status CV_DEFAULT(NULL) );
+
+/* For each input point on one of images
+ computes parameters of the corresponding
+ epipolar line on the other image */
+CVAPI(void) cvComputeCorrespondEpilines( const CvMat* points,
+ int which_image,
+ const CvMat* fundamental_matrix,
+ CvMat* correspondent_lines );
+
+/* Triangulation functions */
+
+CVAPI(void) cvTriangulatePoints(CvMat* projMatr1, CvMat* projMatr2,
+ CvMat* projPoints1, CvMat* projPoints2,
+ CvMat* points4D);
+
+CVAPI(void) cvCorrectMatches(CvMat* F, CvMat* points1, CvMat* points2,
+ CvMat* new_points1, CvMat* new_points2);
+
+
+/* Computes the optimal new camera matrix according to the free scaling parameter alpha:
+ alpha=0 - only valid pixels will be retained in the undistorted image
+ alpha=1 - all the source image pixels will be retained in the undistorted image
+*/
+CVAPI(void) cvGetOptimalNewCameraMatrix( const CvMat* camera_matrix,
+ const CvMat* dist_coeffs,
+ CvSize image_size, double alpha,
+ CvMat* new_camera_matrix,
+ CvSize new_imag_size CV_DEFAULT(cvSize(0,0)),
+ CvRect* valid_pixel_ROI CV_DEFAULT(0),
+ int center_principal_point CV_DEFAULT(0));
+
+/* Converts rotation vector to rotation matrix or vice versa */
+CVAPI(int) cvRodrigues2( const CvMat* src, CvMat* dst,
+ CvMat* jacobian CV_DEFAULT(0) );
+
+/* Finds perspective transformation between the object plane and image (view) plane */
+CVAPI(int) cvFindHomography( const CvMat* src_points,
+ const CvMat* dst_points,
+ CvMat* homography,
+ int method CV_DEFAULT(0),
+ double ransacReprojThreshold CV_DEFAULT(3),
+ CvMat* mask CV_DEFAULT(0),
+ int maxIters CV_DEFAULT(2000),
+ double confidence CV_DEFAULT(0.995));
+
+/* Computes RQ decomposition for 3x3 matrices */
+CVAPI(void) cvRQDecomp3x3( const CvMat *matrixM, CvMat *matrixR, CvMat *matrixQ,
+ CvMat *matrixQx CV_DEFAULT(NULL),
+ CvMat *matrixQy CV_DEFAULT(NULL),
+ CvMat *matrixQz CV_DEFAULT(NULL),
+ CvPoint3D64f *eulerAngles CV_DEFAULT(NULL));
+
+/* Computes projection matrix decomposition */
+CVAPI(void) cvDecomposeProjectionMatrix( const CvMat *projMatr, CvMat *calibMatr,
+ CvMat *rotMatr, CvMat *posVect,
+ CvMat *rotMatrX CV_DEFAULT(NULL),
+ CvMat *rotMatrY CV_DEFAULT(NULL),
+ CvMat *rotMatrZ CV_DEFAULT(NULL),
+ CvPoint3D64f *eulerAngles CV_DEFAULT(NULL));
+
+/* Computes d(AB)/dA and d(AB)/dB */
+CVAPI(void) cvCalcMatMulDeriv( const CvMat* A, const CvMat* B, CvMat* dABdA, CvMat* dABdB );
+
+/* Computes r3 = rodrigues(rodrigues(r2)*rodrigues(r1)),
+ t3 = rodrigues(r2)*t1 + t2 and the respective derivatives */
+CVAPI(void) cvComposeRT( const CvMat* _rvec1, const CvMat* _tvec1,
+ const CvMat* _rvec2, const CvMat* _tvec2,
+ CvMat* _rvec3, CvMat* _tvec3,
+ CvMat* dr3dr1 CV_DEFAULT(0), CvMat* dr3dt1 CV_DEFAULT(0),
+ CvMat* dr3dr2 CV_DEFAULT(0), CvMat* dr3dt2 CV_DEFAULT(0),
+ CvMat* dt3dr1 CV_DEFAULT(0), CvMat* dt3dt1 CV_DEFAULT(0),
+ CvMat* dt3dr2 CV_DEFAULT(0), CvMat* dt3dt2 CV_DEFAULT(0) );
+
+/* Projects object points to the view plane using
+ the specified extrinsic and intrinsic camera parameters */
+CVAPI(void) cvProjectPoints2( const CvMat* object_points, const CvMat* rotation_vector,
+ const CvMat* translation_vector, const CvMat* camera_matrix,
+ const CvMat* distortion_coeffs, CvMat* image_points,
+ CvMat* dpdrot CV_DEFAULT(NULL), CvMat* dpdt CV_DEFAULT(NULL),
+ CvMat* dpdf CV_DEFAULT(NULL), CvMat* dpdc CV_DEFAULT(NULL),
+ CvMat* dpddist CV_DEFAULT(NULL),
+ double aspect_ratio CV_DEFAULT(0));
+
+/* Finds extrinsic camera parameters from
+ a few known corresponding point pairs and intrinsic parameters */
+CVAPI(void) cvFindExtrinsicCameraParams2( const CvMat* object_points,
+ const CvMat* image_points,
+ const CvMat* camera_matrix,
+ const CvMat* distortion_coeffs,
+ CvMat* rotation_vector,
+ CvMat* translation_vector,
+ int use_extrinsic_guess CV_DEFAULT(0) );
+
+/* Computes initial estimate of the intrinsic camera parameters
+ in case of planar calibration target (e.g. chessboard) */
+CVAPI(void) cvInitIntrinsicParams2D( const CvMat* object_points,
+ const CvMat* image_points,
+ const CvMat* npoints, CvSize image_size,
+ CvMat* camera_matrix,
+ double aspect_ratio CV_DEFAULT(1.) );
+
+#define CV_CALIB_CB_ADAPTIVE_THRESH 1
+#define CV_CALIB_CB_NORMALIZE_IMAGE 2
+#define CV_CALIB_CB_FILTER_QUADS 4
+#define CV_CALIB_CB_FAST_CHECK 8
+
+// Performs a fast check if a chessboard is in the input image. This is a workaround to
+// a problem of cvFindChessboardCorners being slow on images with no chessboard
+// - src: input image
+// - size: chessboard size
+// Returns 1 if a chessboard can be in this image and findChessboardCorners should be called,
+// 0 if there is no chessboard, -1 in case of error
+CVAPI(int) cvCheckChessboard(IplImage* src, CvSize size);
+
+ /* Detects corners on a chessboard calibration pattern */
+CVAPI(int) cvFindChessboardCorners( const void* image, CvSize pattern_size,
+ CvPoint2D32f* corners,
+ int* corner_count CV_DEFAULT(NULL),
+ int flags CV_DEFAULT(CV_CALIB_CB_ADAPTIVE_THRESH+CV_CALIB_CB_NORMALIZE_IMAGE) );
+
+/* Draws individual chessboard corners or the whole chessboard detected */
+CVAPI(void) cvDrawChessboardCorners( CvArr* image, CvSize pattern_size,
+ CvPoint2D32f* corners,
+ int count, int pattern_was_found );
+
+#define CV_CALIB_USE_INTRINSIC_GUESS 1
+#define CV_CALIB_FIX_ASPECT_RATIO 2
+#define CV_CALIB_FIX_PRINCIPAL_POINT 4
+#define CV_CALIB_ZERO_TANGENT_DIST 8
+#define CV_CALIB_FIX_FOCAL_LENGTH 16
+#define CV_CALIB_FIX_K1 32
+#define CV_CALIB_FIX_K2 64
+#define CV_CALIB_FIX_K3 128
+#define CV_CALIB_FIX_K4 2048
+#define CV_CALIB_FIX_K5 4096
+#define CV_CALIB_FIX_K6 8192
+#define CV_CALIB_RATIONAL_MODEL 16384
+#define CV_CALIB_THIN_PRISM_MODEL 32768
+#define CV_CALIB_FIX_S1_S2_S3_S4 65536
+#define CV_CALIB_TILTED_MODEL 262144
+#define CV_CALIB_FIX_TAUX_TAUY 524288
+
+
+/* Finds intrinsic and extrinsic camera parameters
+ from a few views of known calibration pattern */
+CVAPI(double) cvCalibrateCamera2( const CvMat* object_points,
+ const CvMat* image_points,
+ const CvMat* point_counts,
+ CvSize image_size,
+ CvMat* camera_matrix,
+ CvMat* distortion_coeffs,
+ CvMat* rotation_vectors CV_DEFAULT(NULL),
+ CvMat* translation_vectors CV_DEFAULT(NULL),
+ int flags CV_DEFAULT(0),
+ CvTermCriteria term_crit CV_DEFAULT(cvTermCriteria(
+ CV_TERMCRIT_ITER+CV_TERMCRIT_EPS,30,DBL_EPSILON)) );
+
+/* Computes various useful characteristics of the camera from the data computed by
+ cvCalibrateCamera2 */
+CVAPI(void) cvCalibrationMatrixValues( const CvMat *camera_matrix,
+ CvSize image_size,
+ double aperture_width CV_DEFAULT(0),
+ double aperture_height CV_DEFAULT(0),
+ double *fovx CV_DEFAULT(NULL),
+ double *fovy CV_DEFAULT(NULL),
+ double *focal_length CV_DEFAULT(NULL),
+ CvPoint2D64f *principal_point CV_DEFAULT(NULL),
+ double *pixel_aspect_ratio CV_DEFAULT(NULL));
+
+#define CV_CALIB_FIX_INTRINSIC 256
+#define CV_CALIB_SAME_FOCAL_LENGTH 512
+
+/* Computes the transformation from one camera coordinate system to another one
+ from a few correspondent views of the same calibration target. Optionally, calibrates
+ both cameras */
+CVAPI(double) cvStereoCalibrate( const CvMat* object_points, const CvMat* image_points1,
+ const CvMat* image_points2, const CvMat* npoints,
+ CvMat* camera_matrix1, CvMat* dist_coeffs1,
+ CvMat* camera_matrix2, CvMat* dist_coeffs2,
+ CvSize image_size, CvMat* R, CvMat* T,
+ CvMat* E CV_DEFAULT(0), CvMat* F CV_DEFAULT(0),
+ int flags CV_DEFAULT(CV_CALIB_FIX_INTRINSIC),
+ CvTermCriteria term_crit CV_DEFAULT(cvTermCriteria(
+ CV_TERMCRIT_ITER+CV_TERMCRIT_EPS,30,1e-6)) );
+
+#define CV_CALIB_ZERO_DISPARITY 1024
+
+/* Computes 3D rotations (+ optional shift) for each camera coordinate system to make both
+ views parallel (=> to make all the epipolar lines horizontal or vertical) */
+CVAPI(void) cvStereoRectify( const CvMat* camera_matrix1, const CvMat* camera_matrix2,
+ const CvMat* dist_coeffs1, const CvMat* dist_coeffs2,
+ CvSize image_size, const CvMat* R, const CvMat* T,
+ CvMat* R1, CvMat* R2, CvMat* P1, CvMat* P2,
+ CvMat* Q CV_DEFAULT(0),
+ int flags CV_DEFAULT(CV_CALIB_ZERO_DISPARITY),
+ double alpha CV_DEFAULT(-1),
+ CvSize new_image_size CV_DEFAULT(cvSize(0,0)),
+ CvRect* valid_pix_ROI1 CV_DEFAULT(0),
+ CvRect* valid_pix_ROI2 CV_DEFAULT(0));
+
+/* Computes rectification transformations for uncalibrated pair of images using a set
+ of point correspondences */
+CVAPI(int) cvStereoRectifyUncalibrated( const CvMat* points1, const CvMat* points2,
+ const CvMat* F, CvSize img_size,
+ CvMat* H1, CvMat* H2,
+ double threshold CV_DEFAULT(5));
+
+
+
+/* stereo correspondence parameters and functions */
+
+#define CV_STEREO_BM_NORMALIZED_RESPONSE 0
+#define CV_STEREO_BM_XSOBEL 1
+
+/* Block matching algorithm structure */
+typedef struct CvStereoBMState
+{
+ // pre-filtering (normalization of input images)
+ int preFilterType; // =CV_STEREO_BM_NORMALIZED_RESPONSE now
+ int preFilterSize; // averaging window size: ~5x5..21x21
+ int preFilterCap; // the output of pre-filtering is clipped by [-preFilterCap,preFilterCap]
+
+ // correspondence using Sum of Absolute Difference (SAD)
+ int SADWindowSize; // ~5x5..21x21
+ int minDisparity; // minimum disparity (can be negative)
+ int numberOfDisparities; // maximum disparity - minimum disparity (> 0)
+
+ // post-filtering
+ int textureThreshold; // the disparity is only computed for pixels
+ // with textured enough neighborhood
+ int uniquenessRatio; // accept the computed disparity d* only if
+ // SAD(d) >= SAD(d*)*(1 + uniquenessRatio/100.)
+ // for any d != d*+/-1 within the search range.
+ int speckleWindowSize; // disparity variation window
+ int speckleRange; // acceptable range of variation in window
+
+ int trySmallerWindows; // if 1, the results may be more accurate,
+ // at the expense of slower processing
+ CvRect roi1, roi2;
+ int disp12MaxDiff;
+
+ // temporary buffers
+ CvMat* preFilteredImg0;
+ CvMat* preFilteredImg1;
+ CvMat* slidingSumBuf;
+ CvMat* cost;
+ CvMat* disp;
+} CvStereoBMState;
+
+#define CV_STEREO_BM_BASIC 0
+#define CV_STEREO_BM_FISH_EYE 1
+#define CV_STEREO_BM_NARROW 2
+
+CVAPI(CvStereoBMState*) cvCreateStereoBMState(int preset CV_DEFAULT(CV_STEREO_BM_BASIC),
+ int numberOfDisparities CV_DEFAULT(0));
+
+CVAPI(void) cvReleaseStereoBMState( CvStereoBMState** state );
+
+CVAPI(void) cvFindStereoCorrespondenceBM( const CvArr* left, const CvArr* right,
+ CvArr* disparity, CvStereoBMState* state );
+
+CVAPI(CvRect) cvGetValidDisparityROI( CvRect roi1, CvRect roi2, int minDisparity,
+ int numberOfDisparities, int SADWindowSize );
+
+CVAPI(void) cvValidateDisparity( CvArr* disparity, const CvArr* cost,
+ int minDisparity, int numberOfDisparities,
+ int disp12MaxDiff CV_DEFAULT(1) );
+
+/* Reprojects the computed disparity image to the 3D space using the specified 4x4 matrix */
+CVAPI(void) cvReprojectImageTo3D( const CvArr* disparityImage,
+ CvArr* _3dImage, const CvMat* Q,
+ int handleMissingValues CV_DEFAULT(0) );
+
+/** @} calib3d_c */
+
+#ifdef __cplusplus
+} // extern "C"
+
+//////////////////////////////////////////////////////////////////////////////////////////
+class CV_EXPORTS CvLevMarq
+{
+public:
+ CvLevMarq();
+ CvLevMarq( int nparams, int nerrs, CvTermCriteria criteria=
+ cvTermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER,30,DBL_EPSILON),
+ bool completeSymmFlag=false );
+ ~CvLevMarq();
+ void init( int nparams, int nerrs, CvTermCriteria criteria=
+ cvTermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER,30,DBL_EPSILON),
+ bool completeSymmFlag=false );
+ bool update( const CvMat*& param, CvMat*& J, CvMat*& err );
+ bool updateAlt( const CvMat*& param, CvMat*& JtJ, CvMat*& JtErr, double*& errNorm );
+
+ void clear();
+ void step();
+ enum { DONE=0, STARTED=1, CALC_J=2, CHECK_ERR=3 };
+
+ cv::Ptr mask;
+ cv::Ptr prevParam;
+ cv::Ptr param;
+ cv::Ptr J;
+ cv::Ptr err;
+ cv::Ptr JtJ;
+ cv::Ptr JtJN;
+ cv::Ptr JtErr;
+ cv::Ptr JtJV;
+ cv::Ptr JtJW;
+ double prevErrNorm, errNorm;
+ int lambdaLg10;
+ CvTermCriteria criteria;
+ int state;
+ int iters;
+ bool completeSymmFlag;
+ int solveMethod;
+};
+
+#endif
+
+#endif /* __OPENCV_CALIB3D_C_H__ */
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/opencv310/include/opencv2/core.hpp b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/opencv310/include/opencv2/core.hpp
new file mode 100644
index 0000000..5592260
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/opencv310/include/opencv2/core.hpp
@@ -0,0 +1,3168 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2015, Intel Corporation, all rights reserved.
+// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2015, OpenCV Foundation, all rights reserved.
+// Copyright (C) 2015, Itseez Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef __OPENCV_CORE_HPP__
+#define __OPENCV_CORE_HPP__
+
+#ifndef __cplusplus
+# error core.hpp header must be compiled as C++
+#endif
+
+#include "opencv2/core/cvdef.h"
+#include "opencv2/core/version.hpp"
+#include "opencv2/core/base.hpp"
+#include "opencv2/core/cvstd.hpp"
+#include "opencv2/core/traits.hpp"
+#include "opencv2/core/matx.hpp"
+#include "opencv2/core/types.hpp"
+#include "opencv2/core/mat.hpp"
+#include "opencv2/core/persistence.hpp"
+
+/**
+@defgroup core Core functionality
+@{
+ @defgroup core_basic Basic structures
+ @defgroup core_c C structures and operations
+ @{
+ @defgroup core_c_glue Connections with C++
+ @}
+ @defgroup core_array Operations on arrays
+ @defgroup core_xml XML/YAML Persistence
+ @defgroup core_cluster Clustering
+ @defgroup core_utils Utility and system functions and macros
+ @{
+ @defgroup core_utils_sse SSE utilities
+ @defgroup core_utils_neon NEON utilities
+ @}
+ @defgroup core_opengl OpenGL interoperability
+ @defgroup core_ipp Intel IPP Asynchronous C/C++ Converters
+ @defgroup core_optim Optimization Algorithms
+ @defgroup core_directx DirectX interoperability
+ @defgroup core_eigen Eigen support
+ @defgroup core_opencl OpenCL support
+ @defgroup core_va_intel Intel VA-API/OpenCL (CL-VA) interoperability
+ @defgroup core_hal Hardware Acceleration Layer
+ @{
+ @defgroup core_hal_functions Functions
+ @defgroup core_hal_interface Interface
+ @defgroup core_hal_intrin Universal intrinsics
+ @{
+ @defgroup core_hal_intrin_impl Private implementation helpers
+ @}
+ @}
+@}
+ */
+
+namespace cv {
+
+//! @addtogroup core_utils
+//! @{
+
+/*! @brief Class passed to an error.
+
+This class encapsulates all or almost all necessary
+information about the error happened in the program. The exception is
+usually constructed and thrown implicitly via CV_Error and CV_Error_ macros.
+@see error
+ */
+class CV_EXPORTS Exception : public std::exception
+{
+public:
+ /*!
+ Default constructor
+ */
+ Exception();
+ /*!
+ Full constructor. Normally the constuctor is not called explicitly.
+ Instead, the macros CV_Error(), CV_Error_() and CV_Assert() are used.
+ */
+ Exception(int _code, const String& _err, const String& _func, const String& _file, int _line);
+ virtual ~Exception() throw();
+
+ /*!
+ \return the error description and the context as a text string.
+ */
+ virtual const char *what() const throw();
+ void formatMessage();
+
+ String msg; ///< the formatted error message
+
+ int code; ///< error code @see CVStatus
+ String err; ///< error description
+ String func; ///< function name. Available only when the compiler supports getting it
+ String file; ///< source file name where the error has occured
+ int line; ///< line number in the source file where the error has occured
+};
+
+/*! @brief Signals an error and raises the exception.
+
+By default the function prints information about the error to stderr,
+then it either stops if cv::setBreakOnError() had been called before or raises the exception.
+It is possible to alternate error processing by using cv::redirectError().
+@param exc the exception raisen.
+@deprecated drop this version
+ */
+CV_EXPORTS void error( const Exception& exc );
+
+enum SortFlags { SORT_EVERY_ROW = 0, //!< each matrix row is sorted independently
+ SORT_EVERY_COLUMN = 1, //!< each matrix column is sorted
+ //!< independently; this flag and the previous one are
+ //!< mutually exclusive.
+ SORT_ASCENDING = 0, //!< each matrix row is sorted in the ascending
+ //!< order.
+ SORT_DESCENDING = 16 //!< each matrix row is sorted in the
+ //!< descending order; this flag and the previous one are also
+ //!< mutually exclusive.
+ };
+
+//! @} core_utils
+
+//! @addtogroup core
+//! @{
+
+//! Covariation flags
+enum CovarFlags {
+ /** The output covariance matrix is calculated as:
+ \f[\texttt{scale} \cdot [ \texttt{vects} [0]- \texttt{mean} , \texttt{vects} [1]- \texttt{mean} ,...]^T \cdot [ \texttt{vects} [0]- \texttt{mean} , \texttt{vects} [1]- \texttt{mean} ,...],\f]
+ The covariance matrix will be nsamples x nsamples. Such an unusual covariance matrix is used
+ for fast PCA of a set of very large vectors (see, for example, the EigenFaces technique for
+ face recognition). Eigenvalues of this "scrambled" matrix match the eigenvalues of the true
+ covariance matrix. The "true" eigenvectors can be easily calculated from the eigenvectors of
+ the "scrambled" covariance matrix. */
+ COVAR_SCRAMBLED = 0,
+ /**The output covariance matrix is calculated as:
+ \f[\texttt{scale} \cdot [ \texttt{vects} [0]- \texttt{mean} , \texttt{vects} [1]- \texttt{mean} ,...] \cdot [ \texttt{vects} [0]- \texttt{mean} , \texttt{vects} [1]- \texttt{mean} ,...]^T,\f]
+ covar will be a square matrix of the same size as the total number of elements in each input
+ vector. One and only one of COVAR_SCRAMBLED and COVAR_NORMAL must be specified.*/
+ COVAR_NORMAL = 1,
+ /** If the flag is specified, the function does not calculate mean from
+ the input vectors but, instead, uses the passed mean vector. This is useful if mean has been
+ pre-calculated or known in advance, or if the covariance matrix is calculated by parts. In
+ this case, mean is not a mean vector of the input sub-set of vectors but rather the mean
+ vector of the whole set.*/
+ COVAR_USE_AVG = 2,
+ /** If the flag is specified, the covariance matrix is scaled. In the
+ "normal" mode, scale is 1./nsamples . In the "scrambled" mode, scale is the reciprocal of the
+ total number of elements in each input vector. By default (if the flag is not specified), the
+ covariance matrix is not scaled ( scale=1 ).*/
+ COVAR_SCALE = 4,
+ /** If the flag is
+ specified, all the input vectors are stored as rows of the samples matrix. mean should be a
+ single-row vector in this case.*/
+ COVAR_ROWS = 8,
+ /** If the flag is
+ specified, all the input vectors are stored as columns of the samples matrix. mean should be a
+ single-column vector in this case.*/
+ COVAR_COLS = 16
+};
+
+//! k-Means flags
+enum KmeansFlags {
+ /** Select random initial centers in each attempt.*/
+ KMEANS_RANDOM_CENTERS = 0,
+ /** Use kmeans++ center initialization by Arthur and Vassilvitskii [Arthur2007].*/
+ KMEANS_PP_CENTERS = 2,
+ /** During the first (and possibly the only) attempt, use the
+ user-supplied labels instead of computing them from the initial centers. For the second and
+ further attempts, use the random or semi-random centers. Use one of KMEANS_\*_CENTERS flag
+ to specify the exact method.*/
+ KMEANS_USE_INITIAL_LABELS = 1
+};
+
+//! type of line
+enum LineTypes {
+ FILLED = -1,
+ LINE_4 = 4, //!< 4-connected line
+ LINE_8 = 8, //!< 8-connected line
+ LINE_AA = 16 //!< antialiased line
+};
+
+//! Only a subset of Hershey fonts
+//! are supported
+enum HersheyFonts {
+ FONT_HERSHEY_SIMPLEX = 0, //!< normal size sans-serif font
+ FONT_HERSHEY_PLAIN = 1, //!< small size sans-serif font
+ FONT_HERSHEY_DUPLEX = 2, //!< normal size sans-serif font (more complex than FONT_HERSHEY_SIMPLEX)
+ FONT_HERSHEY_COMPLEX = 3, //!< normal size serif font
+ FONT_HERSHEY_TRIPLEX = 4, //!< normal size serif font (more complex than FONT_HERSHEY_COMPLEX)
+ FONT_HERSHEY_COMPLEX_SMALL = 5, //!< smaller version of FONT_HERSHEY_COMPLEX
+ FONT_HERSHEY_SCRIPT_SIMPLEX = 6, //!< hand-writing style font
+ FONT_HERSHEY_SCRIPT_COMPLEX = 7, //!< more complex variant of FONT_HERSHEY_SCRIPT_SIMPLEX
+ FONT_ITALIC = 16 //!< flag for italic font
+};
+
+enum ReduceTypes { REDUCE_SUM = 0, //!< the output is the sum of all rows/columns of the matrix.
+ REDUCE_AVG = 1, //!< the output is the mean vector of all rows/columns of the matrix.
+ REDUCE_MAX = 2, //!< the output is the maximum (column/row-wise) of all rows/columns of the matrix.
+ REDUCE_MIN = 3 //!< the output is the minimum (column/row-wise) of all rows/columns of the matrix.
+ };
+
+
+/** @brief Swaps two matrices
+*/
+CV_EXPORTS void swap(Mat& a, Mat& b);
+/** @overload */
+CV_EXPORTS void swap( UMat& a, UMat& b );
+
+//! @} core
+
+//! @addtogroup core_array
+//! @{
+
+/** @brief Computes the source location of an extrapolated pixel.
+
+The function computes and returns the coordinate of a donor pixel corresponding to the specified
+extrapolated pixel when using the specified extrapolation border mode. For example, if you use
+cv::BORDER_WRAP mode in the horizontal direction, cv::BORDER_REFLECT_101 in the vertical direction and
+want to compute value of the "virtual" pixel Point(-5, 100) in a floating-point image img , it
+looks like:
+@code{.cpp}
+ float val = img.at(borderInterpolate(100, img.rows, cv::BORDER_REFLECT_101),
+ borderInterpolate(-5, img.cols, cv::BORDER_WRAP));
+@endcode
+Normally, the function is not called directly. It is used inside filtering functions and also in
+copyMakeBorder.
+@param p 0-based coordinate of the extrapolated pixel along one of the axes, likely \<0 or \>= len
+@param len Length of the array along the corresponding axis.
+@param borderType Border type, one of the cv::BorderTypes, except for cv::BORDER_TRANSPARENT and
+cv::BORDER_ISOLATED . When borderType==cv::BORDER_CONSTANT , the function always returns -1, regardless
+of p and len.
+
+@sa copyMakeBorder
+*/
+CV_EXPORTS_W int borderInterpolate(int p, int len, int borderType);
+
+/** @brief Forms a border around an image.
+
+The function copies the source image into the middle of the destination image. The areas to the
+left, to the right, above and below the copied source image will be filled with extrapolated
+pixels. This is not what filtering functions based on it do (they extrapolate pixels on-fly), but
+what other more complex functions, including your own, may do to simplify image boundary handling.
+
+The function supports the mode when src is already in the middle of dst . In this case, the
+function does not copy src itself but simply constructs the border, for example:
+
+@code{.cpp}
+ // let border be the same in all directions
+ int border=2;
+ // constructs a larger image to fit both the image and the border
+ Mat gray_buf(rgb.rows + border*2, rgb.cols + border*2, rgb.depth());
+ // select the middle part of it w/o copying data
+ Mat gray(gray_canvas, Rect(border, border, rgb.cols, rgb.rows));
+ // convert image from RGB to grayscale
+ cvtColor(rgb, gray, COLOR_RGB2GRAY);
+ // form a border in-place
+ copyMakeBorder(gray, gray_buf, border, border,
+ border, border, BORDER_REPLICATE);
+ // now do some custom filtering ...
+ ...
+@endcode
+@note When the source image is a part (ROI) of a bigger image, the function will try to use the
+pixels outside of the ROI to form a border. To disable this feature and always do extrapolation, as
+if src was not a ROI, use borderType | BORDER_ISOLATED.
+
+@param src Source image.
+@param dst Destination image of the same type as src and the size Size(src.cols+left+right,
+src.rows+top+bottom) .
+@param top
+@param bottom
+@param left
+@param right Parameter specifying how many pixels in each direction from the source image rectangle
+to extrapolate. For example, top=1, bottom=1, left=1, right=1 mean that 1 pixel-wide border needs
+to be built.
+@param borderType Border type. See borderInterpolate for details.
+@param value Border value if borderType==BORDER_CONSTANT .
+
+@sa borderInterpolate
+*/
+CV_EXPORTS_W void copyMakeBorder(InputArray src, OutputArray dst,
+ int top, int bottom, int left, int right,
+ int borderType, const Scalar& value = Scalar() );
+
+/** @brief Calculates the per-element sum of two arrays or an array and a scalar.
+
+The function add calculates:
+- Sum of two arrays when both input arrays have the same size and the same number of channels:
+\f[\texttt{dst}(I) = \texttt{saturate} ( \texttt{src1}(I) + \texttt{src2}(I)) \quad \texttt{if mask}(I) \ne0\f]
+- Sum of an array and a scalar when src2 is constructed from Scalar or has the same number of
+elements as `src1.channels()`:
+\f[\texttt{dst}(I) = \texttt{saturate} ( \texttt{src1}(I) + \texttt{src2} ) \quad \texttt{if mask}(I) \ne0\f]
+- Sum of a scalar and an array when src1 is constructed from Scalar or has the same number of
+elements as `src2.channels()`:
+\f[\texttt{dst}(I) = \texttt{saturate} ( \texttt{src1} + \texttt{src2}(I) ) \quad \texttt{if mask}(I) \ne0\f]
+where `I` is a multi-dimensional index of array elements. In case of multi-channel arrays, each
+channel is processed independently.
+
+The first function in the list above can be replaced with matrix expressions:
+@code{.cpp}
+ dst = src1 + src2;
+ dst += src1; // equivalent to add(dst, src1, dst);
+@endcode
+The input arrays and the output array can all have the same or different depths. For example, you
+can add a 16-bit unsigned array to a 8-bit signed array and store the sum as a 32-bit
+floating-point array. Depth of the output array is determined by the dtype parameter. In the second
+and third cases above, as well as in the first case, when src1.depth() == src2.depth(), dtype can
+be set to the default -1. In this case, the output array will have the same depth as the input
+array, be it src1, src2 or both.
+@note Saturation is not applied when the output array has the depth CV_32S. You may even get
+result of an incorrect sign in the case of overflow.
+@param src1 first input array or a scalar.
+@param src2 second input array or a scalar.
+@param dst output array that has the same size and number of channels as the input array(s); the
+depth is defined by dtype or src1/src2.
+@param mask optional operation mask - 8-bit single channel array, that specifies elements of the
+output array to be changed.
+@param dtype optional depth of the output array (see the discussion below).
+@sa subtract, addWeighted, scaleAdd, Mat::convertTo
+*/
+CV_EXPORTS_W void add(InputArray src1, InputArray src2, OutputArray dst,
+ InputArray mask = noArray(), int dtype = -1);
+
+/** @brief Calculates the per-element difference between two arrays or array and a scalar.
+
+The function subtract calculates:
+- Difference between two arrays, when both input arrays have the same size and the same number of
+channels:
+ \f[\texttt{dst}(I) = \texttt{saturate} ( \texttt{src1}(I) - \texttt{src2}(I)) \quad \texttt{if mask}(I) \ne0\f]
+- Difference between an array and a scalar, when src2 is constructed from Scalar or has the same
+number of elements as `src1.channels()`:
+ \f[\texttt{dst}(I) = \texttt{saturate} ( \texttt{src1}(I) - \texttt{src2} ) \quad \texttt{if mask}(I) \ne0\f]
+- Difference between a scalar and an array, when src1 is constructed from Scalar or has the same
+number of elements as `src2.channels()`:
+ \f[\texttt{dst}(I) = \texttt{saturate} ( \texttt{src1} - \texttt{src2}(I) ) \quad \texttt{if mask}(I) \ne0\f]
+- The reverse difference between a scalar and an array in the case of `SubRS`:
+ \f[\texttt{dst}(I) = \texttt{saturate} ( \texttt{src2} - \texttt{src1}(I) ) \quad \texttt{if mask}(I) \ne0\f]
+where I is a multi-dimensional index of array elements. In case of multi-channel arrays, each
+channel is processed independently.
+
+The first function in the list above can be replaced with matrix expressions:
+@code{.cpp}
+ dst = src1 - src2;
+ dst -= src1; // equivalent to subtract(dst, src1, dst);
+@endcode
+The input arrays and the output array can all have the same or different depths. For example, you
+can subtract to 8-bit unsigned arrays and store the difference in a 16-bit signed array. Depth of
+the output array is determined by dtype parameter. In the second and third cases above, as well as
+in the first case, when src1.depth() == src2.depth(), dtype can be set to the default -1. In this
+case the output array will have the same depth as the input array, be it src1, src2 or both.
+@note Saturation is not applied when the output array has the depth CV_32S. You may even get
+result of an incorrect sign in the case of overflow.
+@param src1 first input array or a scalar.
+@param src2 second input array or a scalar.
+@param dst output array of the same size and the same number of channels as the input array.
+@param mask optional operation mask; this is an 8-bit single channel array that specifies elements
+of the output array to be changed.
+@param dtype optional depth of the output array
+@sa add, addWeighted, scaleAdd, Mat::convertTo
+ */
+CV_EXPORTS_W void subtract(InputArray src1, InputArray src2, OutputArray dst,
+ InputArray mask = noArray(), int dtype = -1);
+
+
+/** @brief Calculates the per-element scaled product of two arrays.
+
+The function multiply calculates the per-element product of two arrays:
+
+\f[\texttt{dst} (I)= \texttt{saturate} ( \texttt{scale} \cdot \texttt{src1} (I) \cdot \texttt{src2} (I))\f]
+
+There is also a @ref MatrixExpressions -friendly variant of the first function. See Mat::mul .
+
+For a not-per-element matrix product, see gemm .
+
+@note Saturation is not applied when the output array has the depth
+CV_32S. You may even get result of an incorrect sign in the case of
+overflow.
+@param src1 first input array.
+@param src2 second input array of the same size and the same type as src1.
+@param dst output array of the same size and type as src1.
+@param scale optional scale factor.
+@param dtype optional depth of the output array
+@sa add, subtract, divide, scaleAdd, addWeighted, accumulate, accumulateProduct, accumulateSquare,
+Mat::convertTo
+*/
+CV_EXPORTS_W void multiply(InputArray src1, InputArray src2,
+ OutputArray dst, double scale = 1, int dtype = -1);
+
+/** @brief Performs per-element division of two arrays or a scalar by an array.
+
+The functions divide divide one array by another:
+\f[\texttt{dst(I) = saturate(src1(I)*scale/src2(I))}\f]
+or a scalar by an array when there is no src1 :
+\f[\texttt{dst(I) = saturate(scale/src2(I))}\f]
+
+When src2(I) is zero, dst(I) will also be zero. Different channels of
+multi-channel arrays are processed independently.
+
+@note Saturation is not applied when the output array has the depth CV_32S. You may even get
+result of an incorrect sign in the case of overflow.
+@param src1 first input array.
+@param src2 second input array of the same size and type as src1.
+@param scale scalar factor.
+@param dst output array of the same size and type as src2.
+@param dtype optional depth of the output array; if -1, dst will have depth src2.depth(), but in
+case of an array-by-array division, you can only pass -1 when src1.depth()==src2.depth().
+@sa multiply, add, subtract
+*/
+CV_EXPORTS_W void divide(InputArray src1, InputArray src2, OutputArray dst,
+ double scale = 1, int dtype = -1);
+
+/** @overload */
+CV_EXPORTS_W void divide(double scale, InputArray src2,
+ OutputArray dst, int dtype = -1);
+
+/** @brief Calculates the sum of a scaled array and another array.
+
+The function scaleAdd is one of the classical primitive linear algebra operations, known as DAXPY
+or SAXPY in [BLAS](http://en.wikipedia.org/wiki/Basic_Linear_Algebra_Subprograms). It calculates
+the sum of a scaled array and another array:
+\f[\texttt{dst} (I)= \texttt{scale} \cdot \texttt{src1} (I) + \texttt{src2} (I)\f]
+The function can also be emulated with a matrix expression, for example:
+@code{.cpp}
+ Mat A(3, 3, CV_64F);
+ ...
+ A.row(0) = A.row(1)*2 + A.row(2);
+@endcode
+@param src1 first input array.
+@param alpha scale factor for the first array.
+@param src2 second input array of the same size and type as src1.
+@param dst output array of the same size and type as src1.
+@sa add, addWeighted, subtract, Mat::dot, Mat::convertTo
+*/
+CV_EXPORTS_W void scaleAdd(InputArray src1, double alpha, InputArray src2, OutputArray dst);
+
+/** @brief Calculates the weighted sum of two arrays.
+
+The function addWeighted calculates the weighted sum of two arrays as follows:
+\f[\texttt{dst} (I)= \texttt{saturate} ( \texttt{src1} (I)* \texttt{alpha} + \texttt{src2} (I)* \texttt{beta} + \texttt{gamma} )\f]
+where I is a multi-dimensional index of array elements. In case of multi-channel arrays, each
+channel is processed independently.
+The function can be replaced with a matrix expression:
+@code{.cpp}
+ dst = src1*alpha + src2*beta + gamma;
+@endcode
+@note Saturation is not applied when the output array has the depth CV_32S. You may even get
+result of an incorrect sign in the case of overflow.
+@param src1 first input array.
+@param alpha weight of the first array elements.
+@param src2 second input array of the same size and channel number as src1.
+@param beta weight of the second array elements.
+@param gamma scalar added to each sum.
+@param dst output array that has the same size and number of channels as the input arrays.
+@param dtype optional depth of the output array; when both input arrays have the same depth, dtype
+can be set to -1, which will be equivalent to src1.depth().
+@sa add, subtract, scaleAdd, Mat::convertTo
+*/
+CV_EXPORTS_W void addWeighted(InputArray src1, double alpha, InputArray src2,
+ double beta, double gamma, OutputArray dst, int dtype = -1);
+
+/** @brief Scales, calculates absolute values, and converts the result to 8-bit.
+
+On each element of the input array, the function convertScaleAbs
+performs three operations sequentially: scaling, taking an absolute
+value, conversion to an unsigned 8-bit type:
+\f[\texttt{dst} (I)= \texttt{saturate\_cast} (| \texttt{src} (I)* \texttt{alpha} + \texttt{beta} |)\f]
+In case of multi-channel arrays, the function processes each channel
+independently. When the output is not 8-bit, the operation can be
+emulated by calling the Mat::convertTo method (or by using matrix
+expressions) and then by calculating an absolute value of the result.
+For example:
+@code{.cpp}
+ Mat_ A(30,30);
+ randu(A, Scalar(-100), Scalar(100));
+ Mat_ B = A*5 + 3;
+ B = abs(B);
+ // Mat_ B = abs(A*5+3) will also do the job,
+ // but it will allocate a temporary matrix
+@endcode
+@param src input array.
+@param dst output array.
+@param alpha optional scale factor.
+@param beta optional delta added to the scaled values.
+@sa Mat::convertTo, cv::abs(const Mat&)
+*/
+CV_EXPORTS_W void convertScaleAbs(InputArray src, OutputArray dst,
+ double alpha = 1, double beta = 0);
+
+/** @brief Performs a look-up table transform of an array.
+
+The function LUT fills the output array with values from the look-up table. Indices of the entries
+are taken from the input array. That is, the function processes each element of src as follows:
+\f[\texttt{dst} (I) \leftarrow \texttt{lut(src(I) + d)}\f]
+where
+\f[d = \fork{0}{if \(\texttt{src}\) has depth \(\texttt{CV_8U}\)}{128}{if \(\texttt{src}\) has depth \(\texttt{CV_8S}\)}\f]
+@param src input array of 8-bit elements.
+@param lut look-up table of 256 elements; in case of multi-channel input array, the table should
+either have a single channel (in this case the same table is used for all channels) or the same
+number of channels as in the input array.
+@param dst output array of the same size and number of channels as src, and the same depth as lut.
+@sa convertScaleAbs, Mat::convertTo
+*/
+CV_EXPORTS_W void LUT(InputArray src, InputArray lut, OutputArray dst);
+
+/** @brief Calculates the sum of array elements.
+
+The functions sum calculate and return the sum of array elements,
+independently for each channel.
+@param src input array that must have from 1 to 4 channels.
+@sa countNonZero, mean, meanStdDev, norm, minMaxLoc, reduce
+*/
+CV_EXPORTS_AS(sumElems) Scalar sum(InputArray src);
+
+/** @brief Counts non-zero array elements.
+
+The function returns the number of non-zero elements in src :
+\f[\sum _{I: \; \texttt{src} (I) \ne0 } 1\f]
+@param src single-channel array.
+@sa mean, meanStdDev, norm, minMaxLoc, calcCovarMatrix
+*/
+CV_EXPORTS_W int countNonZero( InputArray src );
+
+/** @brief Returns the list of locations of non-zero pixels
+
+Given a binary matrix (likely returned from an operation such
+as threshold(), compare(), >, ==, etc, return all of
+the non-zero indices as a cv::Mat or std::vector (x,y)
+For example:
+@code{.cpp}
+ cv::Mat binaryImage; // input, binary image
+ cv::Mat locations; // output, locations of non-zero pixels
+ cv::findNonZero(binaryImage, locations);
+
+ // access pixel coordinates
+ Point pnt = locations.at(i);
+@endcode
+or
+@code{.cpp}
+ cv::Mat binaryImage; // input, binary image
+ vector locations; // output, locations of non-zero pixels
+ cv::findNonZero(binaryImage, locations);
+
+ // access pixel coordinates
+ Point pnt = locations[i];
+@endcode
+@param src single-channel array (type CV_8UC1)
+@param idx the output array, type of cv::Mat or std::vector, corresponding to non-zero indices in the input
+*/
+CV_EXPORTS_W void findNonZero( InputArray src, OutputArray idx );
+
+/** @brief Calculates an average (mean) of array elements.
+
+The function mean calculates the mean value M of array elements,
+independently for each channel, and return it:
+\f[\begin{array}{l} N = \sum _{I: \; \texttt{mask} (I) \ne 0} 1 \\ M_c = \left ( \sum _{I: \; \texttt{mask} (I) \ne 0}{ \texttt{mtx} (I)_c} \right )/N \end{array}\f]
+When all the mask elements are 0's, the functions return Scalar::all(0)
+@param src input array that should have from 1 to 4 channels so that the result can be stored in
+Scalar_ .
+@param mask optional operation mask.
+@sa countNonZero, meanStdDev, norm, minMaxLoc
+*/
+CV_EXPORTS_W Scalar mean(InputArray src, InputArray mask = noArray());
+
+/** Calculates a mean and standard deviation of array elements.
+
+The function meanStdDev calculates the mean and the standard deviation M
+of array elements independently for each channel and returns it via the
+output parameters:
+\f[\begin{array}{l} N = \sum _{I, \texttt{mask} (I) \ne 0} 1 \\ \texttt{mean} _c = \frac{\sum_{ I: \; \texttt{mask}(I) \ne 0} \texttt{src} (I)_c}{N} \\ \texttt{stddev} _c = \sqrt{\frac{\sum_{ I: \; \texttt{mask}(I) \ne 0} \left ( \texttt{src} (I)_c - \texttt{mean} _c \right )^2}{N}} \end{array}\f]
+When all the mask elements are 0's, the functions return
+mean=stddev=Scalar::all(0).
+@note The calculated standard deviation is only the diagonal of the
+complete normalized covariance matrix. If the full matrix is needed, you
+can reshape the multi-channel array M x N to the single-channel array
+M\*N x mtx.channels() (only possible when the matrix is continuous) and
+then pass the matrix to calcCovarMatrix .
+@param src input array that should have from 1 to 4 channels so that the results can be stored in
+Scalar_ 's.
+@param mean output parameter: calculated mean value.
+@param stddev output parameter: calculateded standard deviation.
+@param mask optional operation mask.
+@sa countNonZero, mean, norm, minMaxLoc, calcCovarMatrix
+*/
+CV_EXPORTS_W void meanStdDev(InputArray src, OutputArray mean, OutputArray stddev,
+ InputArray mask=noArray());
+
+/** @brief Calculates an absolute array norm, an absolute difference norm, or a
+relative difference norm.
+
+The functions norm calculate an absolute norm of src1 (when there is no
+src2 ):
+
+\f[norm = \forkthree{\|\texttt{src1}\|_{L_{\infty}} = \max _I | \texttt{src1} (I)|}{if \(\texttt{normType} = \texttt{NORM_INF}\) }
+{ \| \texttt{src1} \| _{L_1} = \sum _I | \texttt{src1} (I)|}{if \(\texttt{normType} = \texttt{NORM_L1}\) }
+{ \| \texttt{src1} \| _{L_2} = \sqrt{\sum_I \texttt{src1}(I)^2} }{if \(\texttt{normType} = \texttt{NORM_L2}\) }\f]
+
+or an absolute or relative difference norm if src2 is there:
+
+\f[norm = \forkthree{\|\texttt{src1}-\texttt{src2}\|_{L_{\infty}} = \max _I | \texttt{src1} (I) - \texttt{src2} (I)|}{if \(\texttt{normType} = \texttt{NORM_INF}\) }
+{ \| \texttt{src1} - \texttt{src2} \| _{L_1} = \sum _I | \texttt{src1} (I) - \texttt{src2} (I)|}{if \(\texttt{normType} = \texttt{NORM_L1}\) }
+{ \| \texttt{src1} - \texttt{src2} \| _{L_2} = \sqrt{\sum_I (\texttt{src1}(I) - \texttt{src2}(I))^2} }{if \(\texttt{normType} = \texttt{NORM_L2}\) }\f]
+
+or
+
+\f[norm = \forkthree{\frac{\|\texttt{src1}-\texttt{src2}\|_{L_{\infty}} }{\|\texttt{src2}\|_{L_{\infty}} }}{if \(\texttt{normType} = \texttt{NORM_RELATIVE_INF}\) }
+{ \frac{\|\texttt{src1}-\texttt{src2}\|_{L_1} }{\|\texttt{src2}\|_{L_1}} }{if \(\texttt{normType} = \texttt{NORM_RELATIVE_L1}\) }
+{ \frac{\|\texttt{src1}-\texttt{src2}\|_{L_2} }{\|\texttt{src2}\|_{L_2}} }{if \(\texttt{normType} = \texttt{NORM_RELATIVE_L2}\) }\f]
+
+The functions norm return the calculated norm.
+
+When the mask parameter is specified and it is not empty, the norm is
+calculated only over the region specified by the mask.
+
+A multi-channel input arrays are treated as a single-channel, that is,
+the results for all channels are combined.
+
+@param src1 first input array.
+@param normType type of the norm (see cv::NormTypes).
+@param mask optional operation mask; it must have the same size as src1 and CV_8UC1 type.
+*/
+CV_EXPORTS_W double norm(InputArray src1, int normType = NORM_L2, InputArray mask = noArray());
+
+/** @overload
+@param src1 first input array.
+@param src2 second input array of the same size and the same type as src1.
+@param normType type of the norm (cv::NormTypes).
+@param mask optional operation mask; it must have the same size as src1 and CV_8UC1 type.
+*/
+CV_EXPORTS_W double norm(InputArray src1, InputArray src2,
+ int normType = NORM_L2, InputArray mask = noArray());
+/** @overload
+@param src first input array.
+@param normType type of the norm (see cv::NormTypes).
+*/
+CV_EXPORTS double norm( const SparseMat& src, int normType );
+
+/** @brief computes PSNR image/video quality metric
+
+see http://en.wikipedia.org/wiki/Peak_signal-to-noise_ratio for details
+@todo document
+ */
+CV_EXPORTS_W double PSNR(InputArray src1, InputArray src2);
+
+/** @brief naive nearest neighbor finder
+
+see http://en.wikipedia.org/wiki/Nearest_neighbor_search
+@todo document
+ */
+CV_EXPORTS_W void batchDistance(InputArray src1, InputArray src2,
+ OutputArray dist, int dtype, OutputArray nidx,
+ int normType = NORM_L2, int K = 0,
+ InputArray mask = noArray(), int update = 0,
+ bool crosscheck = false);
+
+/** @brief Normalizes the norm or value range of an array.
+
+The functions normalize scale and shift the input array elements so that
+\f[\| \texttt{dst} \| _{L_p}= \texttt{alpha}\f]
+(where p=Inf, 1 or 2) when normType=NORM_INF, NORM_L1, or NORM_L2, respectively; or so that
+\f[\min _I \texttt{dst} (I)= \texttt{alpha} , \, \, \max _I \texttt{dst} (I)= \texttt{beta}\f]
+
+when normType=NORM_MINMAX (for dense arrays only). The optional mask specifies a sub-array to be
+normalized. This means that the norm or min-n-max are calculated over the sub-array, and then this
+sub-array is modified to be normalized. If you want to only use the mask to calculate the norm or
+min-max but modify the whole array, you can use norm and Mat::convertTo.
+
+In case of sparse matrices, only the non-zero values are analyzed and transformed. Because of this,
+the range transformation for sparse matrices is not allowed since it can shift the zero level.
+
+Possible usage with some positive example data:
+@code{.cpp}
+ vector positiveData = { 2.0, 8.0, 10.0 };
+ vector normalizedData_l1, normalizedData_l2, normalizedData_inf, normalizedData_minmax;
+
+ // Norm to probability (total count)
+ // sum(numbers) = 20.0
+ // 2.0 0.1 (2.0/20.0)
+ // 8.0 0.4 (8.0/20.0)
+ // 10.0 0.5 (10.0/20.0)
+ normalize(positiveData, normalizedData_l1, 1.0, 0.0, NORM_L1);
+
+ // Norm to unit vector: ||positiveData|| = 1.0
+ // 2.0 0.15
+ // 8.0 0.62
+ // 10.0 0.77
+ normalize(positiveData, normalizedData_l2, 1.0, 0.0, NORM_L2);
+
+ // Norm to max element
+ // 2.0 0.2 (2.0/10.0)
+ // 8.0 0.8 (8.0/10.0)
+ // 10.0 1.0 (10.0/10.0)
+ normalize(positiveData, normalizedData_inf, 1.0, 0.0, NORM_INF);
+
+ // Norm to range [0.0;1.0]
+ // 2.0 0.0 (shift to left border)
+ // 8.0 0.75 (6.0/8.0)
+ // 10.0 1.0 (shift to right border)
+ normalize(positiveData, normalizedData_minmax, 1.0, 0.0, NORM_MINMAX);
+@endcode
+
+@param src input array.
+@param dst output array of the same size as src .
+@param alpha norm value to normalize to or the lower range boundary in case of the range
+normalization.
+@param beta upper range boundary in case of the range normalization; it is not used for the norm
+normalization.
+@param norm_type normalization type (see cv::NormTypes).
+@param dtype when negative, the output array has the same type as src; otherwise, it has the same
+number of channels as src and the depth =CV_MAT_DEPTH(dtype).
+@param mask optional operation mask.
+@sa norm, Mat::convertTo, SparseMat::convertTo
+*/
+CV_EXPORTS_W void normalize( InputArray src, InputOutputArray dst, double alpha = 1, double beta = 0,
+ int norm_type = NORM_L2, int dtype = -1, InputArray mask = noArray());
+
+/** @overload
+@param src input array.
+@param dst output array of the same size as src .
+@param alpha norm value to normalize to or the lower range boundary in case of the range
+normalization.
+@param normType normalization type (see cv::NormTypes).
+*/
+CV_EXPORTS void normalize( const SparseMat& src, SparseMat& dst, double alpha, int normType );
+
+/** @brief Finds the global minimum and maximum in an array.
+
+The functions minMaxLoc find the minimum and maximum element values and their positions. The
+extremums are searched across the whole array or, if mask is not an empty array, in the specified
+array region.
+
+The functions do not work with multi-channel arrays. If you need to find minimum or maximum
+elements across all the channels, use Mat::reshape first to reinterpret the array as
+single-channel. Or you may extract the particular channel using either extractImageCOI , or
+mixChannels , or split .
+@param src input single-channel array.
+@param minVal pointer to the returned minimum value; NULL is used if not required.
+@param maxVal pointer to the returned maximum value; NULL is used if not required.
+@param minLoc pointer to the returned minimum location (in 2D case); NULL is used if not required.
+@param maxLoc pointer to the returned maximum location (in 2D case); NULL is used if not required.
+@param mask optional mask used to select a sub-array.
+@sa max, min, compare, inRange, extractImageCOI, mixChannels, split, Mat::reshape
+*/
+CV_EXPORTS_W void minMaxLoc(InputArray src, CV_OUT double* minVal,
+ CV_OUT double* maxVal = 0, CV_OUT Point* minLoc = 0,
+ CV_OUT Point* maxLoc = 0, InputArray mask = noArray());
+
+
+/** @brief Finds the global minimum and maximum in an array
+
+The function minMaxIdx finds the minimum and maximum element values and their positions. The
+extremums are searched across the whole array or, if mask is not an empty array, in the specified
+array region. The function does not work with multi-channel arrays. If you need to find minimum or
+maximum elements across all the channels, use Mat::reshape first to reinterpret the array as
+single-channel. Or you may extract the particular channel using either extractImageCOI , or
+mixChannels , or split . In case of a sparse matrix, the minimum is found among non-zero elements
+only.
+@note When minIdx is not NULL, it must have at least 2 elements (as well as maxIdx), even if src is
+a single-row or single-column matrix. In OpenCV (following MATLAB) each array has at least 2
+dimensions, i.e. single-column matrix is Mx1 matrix (and therefore minIdx/maxIdx will be
+(i1,0)/(i2,0)) and single-row matrix is 1xN matrix (and therefore minIdx/maxIdx will be
+(0,j1)/(0,j2)).
+@param src input single-channel array.
+@param minVal pointer to the returned minimum value; NULL is used if not required.
+@param maxVal pointer to the returned maximum value; NULL is used if not required.
+@param minIdx pointer to the returned minimum location (in nD case); NULL is used if not required;
+Otherwise, it must point to an array of src.dims elements, the coordinates of the minimum element
+in each dimension are stored there sequentially.
+@param maxIdx pointer to the returned maximum location (in nD case). NULL is used if not required.
+@param mask specified array region
+*/
+CV_EXPORTS void minMaxIdx(InputArray src, double* minVal, double* maxVal = 0,
+ int* minIdx = 0, int* maxIdx = 0, InputArray mask = noArray());
+
+/** @overload
+@param a input single-channel array.
+@param minVal pointer to the returned minimum value; NULL is used if not required.
+@param maxVal pointer to the returned maximum value; NULL is used if not required.
+@param minIdx pointer to the returned minimum location (in nD case); NULL is used if not required;
+Otherwise, it must point to an array of src.dims elements, the coordinates of the minimum element
+in each dimension are stored there sequentially.
+@param maxIdx pointer to the returned maximum location (in nD case). NULL is used if not required.
+*/
+CV_EXPORTS void minMaxLoc(const SparseMat& a, double* minVal,
+ double* maxVal, int* minIdx = 0, int* maxIdx = 0);
+
+/** @brief Reduces a matrix to a vector.
+
+The function reduce reduces the matrix to a vector by treating the matrix rows/columns as a set of
+1D vectors and performing the specified operation on the vectors until a single row/column is
+obtained. For example, the function can be used to compute horizontal and vertical projections of a
+raster image. In case of REDUCE_SUM and REDUCE_AVG , the output may have a larger element
+bit-depth to preserve accuracy. And multi-channel arrays are also supported in these two reduction
+modes.
+@param src input 2D matrix.
+@param dst output vector. Its size and type is defined by dim and dtype parameters.
+@param dim dimension index along which the matrix is reduced. 0 means that the matrix is reduced to
+a single row. 1 means that the matrix is reduced to a single column.
+@param rtype reduction operation that could be one of cv::ReduceTypes
+@param dtype when negative, the output vector will have the same type as the input matrix,
+otherwise, its type will be CV_MAKE_TYPE(CV_MAT_DEPTH(dtype), src.channels()).
+@sa repeat
+*/
+CV_EXPORTS_W void reduce(InputArray src, OutputArray dst, int dim, int rtype, int dtype = -1);
+
+/** @brief Creates one multi-channel array out of several single-channel ones.
+
+The function merge merges several arrays to make a single multi-channel array. That is, each
+element of the output array will be a concatenation of the elements of the input arrays, where
+elements of i-th input array are treated as mv[i].channels()-element vectors.
+
+The function cv::split does the reverse operation. If you need to shuffle channels in some other
+advanced way, use cv::mixChannels.
+@param mv input array of matrices to be merged; all the matrices in mv must have the same
+size and the same depth.
+@param count number of input matrices when mv is a plain C array; it must be greater than zero.
+@param dst output array of the same size and the same depth as mv[0]; The number of channels will
+be equal to the parameter count.
+@sa mixChannels, split, Mat::reshape
+*/
+CV_EXPORTS void merge(const Mat* mv, size_t count, OutputArray dst);
+
+/** @overload
+@param mv input vector of matrices to be merged; all the matrices in mv must have the same
+size and the same depth.
+@param dst output array of the same size and the same depth as mv[0]; The number of channels will
+be the total number of channels in the matrix array.
+ */
+CV_EXPORTS_W void merge(InputArrayOfArrays mv, OutputArray dst);
+
+/** @brief Divides a multi-channel array into several single-channel arrays.
+
+The functions split split a multi-channel array into separate single-channel arrays:
+\f[\texttt{mv} [c](I) = \texttt{src} (I)_c\f]
+If you need to extract a single channel or do some other sophisticated channel permutation, use
+mixChannels .
+@param src input multi-channel array.
+@param mvbegin output array; the number of arrays must match src.channels(); the arrays themselves are
+reallocated, if needed.
+@sa merge, mixChannels, cvtColor
+*/
+CV_EXPORTS void split(const Mat& src, Mat* mvbegin);
+
+/** @overload
+@param m input multi-channel array.
+@param mv output vector of arrays; the arrays themselves are reallocated, if needed.
+*/
+CV_EXPORTS_W void split(InputArray m, OutputArrayOfArrays mv);
+
+/** @brief Copies specified channels from input arrays to the specified channels of
+output arrays.
+
+The function cv::mixChannels provides an advanced mechanism for shuffling image channels.
+
+cv::split and cv::merge and some forms of cv::cvtColor are partial cases of cv::mixChannels .
+
+In the example below, the code splits a 4-channel BGRA image into a 3-channel BGR (with B and R
+channels swapped) and a separate alpha-channel image:
+@code{.cpp}
+ Mat bgra( 100, 100, CV_8UC4, Scalar(255,0,0,255) );
+ Mat bgr( bgra.rows, bgra.cols, CV_8UC3 );
+ Mat alpha( bgra.rows, bgra.cols, CV_8UC1 );
+
+ // forming an array of matrices is a quite efficient operation,
+ // because the matrix data is not copied, only the headers
+ Mat out[] = { bgr, alpha };
+ // bgra[0] -> bgr[2], bgra[1] -> bgr[1],
+ // bgra[2] -> bgr[0], bgra[3] -> alpha[0]
+ int from_to[] = { 0,2, 1,1, 2,0, 3,3 };
+ mixChannels( &bgra, 1, out, 2, from_to, 4 );
+@endcode
+@note Unlike many other new-style C++ functions in OpenCV (see the introduction section and
+Mat::create ), cv::mixChannels requires the output arrays to be pre-allocated before calling the
+function.
+@param src input array or vector of matrices; all of the matrices must have the same size and the
+same depth.
+@param nsrcs number of matrices in `src`.
+@param dst output array or vector of matrices; all the matrices **must be allocated**; their size and
+depth must be the same as in `src[0]`.
+@param ndsts number of matrices in `dst`.
+@param fromTo array of index pairs specifying which channels are copied and where; fromTo[k\*2] is
+a 0-based index of the input channel in src, fromTo[k\*2+1] is an index of the output channel in
+dst; the continuous channel numbering is used: the first input image channels are indexed from 0 to
+src[0].channels()-1, the second input image channels are indexed from src[0].channels() to
+src[0].channels() + src[1].channels()-1, and so on, the same scheme is used for the output image
+channels; as a special case, when fromTo[k\*2] is negative, the corresponding output channel is
+filled with zero .
+@param npairs number of index pairs in `fromTo`.
+@sa cv::split, cv::merge, cv::cvtColor
+*/
+CV_EXPORTS void mixChannels(const Mat* src, size_t nsrcs, Mat* dst, size_t ndsts,
+ const int* fromTo, size_t npairs);
+
+/** @overload
+@param src input array or vector of matrices; all of the matrices must have the same size and the
+same depth.
+@param dst output array or vector of matrices; all the matrices **must be allocated**; their size and
+depth must be the same as in src[0].
+@param fromTo array of index pairs specifying which channels are copied and where; fromTo[k\*2] is
+a 0-based index of the input channel in src, fromTo[k\*2+1] is an index of the output channel in
+dst; the continuous channel numbering is used: the first input image channels are indexed from 0 to
+src[0].channels()-1, the second input image channels are indexed from src[0].channels() to
+src[0].channels() + src[1].channels()-1, and so on, the same scheme is used for the output image
+channels; as a special case, when fromTo[k\*2] is negative, the corresponding output channel is
+filled with zero .
+@param npairs number of index pairs in fromTo.
+*/
+CV_EXPORTS void mixChannels(InputArrayOfArrays src, InputOutputArrayOfArrays dst,
+ const int* fromTo, size_t npairs);
+
+/** @overload
+@param src input array or vector of matrices; all of the matrices must have the same size and the
+same depth.
+@param dst output array or vector of matrices; all the matrices **must be allocated**; their size and
+depth must be the same as in src[0].
+@param fromTo array of index pairs specifying which channels are copied and where; fromTo[k\*2] is
+a 0-based index of the input channel in src, fromTo[k\*2+1] is an index of the output channel in
+dst; the continuous channel numbering is used: the first input image channels are indexed from 0 to
+src[0].channels()-1, the second input image channels are indexed from src[0].channels() to
+src[0].channels() + src[1].channels()-1, and so on, the same scheme is used for the output image
+channels; as a special case, when fromTo[k\*2] is negative, the corresponding output channel is
+filled with zero .
+*/
+CV_EXPORTS_W void mixChannels(InputArrayOfArrays src, InputOutputArrayOfArrays dst,
+ const std::vector& fromTo);
+
+/** @brief extracts a single channel from src (coi is 0-based index)
+@todo document
+*/
+CV_EXPORTS_W void extractChannel(InputArray src, OutputArray dst, int coi);
+
+/** @brief inserts a single channel to dst (coi is 0-based index)
+@todo document
+*/
+CV_EXPORTS_W void insertChannel(InputArray src, InputOutputArray dst, int coi);
+
+/** @brief Flips a 2D array around vertical, horizontal, or both axes.
+
+The function flip flips the array in one of three different ways (row
+and column indices are 0-based):
+\f[\texttt{dst} _{ij} =
+\left\{
+\begin{array}{l l}
+\texttt{src} _{\texttt{src.rows}-i-1,j} & if\; \texttt{flipCode} = 0 \\
+\texttt{src} _{i, \texttt{src.cols} -j-1} & if\; \texttt{flipCode} > 0 \\
+\texttt{src} _{ \texttt{src.rows} -i-1, \texttt{src.cols} -j-1} & if\; \texttt{flipCode} < 0 \\
+\end{array}
+\right.\f]
+The example scenarios of using the function are the following:
+* Vertical flipping of the image (flipCode == 0) to switch between
+ top-left and bottom-left image origin. This is a typical operation
+ in video processing on Microsoft Windows\* OS.
+* Horizontal flipping of the image with the subsequent horizontal
+ shift and absolute difference calculation to check for a
+ vertical-axis symmetry (flipCode \> 0).
+* Simultaneous horizontal and vertical flipping of the image with
+ the subsequent shift and absolute difference calculation to check
+ for a central symmetry (flipCode \< 0).
+* Reversing the order of point arrays (flipCode \> 0 or
+ flipCode == 0).
+@param src input array.
+@param dst output array of the same size and type as src.
+@param flipCode a flag to specify how to flip the array; 0 means
+flipping around the x-axis and positive value (for example, 1) means
+flipping around y-axis. Negative value (for example, -1) means flipping
+around both axes.
+@sa transpose , repeat , completeSymm
+*/
+CV_EXPORTS_W void flip(InputArray src, OutputArray dst, int flipCode);
+
+/** @brief Fills the output array with repeated copies of the input array.
+
+The functions repeat duplicate the input array one or more times along each of the two axes:
+\f[\texttt{dst} _{ij}= \texttt{src} _{i\mod src.rows, \; j\mod src.cols }\f]
+The second variant of the function is more convenient to use with @ref MatrixExpressions.
+@param src input array to replicate.
+@param dst output array of the same type as src.
+@param ny Flag to specify how many times the src is repeated along the
+vertical axis.
+@param nx Flag to specify how many times the src is repeated along the
+horizontal axis.
+@sa reduce
+*/
+CV_EXPORTS_W void repeat(InputArray src, int ny, int nx, OutputArray dst);
+
+/** @overload
+@param src input array to replicate.
+@param ny Flag to specify how many times the src is repeated along the
+vertical axis.
+@param nx Flag to specify how many times the src is repeated along the
+horizontal axis.
+ */
+CV_EXPORTS Mat repeat(const Mat& src, int ny, int nx);
+
+/** @brief Applies horizontal concatenation to given matrices.
+
+The function horizontally concatenates two or more cv::Mat matrices (with the same number of rows).
+@code{.cpp}
+ cv::Mat matArray[] = { cv::Mat(4, 1, CV_8UC1, cv::Scalar(1)),
+ cv::Mat(4, 1, CV_8UC1, cv::Scalar(2)),
+ cv::Mat(4, 1, CV_8UC1, cv::Scalar(3)),};
+
+ cv::Mat out;
+ cv::hconcat( matArray, 3, out );
+ //out:
+ //[1, 2, 3;
+ // 1, 2, 3;
+ // 1, 2, 3;
+ // 1, 2, 3]
+@endcode
+@param src input array or vector of matrices. all of the matrices must have the same number of rows and the same depth.
+@param nsrc number of matrices in src.
+@param dst output array. It has the same number of rows and depth as the src, and the sum of cols of the src.
+@sa cv::vconcat(const Mat*, size_t, OutputArray), @sa cv::vconcat(InputArrayOfArrays, OutputArray) and @sa cv::vconcat(InputArray, InputArray, OutputArray)
+*/
+CV_EXPORTS void hconcat(const Mat* src, size_t nsrc, OutputArray dst);
+/** @overload
+ @code{.cpp}
+ cv::Mat_ A = (cv::Mat_(3, 2) << 1, 4,
+ 2, 5,
+ 3, 6);
+ cv::Mat_ B = (cv::Mat_(3, 2) << 7, 10,
+ 8, 11,
+ 9, 12);
+
+ cv::Mat C;
+ cv::hconcat(A, B, C);
+ //C:
+ //[1, 4, 7, 10;
+ // 2, 5, 8, 11;
+ // 3, 6, 9, 12]
+ @endcode
+ @param src1 first input array to be considered for horizontal concatenation.
+ @param src2 second input array to be considered for horizontal concatenation.
+ @param dst output array. It has the same number of rows and depth as the src1 and src2, and the sum of cols of the src1 and src2.
+ */
+CV_EXPORTS void hconcat(InputArray src1, InputArray src2, OutputArray dst);
+/** @overload
+ @code{.cpp}
+ std::vector matrices = { cv::Mat(4, 1, CV_8UC1, cv::Scalar(1)),
+ cv::Mat(4, 1, CV_8UC1, cv::Scalar(2)),
+ cv::Mat(4, 1, CV_8UC1, cv::Scalar(3)),};
+
+ cv::Mat out;
+ cv::hconcat( matrices, out );
+ //out:
+ //[1, 2, 3;
+ // 1, 2, 3;
+ // 1, 2, 3;
+ // 1, 2, 3]
+ @endcode
+ @param src input array or vector of matrices. all of the matrices must have the same number of rows and the same depth.
+ @param dst output array. It has the same number of rows and depth as the src, and the sum of cols of the src.
+same depth.
+ */
+CV_EXPORTS_W void hconcat(InputArrayOfArrays src, OutputArray dst);
+
+/** @brief Applies vertical concatenation to given matrices.
+
+The function vertically concatenates two or more cv::Mat matrices (with the same number of cols).
+@code{.cpp}
+ cv::Mat matArray[] = { cv::Mat(1, 4, CV_8UC1, cv::Scalar(1)),
+ cv::Mat(1, 4, CV_8UC1, cv::Scalar(2)),
+ cv::Mat(1, 4, CV_8UC1, cv::Scalar(3)),};
+
+ cv::Mat out;
+ cv::vconcat( matArray, 3, out );
+ //out:
+ //[1, 1, 1, 1;
+ // 2, 2, 2, 2;
+ // 3, 3, 3, 3]
+@endcode
+@param src input array or vector of matrices. all of the matrices must have the same number of cols and the same depth.
+@param nsrc number of matrices in src.
+@param dst output array. It has the same number of cols and depth as the src, and the sum of rows of the src.
+@sa cv::hconcat(const Mat*, size_t, OutputArray), @sa cv::hconcat(InputArrayOfArrays, OutputArray) and @sa cv::hconcat(InputArray, InputArray, OutputArray)
+*/
+CV_EXPORTS void vconcat(const Mat* src, size_t nsrc, OutputArray dst);
+/** @overload
+ @code{.cpp}
+ cv::Mat_ A = (cv::Mat_(3, 2) << 1, 7,
+ 2, 8,
+ 3, 9);
+ cv::Mat_ B = (cv::Mat_(3, 2) << 4, 10,
+ 5, 11,
+ 6, 12);
+
+ cv::Mat C;
+ cv::vconcat(A, B, C);
+ //C:
+ //[1, 7;
+ // 2, 8;
+ // 3, 9;
+ // 4, 10;
+ // 5, 11;
+ // 6, 12]
+ @endcode
+ @param src1 first input array to be considered for vertical concatenation.
+ @param src2 second input array to be considered for vertical concatenation.
+ @param dst output array. It has the same number of cols and depth as the src1 and src2, and the sum of rows of the src1 and src2.
+ */
+CV_EXPORTS void vconcat(InputArray src1, InputArray src2, OutputArray dst);
+/** @overload
+ @code{.cpp}
+ std::vector matrices = { cv::Mat(1, 4, CV_8UC1, cv::Scalar(1)),
+ cv::Mat(1, 4, CV_8UC1, cv::Scalar(2)),
+ cv::Mat(1, 4, CV_8UC1, cv::Scalar(3)),};
+
+ cv::Mat out;
+ cv::vconcat( matrices, out );
+ //out:
+ //[1, 1, 1, 1;
+ // 2, 2, 2, 2;
+ // 3, 3, 3, 3]
+ @endcode
+ @param src input array or vector of matrices. all of the matrices must have the same number of cols and the same depth
+ @param dst output array. It has the same number of cols and depth as the src, and the sum of rows of the src.
+same depth.
+ */
+CV_EXPORTS_W void vconcat(InputArrayOfArrays src, OutputArray dst);
+
+/** @brief computes bitwise conjunction of the two arrays (dst = src1 & src2)
+Calculates the per-element bit-wise conjunction of two arrays or an
+array and a scalar.
+
+The function calculates the per-element bit-wise logical conjunction for:
+* Two arrays when src1 and src2 have the same size:
+ \f[\texttt{dst} (I) = \texttt{src1} (I) \wedge \texttt{src2} (I) \quad \texttt{if mask} (I) \ne0\f]
+* An array and a scalar when src2 is constructed from Scalar or has
+ the same number of elements as `src1.channels()`:
+ \f[\texttt{dst} (I) = \texttt{src1} (I) \wedge \texttt{src2} \quad \texttt{if mask} (I) \ne0\f]
+* A scalar and an array when src1 is constructed from Scalar or has
+ the same number of elements as `src2.channels()`:
+ \f[\texttt{dst} (I) = \texttt{src1} \wedge \texttt{src2} (I) \quad \texttt{if mask} (I) \ne0\f]
+In case of floating-point arrays, their machine-specific bit
+representations (usually IEEE754-compliant) are used for the operation.
+In case of multi-channel arrays, each channel is processed
+independently. In the second and third cases above, the scalar is first
+converted to the array type.
+@param src1 first input array or a scalar.
+@param src2 second input array or a scalar.
+@param dst output array that has the same size and type as the input
+arrays.
+@param mask optional operation mask, 8-bit single channel array, that
+specifies elements of the output array to be changed.
+*/
+CV_EXPORTS_W void bitwise_and(InputArray src1, InputArray src2,
+ OutputArray dst, InputArray mask = noArray());
+
+/** @brief Calculates the per-element bit-wise disjunction of two arrays or an
+array and a scalar.
+
+The function calculates the per-element bit-wise logical disjunction for:
+* Two arrays when src1 and src2 have the same size:
+ \f[\texttt{dst} (I) = \texttt{src1} (I) \vee \texttt{src2} (I) \quad \texttt{if mask} (I) \ne0\f]
+* An array and a scalar when src2 is constructed from Scalar or has
+ the same number of elements as `src1.channels()`:
+ \f[\texttt{dst} (I) = \texttt{src1} (I) \vee \texttt{src2} \quad \texttt{if mask} (I) \ne0\f]
+* A scalar and an array when src1 is constructed from Scalar or has
+ the same number of elements as `src2.channels()`:
+ \f[\texttt{dst} (I) = \texttt{src1} \vee \texttt{src2} (I) \quad \texttt{if mask} (I) \ne0\f]
+In case of floating-point arrays, their machine-specific bit
+representations (usually IEEE754-compliant) are used for the operation.
+In case of multi-channel arrays, each channel is processed
+independently. In the second and third cases above, the scalar is first
+converted to the array type.
+@param src1 first input array or a scalar.
+@param src2 second input array or a scalar.
+@param dst output array that has the same size and type as the input
+arrays.
+@param mask optional operation mask, 8-bit single channel array, that
+specifies elements of the output array to be changed.
+*/
+CV_EXPORTS_W void bitwise_or(InputArray src1, InputArray src2,
+ OutputArray dst, InputArray mask = noArray());
+
+/** @brief Calculates the per-element bit-wise "exclusive or" operation on two
+arrays or an array and a scalar.
+
+The function calculates the per-element bit-wise logical "exclusive-or"
+operation for:
+* Two arrays when src1 and src2 have the same size:
+ \f[\texttt{dst} (I) = \texttt{src1} (I) \oplus \texttt{src2} (I) \quad \texttt{if mask} (I) \ne0\f]
+* An array and a scalar when src2 is constructed from Scalar or has
+ the same number of elements as `src1.channels()`:
+ \f[\texttt{dst} (I) = \texttt{src1} (I) \oplus \texttt{src2} \quad \texttt{if mask} (I) \ne0\f]
+* A scalar and an array when src1 is constructed from Scalar or has
+ the same number of elements as `src2.channels()`:
+ \f[\texttt{dst} (I) = \texttt{src1} \oplus \texttt{src2} (I) \quad \texttt{if mask} (I) \ne0\f]
+In case of floating-point arrays, their machine-specific bit
+representations (usually IEEE754-compliant) are used for the operation.
+In case of multi-channel arrays, each channel is processed
+independently. In the 2nd and 3rd cases above, the scalar is first
+converted to the array type.
+@param src1 first input array or a scalar.
+@param src2 second input array or a scalar.
+@param dst output array that has the same size and type as the input
+arrays.
+@param mask optional operation mask, 8-bit single channel array, that
+specifies elements of the output array to be changed.
+*/
+CV_EXPORTS_W void bitwise_xor(InputArray src1, InputArray src2,
+ OutputArray dst, InputArray mask = noArray());
+
+/** @brief Inverts every bit of an array.
+
+The function calculates per-element bit-wise inversion of the input
+array:
+\f[\texttt{dst} (I) = \neg \texttt{src} (I)\f]
+In case of a floating-point input array, its machine-specific bit
+representation (usually IEEE754-compliant) is used for the operation. In
+case of multi-channel arrays, each channel is processed independently.
+@param src input array.
+@param dst output array that has the same size and type as the input
+array.
+@param mask optional operation mask, 8-bit single channel array, that
+specifies elements of the output array to be changed.
+*/
+CV_EXPORTS_W void bitwise_not(InputArray src, OutputArray dst,
+ InputArray mask = noArray());
+
+/** @brief Calculates the per-element absolute difference between two arrays or between an array and a scalar.
+
+The function absdiff calculates:
+* Absolute difference between two arrays when they have the same
+ size and type:
+ \f[\texttt{dst}(I) = \texttt{saturate} (| \texttt{src1}(I) - \texttt{src2}(I)|)\f]
+* Absolute difference between an array and a scalar when the second
+ array is constructed from Scalar or has as many elements as the
+ number of channels in `src1`:
+ \f[\texttt{dst}(I) = \texttt{saturate} (| \texttt{src1}(I) - \texttt{src2} |)\f]
+* Absolute difference between a scalar and an array when the first
+ array is constructed from Scalar or has as many elements as the
+ number of channels in `src2`:
+ \f[\texttt{dst}(I) = \texttt{saturate} (| \texttt{src1} - \texttt{src2}(I) |)\f]
+ where I is a multi-dimensional index of array elements. In case of
+ multi-channel arrays, each channel is processed independently.
+@note Saturation is not applied when the arrays have the depth CV_32S.
+You may even get a negative value in the case of overflow.
+@param src1 first input array or a scalar.
+@param src2 second input array or a scalar.
+@param dst output array that has the same size and type as input arrays.
+@sa cv::abs(const Mat&)
+*/
+CV_EXPORTS_W void absdiff(InputArray src1, InputArray src2, OutputArray dst);
+
+/** @brief Checks if array elements lie between the elements of two other arrays.
+
+The function checks the range as follows:
+- For every element of a single-channel input array:
+ \f[\texttt{dst} (I)= \texttt{lowerb} (I)_0 \leq \texttt{src} (I)_0 \leq \texttt{upperb} (I)_0\f]
+- For two-channel arrays:
+ \f[\texttt{dst} (I)= \texttt{lowerb} (I)_0 \leq \texttt{src} (I)_0 \leq \texttt{upperb} (I)_0 \land \texttt{lowerb} (I)_1 \leq \texttt{src} (I)_1 \leq \texttt{upperb} (I)_1\f]
+- and so forth.
+
+That is, dst (I) is set to 255 (all 1 -bits) if src (I) is within the
+specified 1D, 2D, 3D, ... box and 0 otherwise.
+
+When the lower and/or upper boundary parameters are scalars, the indexes
+(I) at lowerb and upperb in the above formulas should be omitted.
+@param src first input array.
+@param lowerb inclusive lower boundary array or a scalar.
+@param upperb inclusive upper boundary array or a scalar.
+@param dst output array of the same size as src and CV_8U type.
+*/
+CV_EXPORTS_W void inRange(InputArray src, InputArray lowerb,
+ InputArray upperb, OutputArray dst);
+
+/** @brief Performs the per-element comparison of two arrays or an array and scalar value.
+
+The function compares:
+* Elements of two arrays when src1 and src2 have the same size:
+ \f[\texttt{dst} (I) = \texttt{src1} (I) \,\texttt{cmpop}\, \texttt{src2} (I)\f]
+* Elements of src1 with a scalar src2 when src2 is constructed from
+ Scalar or has a single element:
+ \f[\texttt{dst} (I) = \texttt{src1}(I) \,\texttt{cmpop}\, \texttt{src2}\f]
+* src1 with elements of src2 when src1 is constructed from Scalar or
+ has a single element:
+ \f[\texttt{dst} (I) = \texttt{src1} \,\texttt{cmpop}\, \texttt{src2} (I)\f]
+When the comparison result is true, the corresponding element of output
+array is set to 255. The comparison operations can be replaced with the
+equivalent matrix expressions:
+@code{.cpp}
+ Mat dst1 = src1 >= src2;
+ Mat dst2 = src1 < 8;
+ ...
+@endcode
+@param src1 first input array or a scalar; when it is an array, it must have a single channel.
+@param src2 second input array or a scalar; when it is an array, it must have a single channel.
+@param dst output array of type ref CV_8U that has the same size and the same number of channels as
+ the input arrays.
+@param cmpop a flag, that specifies correspondence between the arrays (cv::CmpTypes)
+@sa checkRange, min, max, threshold
+*/
+CV_EXPORTS_W void compare(InputArray src1, InputArray src2, OutputArray dst, int cmpop);
+
+/** @brief Calculates per-element minimum of two arrays or an array and a scalar.
+
+The functions min calculate the per-element minimum of two arrays:
+\f[\texttt{dst} (I)= \min ( \texttt{src1} (I), \texttt{src2} (I))\f]
+or array and a scalar:
+\f[\texttt{dst} (I)= \min ( \texttt{src1} (I), \texttt{value} )\f]
+@param src1 first input array.
+@param src2 second input array of the same size and type as src1.
+@param dst output array of the same size and type as src1.
+@sa max, compare, inRange, minMaxLoc
+*/
+CV_EXPORTS_W void min(InputArray src1, InputArray src2, OutputArray dst);
+/** @overload
+needed to avoid conflicts with const _Tp& std::min(const _Tp&, const _Tp&, _Compare)
+*/
+CV_EXPORTS void min(const Mat& src1, const Mat& src2, Mat& dst);
+/** @overload
+needed to avoid conflicts with const _Tp& std::min(const _Tp&, const _Tp&, _Compare)
+*/
+CV_EXPORTS void min(const UMat& src1, const UMat& src2, UMat& dst);
+
+/** @brief Calculates per-element maximum of two arrays or an array and a scalar.
+
+The functions max calculate the per-element maximum of two arrays:
+\f[\texttt{dst} (I)= \max ( \texttt{src1} (I), \texttt{src2} (I))\f]
+or array and a scalar:
+\f[\texttt{dst} (I)= \max ( \texttt{src1} (I), \texttt{value} )\f]
+@param src1 first input array.
+@param src2 second input array of the same size and type as src1 .
+@param dst output array of the same size and type as src1.
+@sa min, compare, inRange, minMaxLoc, @ref MatrixExpressions
+*/
+CV_EXPORTS_W void max(InputArray src1, InputArray src2, OutputArray dst);
+/** @overload
+needed to avoid conflicts with const _Tp& std::min(const _Tp&, const _Tp&, _Compare)
+*/
+CV_EXPORTS void max(const Mat& src1, const Mat& src2, Mat& dst);
+/** @overload
+needed to avoid conflicts with const _Tp& std::min(const _Tp&, const _Tp&, _Compare)
+*/
+CV_EXPORTS void max(const UMat& src1, const UMat& src2, UMat& dst);
+
+/** @brief Calculates a square root of array elements.
+
+The functions sqrt calculate a square root of each input array element.
+In case of multi-channel arrays, each channel is processed
+independently. The accuracy is approximately the same as of the built-in
+std::sqrt .
+@param src input floating-point array.
+@param dst output array of the same size and type as src.
+*/
+CV_EXPORTS_W void sqrt(InputArray src, OutputArray dst);
+
+/** @brief Raises every array element to a power.
+
+The function pow raises every element of the input array to power :
+\f[\texttt{dst} (I) = \fork{\texttt{src}(I)^{power}}{if \(\texttt{power}\) is integer}{|\texttt{src}(I)|^{power}}{otherwise}\f]
+
+So, for a non-integer power exponent, the absolute values of input array
+elements are used. However, it is possible to get true values for
+negative values using some extra operations. In the example below,
+computing the 5th root of array src shows:
+@code{.cpp}
+ Mat mask = src < 0;
+ pow(src, 1./5, dst);
+ subtract(Scalar::all(0), dst, dst, mask);
+@endcode
+For some values of power, such as integer values, 0.5 and -0.5,
+specialized faster algorithms are used.
+
+Special values (NaN, Inf) are not handled.
+@param src input array.
+@param power exponent of power.
+@param dst output array of the same size and type as src.
+@sa sqrt, exp, log, cartToPolar, polarToCart
+*/
+CV_EXPORTS_W void pow(InputArray src, double power, OutputArray dst);
+
+/** @brief Calculates the exponent of every array element.
+
+The function exp calculates the exponent of every element of the input
+array:
+\f[\texttt{dst} [I] = e^{ src(I) }\f]
+
+The maximum relative error is about 7e-6 for single-precision input and
+less than 1e-10 for double-precision input. Currently, the function
+converts denormalized values to zeros on output. Special values (NaN,
+Inf) are not handled.
+@param src input array.
+@param dst output array of the same size and type as src.
+@sa log , cartToPolar , polarToCart , phase , pow , sqrt , magnitude
+*/
+CV_EXPORTS_W void exp(InputArray src, OutputArray dst);
+
+/** @brief Calculates the natural logarithm of every array element.
+
+The function log calculates the natural logarithm of the absolute value
+of every element of the input array:
+\f[\texttt{dst} (I) = \fork{\log |\texttt{src}(I)|}{if \(\texttt{src}(I) \ne 0\) }{\texttt{C}}{otherwise}\f]
+
+where C is a large negative number (about -700 in the current
+implementation). The maximum relative error is about 7e-6 for
+single-precision input and less than 1e-10 for double-precision input.
+Special values (NaN, Inf) are not handled.
+@param src input array.
+@param dst output array of the same size and type as src .
+@sa exp, cartToPolar, polarToCart, phase, pow, sqrt, magnitude
+*/
+CV_EXPORTS_W void log(InputArray src, OutputArray dst);
+
+/** @brief Calculates x and y coordinates of 2D vectors from their magnitude and angle.
+
+The function polarToCart calculates the Cartesian coordinates of each 2D
+vector represented by the corresponding elements of magnitude and angle:
+\f[\begin{array}{l} \texttt{x} (I) = \texttt{magnitude} (I) \cos ( \texttt{angle} (I)) \\ \texttt{y} (I) = \texttt{magnitude} (I) \sin ( \texttt{angle} (I)) \\ \end{array}\f]
+
+The relative accuracy of the estimated coordinates is about 1e-6.
+@param magnitude input floating-point array of magnitudes of 2D vectors;
+it can be an empty matrix (=Mat()), in this case, the function assumes
+that all the magnitudes are =1; if it is not empty, it must have the
+same size and type as angle.
+@param angle input floating-point array of angles of 2D vectors.
+@param x output array of x-coordinates of 2D vectors; it has the same
+size and type as angle.
+@param y output array of y-coordinates of 2D vectors; it has the same
+size and type as angle.
+@param angleInDegrees when true, the input angles are measured in
+degrees, otherwise, they are measured in radians.
+@sa cartToPolar, magnitude, phase, exp, log, pow, sqrt
+*/
+CV_EXPORTS_W void polarToCart(InputArray magnitude, InputArray angle,
+ OutputArray x, OutputArray y, bool angleInDegrees = false);
+
+/** @brief Calculates the magnitude and angle of 2D vectors.
+
+The function cartToPolar calculates either the magnitude, angle, or both
+for every 2D vector (x(I),y(I)):
+\f[\begin{array}{l} \texttt{magnitude} (I)= \sqrt{\texttt{x}(I)^2+\texttt{y}(I)^2} , \\ \texttt{angle} (I)= \texttt{atan2} ( \texttt{y} (I), \texttt{x} (I))[ \cdot180 / \pi ] \end{array}\f]
+
+The angles are calculated with accuracy about 0.3 degrees. For the point
+(0,0), the angle is set to 0.
+@param x array of x-coordinates; this must be a single-precision or
+double-precision floating-point array.
+@param y array of y-coordinates, that must have the same size and same type as x.
+@param magnitude output array of magnitudes of the same size and type as x.
+@param angle output array of angles that has the same size and type as
+x; the angles are measured in radians (from 0 to 2\*Pi) or in degrees (0 to 360 degrees).
+@param angleInDegrees a flag, indicating whether the angles are measured
+in radians (which is by default), or in degrees.
+@sa Sobel, Scharr
+*/
+CV_EXPORTS_W void cartToPolar(InputArray x, InputArray y,
+ OutputArray magnitude, OutputArray angle,
+ bool angleInDegrees = false);
+
+/** @brief Calculates the rotation angle of 2D vectors.
+
+The function phase calculates the rotation angle of each 2D vector that
+is formed from the corresponding elements of x and y :
+\f[\texttt{angle} (I) = \texttt{atan2} ( \texttt{y} (I), \texttt{x} (I))\f]
+
+The angle estimation accuracy is about 0.3 degrees. When x(I)=y(I)=0 ,
+the corresponding angle(I) is set to 0.
+@param x input floating-point array of x-coordinates of 2D vectors.
+@param y input array of y-coordinates of 2D vectors; it must have the
+same size and the same type as x.
+@param angle output array of vector angles; it has the same size and
+same type as x .
+@param angleInDegrees when true, the function calculates the angle in
+degrees, otherwise, they are measured in radians.
+*/
+CV_EXPORTS_W void phase(InputArray x, InputArray y, OutputArray angle,
+ bool angleInDegrees = false);
+
+/** @brief Calculates the magnitude of 2D vectors.
+
+The function magnitude calculates the magnitude of 2D vectors formed
+from the corresponding elements of x and y arrays:
+\f[\texttt{dst} (I) = \sqrt{\texttt{x}(I)^2 + \texttt{y}(I)^2}\f]
+@param x floating-point array of x-coordinates of the vectors.
+@param y floating-point array of y-coordinates of the vectors; it must
+have the same size as x.
+@param magnitude output array of the same size and type as x.
+@sa cartToPolar, polarToCart, phase, sqrt
+*/
+CV_EXPORTS_W void magnitude(InputArray x, InputArray y, OutputArray magnitude);
+
+/** @brief Checks every element of an input array for invalid values.
+
+The functions checkRange check that every array element is neither NaN nor infinite. When minVal \>
+-DBL_MAX and maxVal \< DBL_MAX, the functions also check that each value is between minVal and
+maxVal. In case of multi-channel arrays, each channel is processed independently. If some values
+are out of range, position of the first outlier is stored in pos (when pos != NULL). Then, the
+functions either return false (when quiet=true) or throw an exception.
+@param a input array.
+@param quiet a flag, indicating whether the functions quietly return false when the array elements
+are out of range or they throw an exception.
+@param pos optional output parameter, when not NULL, must be a pointer to array of src.dims
+elements.
+@param minVal inclusive lower boundary of valid values range.
+@param maxVal exclusive upper boundary of valid values range.
+*/
+CV_EXPORTS_W bool checkRange(InputArray a, bool quiet = true, CV_OUT Point* pos = 0,
+ double minVal = -DBL_MAX, double maxVal = DBL_MAX);
+
+/** @brief converts NaN's to the given number
+*/
+CV_EXPORTS_W void patchNaNs(InputOutputArray a, double val = 0);
+
+/** @brief Performs generalized matrix multiplication.
+
+The function performs generalized matrix multiplication similar to the
+gemm functions in BLAS level 3. For example,
+`gemm(src1, src2, alpha, src3, beta, dst, GEMM_1_T + GEMM_3_T)`
+corresponds to
+\f[\texttt{dst} = \texttt{alpha} \cdot \texttt{src1} ^T \cdot \texttt{src2} + \texttt{beta} \cdot \texttt{src3} ^T\f]
+
+In case of complex (two-channel) data, performed a complex matrix
+multiplication.
+
+The function can be replaced with a matrix expression. For example, the
+above call can be replaced with:
+@code{.cpp}
+ dst = alpha*src1.t()*src2 + beta*src3.t();
+@endcode
+@param src1 first multiplied input matrix that could be real(CV_32FC1,
+CV_64FC1) or complex(CV_32FC2, CV_64FC2).
+@param src2 second multiplied input matrix of the same type as src1.
+@param alpha weight of the matrix product.
+@param src3 third optional delta matrix added to the matrix product; it
+should have the same type as src1 and src2.
+@param beta weight of src3.
+@param dst output matrix; it has the proper size and the same type as
+input matrices.
+@param flags operation flags (cv::GemmFlags)
+@sa mulTransposed , transform
+*/
+CV_EXPORTS_W void gemm(InputArray src1, InputArray src2, double alpha,
+ InputArray src3, double beta, OutputArray dst, int flags = 0);
+
+/** @brief Calculates the product of a matrix and its transposition.
+
+The function mulTransposed calculates the product of src and its
+transposition:
+\f[\texttt{dst} = \texttt{scale} ( \texttt{src} - \texttt{delta} )^T ( \texttt{src} - \texttt{delta} )\f]
+if aTa=true , and
+\f[\texttt{dst} = \texttt{scale} ( \texttt{src} - \texttt{delta} ) ( \texttt{src} - \texttt{delta} )^T\f]
+otherwise. The function is used to calculate the covariance matrix. With
+zero delta, it can be used as a faster substitute for general matrix
+product A\*B when B=A'
+@param src input single-channel matrix. Note that unlike gemm, the
+function can multiply not only floating-point matrices.
+@param dst output square matrix.
+@param aTa Flag specifying the multiplication ordering. See the
+description below.
+@param delta Optional delta matrix subtracted from src before the
+multiplication. When the matrix is empty ( delta=noArray() ), it is
+assumed to be zero, that is, nothing is subtracted. If it has the same
+size as src , it is simply subtracted. Otherwise, it is "repeated" (see
+repeat ) to cover the full src and then subtracted. Type of the delta
+matrix, when it is not empty, must be the same as the type of created
+output matrix. See the dtype parameter description below.
+@param scale Optional scale factor for the matrix product.
+@param dtype Optional type of the output matrix. When it is negative,
+the output matrix will have the same type as src . Otherwise, it will be
+type=CV_MAT_DEPTH(dtype) that should be either CV_32F or CV_64F .
+@sa calcCovarMatrix, gemm, repeat, reduce
+*/
+CV_EXPORTS_W void mulTransposed( InputArray src, OutputArray dst, bool aTa,
+ InputArray delta = noArray(),
+ double scale = 1, int dtype = -1 );
+
+/** @brief Transposes a matrix.
+
+The function transpose transposes the matrix src :
+\f[\texttt{dst} (i,j) = \texttt{src} (j,i)\f]
+@note No complex conjugation is done in case of a complex matrix. It it
+should be done separately if needed.
+@param src input array.
+@param dst output array of the same type as src.
+*/
+CV_EXPORTS_W void transpose(InputArray src, OutputArray dst);
+
+/** @brief Performs the matrix transformation of every array element.
+
+The function transform performs the matrix transformation of every
+element of the array src and stores the results in dst :
+\f[\texttt{dst} (I) = \texttt{m} \cdot \texttt{src} (I)\f]
+(when m.cols=src.channels() ), or
+\f[\texttt{dst} (I) = \texttt{m} \cdot [ \texttt{src} (I); 1]\f]
+(when m.cols=src.channels()+1 )
+
+Every element of the N -channel array src is interpreted as N -element
+vector that is transformed using the M x N or M x (N+1) matrix m to
+M-element vector - the corresponding element of the output array dst .
+
+The function may be used for geometrical transformation of
+N -dimensional points, arbitrary linear color space transformation (such
+as various kinds of RGB to YUV transforms), shuffling the image
+channels, and so forth.
+@param src input array that must have as many channels (1 to 4) as
+m.cols or m.cols-1.
+@param dst output array of the same size and depth as src; it has as
+many channels as m.rows.
+@param m transformation 2x2 or 2x3 floating-point matrix.
+@sa perspectiveTransform, getAffineTransform, estimateRigidTransform, warpAffine, warpPerspective
+*/
+CV_EXPORTS_W void transform(InputArray src, OutputArray dst, InputArray m );
+
+/** @brief Performs the perspective matrix transformation of vectors.
+
+The function perspectiveTransform transforms every element of src by
+treating it as a 2D or 3D vector, in the following way:
+\f[(x, y, z) \rightarrow (x'/w, y'/w, z'/w)\f]
+where
+\f[(x', y', z', w') = \texttt{mat} \cdot \begin{bmatrix} x & y & z & 1 \end{bmatrix}\f]
+and
+\f[w = \fork{w'}{if \(w' \ne 0\)}{\infty}{otherwise}\f]
+
+Here a 3D vector transformation is shown. In case of a 2D vector
+transformation, the z component is omitted.
+
+@note The function transforms a sparse set of 2D or 3D vectors. If you
+want to transform an image using perspective transformation, use
+warpPerspective . If you have an inverse problem, that is, you want to
+compute the most probable perspective transformation out of several
+pairs of corresponding points, you can use getPerspectiveTransform or
+findHomography .
+@param src input two-channel or three-channel floating-point array; each
+element is a 2D/3D vector to be transformed.
+@param dst output array of the same size and type as src.
+@param m 3x3 or 4x4 floating-point transformation matrix.
+@sa transform, warpPerspective, getPerspectiveTransform, findHomography
+*/
+CV_EXPORTS_W void perspectiveTransform(InputArray src, OutputArray dst, InputArray m );
+
+/** @brief Copies the lower or the upper half of a square matrix to another half.
+
+The function completeSymm copies the lower half of a square matrix to
+its another half. The matrix diagonal remains unchanged:
+* \f$\texttt{mtx}_{ij}=\texttt{mtx}_{ji}\f$ for \f$i > j\f$ if
+ lowerToUpper=false
+* \f$\texttt{mtx}_{ij}=\texttt{mtx}_{ji}\f$ for \f$i < j\f$ if
+ lowerToUpper=true
+@param mtx input-output floating-point square matrix.
+@param lowerToUpper operation flag; if true, the lower half is copied to
+the upper half. Otherwise, the upper half is copied to the lower half.
+@sa flip, transpose
+*/
+CV_EXPORTS_W void completeSymm(InputOutputArray mtx, bool lowerToUpper = false);
+
+/** @brief Initializes a scaled identity matrix.
+
+The function setIdentity initializes a scaled identity matrix:
+\f[\texttt{mtx} (i,j)= \fork{\texttt{value}}{ if \(i=j\)}{0}{otherwise}\f]
+
+The function can also be emulated using the matrix initializers and the
+matrix expressions:
+@code
+ Mat A = Mat::eye(4, 3, CV_32F)*5;
+ // A will be set to [[5, 0, 0], [0, 5, 0], [0, 0, 5], [0, 0, 0]]
+@endcode
+@param mtx matrix to initialize (not necessarily square).
+@param s value to assign to diagonal elements.
+@sa Mat::zeros, Mat::ones, Mat::setTo, Mat::operator=
+*/
+CV_EXPORTS_W void setIdentity(InputOutputArray mtx, const Scalar& s = Scalar(1));
+
+/** @brief Returns the determinant of a square floating-point matrix.
+
+The function determinant calculates and returns the determinant of the
+specified matrix. For small matrices ( mtx.cols=mtx.rows\<=3 ), the
+direct method is used. For larger matrices, the function uses LU
+factorization with partial pivoting.
+
+For symmetric positively-determined matrices, it is also possible to use
+eigen decomposition to calculate the determinant.
+@param mtx input matrix that must have CV_32FC1 or CV_64FC1 type and
+square size.
+@sa trace, invert, solve, eigen, @ref MatrixExpressions
+*/
+CV_EXPORTS_W double determinant(InputArray mtx);
+
+/** @brief Returns the trace of a matrix.
+
+The function trace returns the sum of the diagonal elements of the
+matrix mtx .
+\f[\mathrm{tr} ( \texttt{mtx} ) = \sum _i \texttt{mtx} (i,i)\f]
+@param mtx input matrix.
+*/
+CV_EXPORTS_W Scalar trace(InputArray mtx);
+
+/** @brief Finds the inverse or pseudo-inverse of a matrix.
+
+The function invert inverts the matrix src and stores the result in dst
+. When the matrix src is singular or non-square, the function calculates
+the pseudo-inverse matrix (the dst matrix) so that norm(src\*dst - I) is
+minimal, where I is an identity matrix.
+
+In case of the DECOMP_LU method, the function returns non-zero value if
+the inverse has been successfully calculated and 0 if src is singular.
+
+In case of the DECOMP_SVD method, the function returns the inverse
+condition number of src (the ratio of the smallest singular value to the
+largest singular value) and 0 if src is singular. The SVD method
+calculates a pseudo-inverse matrix if src is singular.
+
+Similarly to DECOMP_LU, the method DECOMP_CHOLESKY works only with
+non-singular square matrices that should also be symmetrical and
+positively defined. In this case, the function stores the inverted
+matrix in dst and returns non-zero. Otherwise, it returns 0.
+
+@param src input floating-point M x N matrix.
+@param dst output matrix of N x M size and the same type as src.
+@param flags inversion method (cv::DecompTypes)
+@sa solve, SVD
+*/
+CV_EXPORTS_W double invert(InputArray src, OutputArray dst, int flags = DECOMP_LU);
+
+/** @brief Solves one or more linear systems or least-squares problems.
+
+The function solve solves a linear system or least-squares problem (the
+latter is possible with SVD or QR methods, or by specifying the flag
+DECOMP_NORMAL ):
+\f[\texttt{dst} = \arg \min _X \| \texttt{src1} \cdot \texttt{X} - \texttt{src2} \|\f]
+
+If DECOMP_LU or DECOMP_CHOLESKY method is used, the function returns 1
+if src1 (or \f$\texttt{src1}^T\texttt{src1}\f$ ) is non-singular. Otherwise,
+it returns 0. In the latter case, dst is not valid. Other methods find a
+pseudo-solution in case of a singular left-hand side part.
+
+@note If you want to find a unity-norm solution of an under-defined
+singular system \f$\texttt{src1}\cdot\texttt{dst}=0\f$ , the function solve
+will not do the work. Use SVD::solveZ instead.
+
+@param src1 input matrix on the left-hand side of the system.
+@param src2 input matrix on the right-hand side of the system.
+@param dst output solution.
+@param flags solution (matrix inversion) method (cv::DecompTypes)
+@sa invert, SVD, eigen
+*/
+CV_EXPORTS_W bool solve(InputArray src1, InputArray src2,
+ OutputArray dst, int flags = DECOMP_LU);
+
+/** @brief Sorts each row or each column of a matrix.
+
+The function sort sorts each matrix row or each matrix column in
+ascending or descending order. So you should pass two operation flags to
+get desired behaviour. If you want to sort matrix rows or columns
+lexicographically, you can use STL std::sort generic function with the
+proper comparison predicate.
+
+@param src input single-channel array.
+@param dst output array of the same size and type as src.
+@param flags operation flags, a combination of cv::SortFlags
+@sa sortIdx, randShuffle
+*/
+CV_EXPORTS_W void sort(InputArray src, OutputArray dst, int flags);
+
+/** @brief Sorts each row or each column of a matrix.
+
+The function sortIdx sorts each matrix row or each matrix column in the
+ascending or descending order. So you should pass two operation flags to
+get desired behaviour. Instead of reordering the elements themselves, it
+stores the indices of sorted elements in the output array. For example:
+@code
+ Mat A = Mat::eye(3,3,CV_32F), B;
+ sortIdx(A, B, SORT_EVERY_ROW + SORT_ASCENDING);
+ // B will probably contain
+ // (because of equal elements in A some permutations are possible):
+ // [[1, 2, 0], [0, 2, 1], [0, 1, 2]]
+@endcode
+@param src input single-channel array.
+@param dst output integer array of the same size as src.
+@param flags operation flags that could be a combination of cv::SortFlags
+@sa sort, randShuffle
+*/
+CV_EXPORTS_W void sortIdx(InputArray src, OutputArray dst, int flags);
+
+/** @brief Finds the real roots of a cubic equation.
+
+The function solveCubic finds the real roots of a cubic equation:
+- if coeffs is a 4-element vector:
+\f[\texttt{coeffs} [0] x^3 + \texttt{coeffs} [1] x^2 + \texttt{coeffs} [2] x + \texttt{coeffs} [3] = 0\f]
+- if coeffs is a 3-element vector:
+\f[x^3 + \texttt{coeffs} [0] x^2 + \texttt{coeffs} [1] x + \texttt{coeffs} [2] = 0\f]
+
+The roots are stored in the roots array.
+@param coeffs equation coefficients, an array of 3 or 4 elements.
+@param roots output array of real roots that has 1 or 3 elements.
+*/
+CV_EXPORTS_W int solveCubic(InputArray coeffs, OutputArray roots);
+
+/** @brief Finds the real or complex roots of a polynomial equation.
+
+The function solvePoly finds real and complex roots of a polynomial equation:
+\f[\texttt{coeffs} [n] x^{n} + \texttt{coeffs} [n-1] x^{n-1} + ... + \texttt{coeffs} [1] x + \texttt{coeffs} [0] = 0\f]
+@param coeffs array of polynomial coefficients.
+@param roots output (complex) array of roots.
+@param maxIters maximum number of iterations the algorithm does.
+*/
+CV_EXPORTS_W double solvePoly(InputArray coeffs, OutputArray roots, int maxIters = 300);
+
+/** @brief Calculates eigenvalues and eigenvectors of a symmetric matrix.
+
+The functions eigen calculate just eigenvalues, or eigenvalues and eigenvectors of the symmetric
+matrix src:
+@code
+ src*eigenvectors.row(i).t() = eigenvalues.at(i)*eigenvectors.row(i).t()
+@endcode
+@note in the new and the old interfaces different ordering of eigenvalues and eigenvectors
+parameters is used.
+@param src input matrix that must have CV_32FC1 or CV_64FC1 type, square size and be symmetrical
+(src ^T^ == src).
+@param eigenvalues output vector of eigenvalues of the same type as src; the eigenvalues are stored
+in the descending order.
+@param eigenvectors output matrix of eigenvectors; it has the same size and type as src; the
+eigenvectors are stored as subsequent matrix rows, in the same order as the corresponding
+eigenvalues.
+@sa completeSymm , PCA
+*/
+CV_EXPORTS_W bool eigen(InputArray src, OutputArray eigenvalues,
+ OutputArray eigenvectors = noArray());
+
+/** @brief Calculates the covariance matrix of a set of vectors.
+
+The functions calcCovarMatrix calculate the covariance matrix and, optionally, the mean vector of
+the set of input vectors.
+@param samples samples stored as separate matrices
+@param nsamples number of samples
+@param covar output covariance matrix of the type ctype and square size.
+@param mean input or output (depending on the flags) array as the average value of the input vectors.
+@param flags operation flags as a combination of cv::CovarFlags
+@param ctype type of the matrixl; it equals 'CV_64F' by default.
+@sa PCA, mulTransposed, Mahalanobis
+@todo InputArrayOfArrays
+*/
+CV_EXPORTS void calcCovarMatrix( const Mat* samples, int nsamples, Mat& covar, Mat& mean,
+ int flags, int ctype = CV_64F);
+
+/** @overload
+@note use cv::COVAR_ROWS or cv::COVAR_COLS flag
+@param samples samples stored as rows/columns of a single matrix.
+@param covar output covariance matrix of the type ctype and square size.
+@param mean input or output (depending on the flags) array as the average value of the input vectors.
+@param flags operation flags as a combination of cv::CovarFlags
+@param ctype type of the matrixl; it equals 'CV_64F' by default.
+*/
+CV_EXPORTS_W void calcCovarMatrix( InputArray samples, OutputArray covar,
+ InputOutputArray mean, int flags, int ctype = CV_64F);
+
+/** wrap PCA::operator() */
+CV_EXPORTS_W void PCACompute(InputArray data, InputOutputArray mean,
+ OutputArray eigenvectors, int maxComponents = 0);
+
+/** wrap PCA::operator() */
+CV_EXPORTS_W void PCACompute(InputArray data, InputOutputArray mean,
+ OutputArray eigenvectors, double retainedVariance);
+
+/** wrap PCA::project */
+CV_EXPORTS_W void PCAProject(InputArray data, InputArray mean,
+ InputArray eigenvectors, OutputArray result);
+
+/** wrap PCA::backProject */
+CV_EXPORTS_W void PCABackProject(InputArray data, InputArray mean,
+ InputArray eigenvectors, OutputArray result);
+
+/** wrap SVD::compute */
+CV_EXPORTS_W void SVDecomp( InputArray src, OutputArray w, OutputArray u, OutputArray vt, int flags = 0 );
+
+/** wrap SVD::backSubst */
+CV_EXPORTS_W void SVBackSubst( InputArray w, InputArray u, InputArray vt,
+ InputArray rhs, OutputArray dst );
+
+/** @brief Calculates the Mahalanobis distance between two vectors.
+
+The function Mahalanobis calculates and returns the weighted distance between two vectors:
+\f[d( \texttt{vec1} , \texttt{vec2} )= \sqrt{\sum_{i,j}{\texttt{icovar(i,j)}\cdot(\texttt{vec1}(I)-\texttt{vec2}(I))\cdot(\texttt{vec1(j)}-\texttt{vec2(j)})} }\f]
+The covariance matrix may be calculated using the cv::calcCovarMatrix function and then inverted using
+the invert function (preferably using the cv::DECOMP_SVD method, as the most accurate).
+@param v1 first 1D input vector.
+@param v2 second 1D input vector.
+@param icovar inverse covariance matrix.
+*/
+CV_EXPORTS_W double Mahalanobis(InputArray v1, InputArray v2, InputArray icovar);
+
+/** @brief Performs a forward or inverse Discrete Fourier transform of a 1D or 2D floating-point array.
+
+The function performs one of the following:
+- Forward the Fourier transform of a 1D vector of N elements:
+ \f[Y = F^{(N)} \cdot X,\f]
+ where \f$F^{(N)}_{jk}=\exp(-2\pi i j k/N)\f$ and \f$i=\sqrt{-1}\f$
+- Inverse the Fourier transform of a 1D vector of N elements:
+ \f[\begin{array}{l} X'= \left (F^{(N)} \right )^{-1} \cdot Y = \left (F^{(N)} \right )^* \cdot y \\ X = (1/N) \cdot X, \end{array}\f]
+ where \f$F^*=\left(\textrm{Re}(F^{(N)})-\textrm{Im}(F^{(N)})\right)^T\f$
+- Forward the 2D Fourier transform of a M x N matrix:
+ \f[Y = F^{(M)} \cdot X \cdot F^{(N)}\f]
+- Inverse the 2D Fourier transform of a M x N matrix:
+ \f[\begin{array}{l} X'= \left (F^{(M)} \right )^* \cdot Y \cdot \left (F^{(N)} \right )^* \\ X = \frac{1}{M \cdot N} \cdot X' \end{array}\f]
+
+In case of real (single-channel) data, the output spectrum of the forward Fourier transform or input
+spectrum of the inverse Fourier transform can be represented in a packed format called *CCS*
+(complex-conjugate-symmetrical). It was borrowed from IPL (Intel\* Image Processing Library). Here
+is how 2D *CCS* spectrum looks:
+\f[\begin{bmatrix} Re Y_{0,0} & Re Y_{0,1} & Im Y_{0,1} & Re Y_{0,2} & Im Y_{0,2} & \cdots & Re Y_{0,N/2-1} & Im Y_{0,N/2-1} & Re Y_{0,N/2} \\ Re Y_{1,0} & Re Y_{1,1} & Im Y_{1,1} & Re Y_{1,2} & Im Y_{1,2} & \cdots & Re Y_{1,N/2-1} & Im Y_{1,N/2-1} & Re Y_{1,N/2} \\ Im Y_{1,0} & Re Y_{2,1} & Im Y_{2,1} & Re Y_{2,2} & Im Y_{2,2} & \cdots & Re Y_{2,N/2-1} & Im Y_{2,N/2-1} & Im Y_{1,N/2} \\ \hdotsfor{9} \\ Re Y_{M/2-1,0} & Re Y_{M-3,1} & Im Y_{M-3,1} & \hdotsfor{3} & Re Y_{M-3,N/2-1} & Im Y_{M-3,N/2-1}& Re Y_{M/2-1,N/2} \\ Im Y_{M/2-1,0} & Re Y_{M-2,1} & Im Y_{M-2,1} & \hdotsfor{3} & Re Y_{M-2,N/2-1} & Im Y_{M-2,N/2-1}& Im Y_{M/2-1,N/2} \\ Re Y_{M/2,0} & Re Y_{M-1,1} & Im Y_{M-1,1} & \hdotsfor{3} & Re Y_{M-1,N/2-1} & Im Y_{M-1,N/2-1}& Re Y_{M/2,N/2} \end{bmatrix}\f]
+
+In case of 1D transform of a real vector, the output looks like the first row of the matrix above.
+
+So, the function chooses an operation mode depending on the flags and size of the input array:
+- If DFT_ROWS is set or the input array has a single row or single column, the function
+ performs a 1D forward or inverse transform of each row of a matrix when DFT_ROWS is set.
+ Otherwise, it performs a 2D transform.
+- If the input array is real and DFT_INVERSE is not set, the function performs a forward 1D or
+ 2D transform:
+ - When DFT_COMPLEX_OUTPUT is set, the output is a complex matrix of the same size as
+ input.
+ - When DFT_COMPLEX_OUTPUT is not set, the output is a real matrix of the same size as
+ input. In case of 2D transform, it uses the packed format as shown above. In case of a
+ single 1D transform, it looks like the first row of the matrix above. In case of
+ multiple 1D transforms (when using the DFT_ROWS flag), each row of the output matrix
+ looks like the first row of the matrix above.
+- If the input array is complex and either DFT_INVERSE or DFT_REAL_OUTPUT are not set, the
+ output is a complex array of the same size as input. The function performs a forward or
+ inverse 1D or 2D transform of the whole input array or each row of the input array
+ independently, depending on the flags DFT_INVERSE and DFT_ROWS.
+- When DFT_INVERSE is set and the input array is real, or it is complex but DFT_REAL_OUTPUT
+ is set, the output is a real array of the same size as input. The function performs a 1D or 2D
+ inverse transformation of the whole input array or each individual row, depending on the flags
+ DFT_INVERSE and DFT_ROWS.
+
+If DFT_SCALE is set, the scaling is done after the transformation.
+
+Unlike dct , the function supports arrays of arbitrary size. But only those arrays are processed
+efficiently, whose sizes can be factorized in a product of small prime numbers (2, 3, and 5 in the
+current implementation). Such an efficient DFT size can be calculated using the getOptimalDFTSize
+method.
+
+The sample below illustrates how to calculate a DFT-based convolution of two 2D real arrays:
+@code
+ void convolveDFT(InputArray A, InputArray B, OutputArray C)
+ {
+ // reallocate the output array if needed
+ C.create(abs(A.rows - B.rows)+1, abs(A.cols - B.cols)+1, A.type());
+ Size dftSize;
+ // calculate the size of DFT transform
+ dftSize.width = getOptimalDFTSize(A.cols + B.cols - 1);
+ dftSize.height = getOptimalDFTSize(A.rows + B.rows - 1);
+
+ // allocate temporary buffers and initialize them with 0's
+ Mat tempA(dftSize, A.type(), Scalar::all(0));
+ Mat tempB(dftSize, B.type(), Scalar::all(0));
+
+ // copy A and B to the top-left corners of tempA and tempB, respectively
+ Mat roiA(tempA, Rect(0,0,A.cols,A.rows));
+ A.copyTo(roiA);
+ Mat roiB(tempB, Rect(0,0,B.cols,B.rows));
+ B.copyTo(roiB);
+
+ // now transform the padded A & B in-place;
+ // use "nonzeroRows" hint for faster processing
+ dft(tempA, tempA, 0, A.rows);
+ dft(tempB, tempB, 0, B.rows);
+
+ // multiply the spectrums;
+ // the function handles packed spectrum representations well
+ mulSpectrums(tempA, tempB, tempA);
+
+ // transform the product back from the frequency domain.
+ // Even though all the result rows will be non-zero,
+ // you need only the first C.rows of them, and thus you
+ // pass nonzeroRows == C.rows
+ dft(tempA, tempA, DFT_INVERSE + DFT_SCALE, C.rows);
+
+ // now copy the result back to C.
+ tempA(Rect(0, 0, C.cols, C.rows)).copyTo(C);
+
+ // all the temporary buffers will be deallocated automatically
+ }
+@endcode
+To optimize this sample, consider the following approaches:
+- Since nonzeroRows != 0 is passed to the forward transform calls and since A and B are copied to
+ the top-left corners of tempA and tempB, respectively, it is not necessary to clear the whole
+ tempA and tempB. It is only necessary to clear the tempA.cols - A.cols ( tempB.cols - B.cols)
+ rightmost columns of the matrices.
+- This DFT-based convolution does not have to be applied to the whole big arrays, especially if B
+ is significantly smaller than A or vice versa. Instead, you can calculate convolution by parts.
+ To do this, you need to split the output array C into multiple tiles. For each tile, estimate
+ which parts of A and B are required to calculate convolution in this tile. If the tiles in C are
+ too small, the speed will decrease a lot because of repeated work. In the ultimate case, when
+ each tile in C is a single pixel, the algorithm becomes equivalent to the naive convolution
+ algorithm. If the tiles are too big, the temporary arrays tempA and tempB become too big and
+ there is also a slowdown because of bad cache locality. So, there is an optimal tile size
+ somewhere in the middle.
+- If different tiles in C can be calculated in parallel and, thus, the convolution is done by
+ parts, the loop can be threaded.
+
+All of the above improvements have been implemented in matchTemplate and filter2D . Therefore, by
+using them, you can get the performance even better than with the above theoretically optimal
+implementation. Though, those two functions actually calculate cross-correlation, not convolution,
+so you need to "flip" the second convolution operand B vertically and horizontally using flip .
+@note
+- An example using the discrete fourier transform can be found at
+ opencv_source_code/samples/cpp/dft.cpp
+- (Python) An example using the dft functionality to perform Wiener deconvolution can be found
+ at opencv_source/samples/python/deconvolution.py
+- (Python) An example rearranging the quadrants of a Fourier image can be found at
+ opencv_source/samples/python/dft.py
+@param src input array that could be real or complex.
+@param dst output array whose size and type depends on the flags .
+@param flags transformation flags, representing a combination of the cv::DftFlags
+@param nonzeroRows when the parameter is not zero, the function assumes that only the first
+nonzeroRows rows of the input array (DFT_INVERSE is not set) or only the first nonzeroRows of the
+output array (DFT_INVERSE is set) contain non-zeros, thus, the function can handle the rest of the
+rows more efficiently and save some time; this technique is very useful for calculating array
+cross-correlation or convolution using DFT.
+@sa dct , getOptimalDFTSize , mulSpectrums, filter2D , matchTemplate , flip , cartToPolar ,
+magnitude , phase
+*/
+CV_EXPORTS_W void dft(InputArray src, OutputArray dst, int flags = 0, int nonzeroRows = 0);
+
+/** @brief Calculates the inverse Discrete Fourier Transform of a 1D or 2D array.
+
+idft(src, dst, flags) is equivalent to dft(src, dst, flags | DFT_INVERSE) .
+@note None of dft and idft scales the result by default. So, you should pass DFT_SCALE to one of
+dft or idft explicitly to make these transforms mutually inverse.
+@sa dft, dct, idct, mulSpectrums, getOptimalDFTSize
+@param src input floating-point real or complex array.
+@param dst output array whose size and type depend on the flags.
+@param flags operation flags (see dft and cv::DftFlags).
+@param nonzeroRows number of dst rows to process; the rest of the rows have undefined content (see
+the convolution sample in dft description.
+*/
+CV_EXPORTS_W void idft(InputArray src, OutputArray dst, int flags = 0, int nonzeroRows = 0);
+
+/** @brief Performs a forward or inverse discrete Cosine transform of 1D or 2D array.
+
+The function dct performs a forward or inverse discrete Cosine transform (DCT) of a 1D or 2D
+floating-point array:
+- Forward Cosine transform of a 1D vector of N elements:
+ \f[Y = C^{(N)} \cdot X\f]
+ where
+ \f[C^{(N)}_{jk}= \sqrt{\alpha_j/N} \cos \left ( \frac{\pi(2k+1)j}{2N} \right )\f]
+ and
+ \f$\alpha_0=1\f$, \f$\alpha_j=2\f$ for *j \> 0*.
+- Inverse Cosine transform of a 1D vector of N elements:
+ \f[X = \left (C^{(N)} \right )^{-1} \cdot Y = \left (C^{(N)} \right )^T \cdot Y\f]
+ (since \f$C^{(N)}\f$ is an orthogonal matrix, \f$C^{(N)} \cdot \left(C^{(N)}\right)^T = I\f$ )
+- Forward 2D Cosine transform of M x N matrix:
+ \f[Y = C^{(N)} \cdot X \cdot \left (C^{(N)} \right )^T\f]
+- Inverse 2D Cosine transform of M x N matrix:
+ \f[X = \left (C^{(N)} \right )^T \cdot X \cdot C^{(N)}\f]
+
+The function chooses the mode of operation by looking at the flags and size of the input array:
+- If (flags & DCT_INVERSE) == 0 , the function does a forward 1D or 2D transform. Otherwise, it
+ is an inverse 1D or 2D transform.
+- If (flags & DCT_ROWS) != 0 , the function performs a 1D transform of each row.
+- If the array is a single column or a single row, the function performs a 1D transform.
+- If none of the above is true, the function performs a 2D transform.
+
+@note Currently dct supports even-size arrays (2, 4, 6 ...). For data analysis and approximation, you
+can pad the array when necessary.
+Also, the function performance depends very much, and not monotonically, on the array size (see
+getOptimalDFTSize ). In the current implementation DCT of a vector of size N is calculated via DFT
+of a vector of size N/2 . Thus, the optimal DCT size N1 \>= N can be calculated as:
+@code
+ size_t getOptimalDCTSize(size_t N) { return 2*getOptimalDFTSize((N+1)/2); }
+ N1 = getOptimalDCTSize(N);
+@endcode
+@param src input floating-point array.
+@param dst output array of the same size and type as src .
+@param flags transformation flags as a combination of cv::DftFlags (DCT_*)
+@sa dft , getOptimalDFTSize , idct
+*/
+CV_EXPORTS_W void dct(InputArray src, OutputArray dst, int flags = 0);
+
+/** @brief Calculates the inverse Discrete Cosine Transform of a 1D or 2D array.
+
+idct(src, dst, flags) is equivalent to dct(src, dst, flags | DCT_INVERSE).
+@param src input floating-point single-channel array.
+@param dst output array of the same size and type as src.
+@param flags operation flags.
+@sa dct, dft, idft, getOptimalDFTSize
+*/
+CV_EXPORTS_W void idct(InputArray src, OutputArray dst, int flags = 0);
+
+/** @brief Performs the per-element multiplication of two Fourier spectrums.
+
+The function mulSpectrums performs the per-element multiplication of the two CCS-packed or complex
+matrices that are results of a real or complex Fourier transform.
+
+The function, together with dft and idft , may be used to calculate convolution (pass conjB=false )
+or correlation (pass conjB=true ) of two arrays rapidly. When the arrays are complex, they are
+simply multiplied (per element) with an optional conjugation of the second-array elements. When the
+arrays are real, they are assumed to be CCS-packed (see dft for details).
+@param a first input array.
+@param b second input array of the same size and type as src1 .
+@param c output array of the same size and type as src1 .
+@param flags operation flags; currently, the only supported flag is cv::DFT_ROWS, which indicates that
+each row of src1 and src2 is an independent 1D Fourier spectrum. If you do not want to use this flag, then simply add a `0` as value.
+@param conjB optional flag that conjugates the second input array before the multiplication (true)
+or not (false).
+*/
+CV_EXPORTS_W void mulSpectrums(InputArray a, InputArray b, OutputArray c,
+ int flags, bool conjB = false);
+
+/** @brief Returns the optimal DFT size for a given vector size.
+
+DFT performance is not a monotonic function of a vector size. Therefore, when you calculate
+convolution of two arrays or perform the spectral analysis of an array, it usually makes sense to
+pad the input data with zeros to get a bit larger array that can be transformed much faster than the
+original one. Arrays whose size is a power-of-two (2, 4, 8, 16, 32, ...) are the fastest to process.
+Though, the arrays whose size is a product of 2's, 3's, and 5's (for example, 300 = 5\*5\*3\*2\*2)
+are also processed quite efficiently.
+
+The function getOptimalDFTSize returns the minimum number N that is greater than or equal to vecsize
+so that the DFT of a vector of size N can be processed efficiently. In the current implementation N
+= 2 ^p^ \* 3 ^q^ \* 5 ^r^ for some integer p, q, r.
+
+The function returns a negative number if vecsize is too large (very close to INT_MAX ).
+
+While the function cannot be used directly to estimate the optimal vector size for DCT transform
+(since the current DCT implementation supports only even-size vectors), it can be easily processed
+as getOptimalDFTSize((vecsize+1)/2)\*2.
+@param vecsize vector size.
+@sa dft , dct , idft , idct , mulSpectrums
+*/
+CV_EXPORTS_W int getOptimalDFTSize(int vecsize);
+
+/** @brief Returns the default random number generator.
+
+The function theRNG returns the default random number generator. For each thread, there is a
+separate random number generator, so you can use the function safely in multi-thread environments.
+If you just need to get a single random number using this generator or initialize an array, you can
+use randu or randn instead. But if you are going to generate many random numbers inside a loop, it
+is much faster to use this function to retrieve the generator and then use RNG::operator _Tp() .
+@sa RNG, randu, randn
+*/
+CV_EXPORTS RNG& theRNG();
+
+/** @brief Generates a single uniformly-distributed random number or an array of random numbers.
+
+Non-template variant of the function fills the matrix dst with uniformly-distributed
+random numbers from the specified range:
+\f[\texttt{low} _c \leq \texttt{dst} (I)_c < \texttt{high} _c\f]
+@param dst output array of random numbers; the array must be pre-allocated.
+@param low inclusive lower boundary of the generated random numbers.
+@param high exclusive upper boundary of the generated random numbers.
+@sa RNG, randn, theRNG
+*/
+CV_EXPORTS_W void randu(InputOutputArray dst, InputArray low, InputArray high);
+
+/** @brief Fills the array with normally distributed random numbers.
+
+The function randn fills the matrix dst with normally distributed random numbers with the specified
+mean vector and the standard deviation matrix. The generated random numbers are clipped to fit the
+value range of the output array data type.
+@param dst output array of random numbers; the array must be pre-allocated and have 1 to 4 channels.
+@param mean mean value (expectation) of the generated random numbers.
+@param stddev standard deviation of the generated random numbers; it can be either a vector (in
+which case a diagonal standard deviation matrix is assumed) or a square matrix.
+@sa RNG, randu
+*/
+CV_EXPORTS_W void randn(InputOutputArray dst, InputArray mean, InputArray stddev);
+
+/** @brief Shuffles the array elements randomly.
+
+The function randShuffle shuffles the specified 1D array by randomly choosing pairs of elements and
+swapping them. The number of such swap operations will be dst.rows\*dst.cols\*iterFactor .
+@param dst input/output numerical 1D array.
+@param iterFactor scale factor that determines the number of random swap operations (see the details
+below).
+@param rng optional random number generator used for shuffling; if it is zero, theRNG () is used
+instead.
+@sa RNG, sort
+*/
+CV_EXPORTS_W void randShuffle(InputOutputArray dst, double iterFactor = 1., RNG* rng = 0);
+
+/** @brief Principal Component Analysis
+
+The class is used to calculate a special basis for a set of vectors. The
+basis will consist of eigenvectors of the covariance matrix calculated
+from the input set of vectors. The class %PCA can also transform
+vectors to/from the new coordinate space defined by the basis. Usually,
+in this new coordinate system, each vector from the original set (and
+any linear combination of such vectors) can be quite accurately
+approximated by taking its first few components, corresponding to the
+eigenvectors of the largest eigenvalues of the covariance matrix.
+Geometrically it means that you calculate a projection of the vector to
+a subspace formed by a few eigenvectors corresponding to the dominant
+eigenvalues of the covariance matrix. And usually such a projection is
+very close to the original vector. So, you can represent the original
+vector from a high-dimensional space with a much shorter vector
+consisting of the projected vector's coordinates in the subspace. Such a
+transformation is also known as Karhunen-Loeve Transform, or KLT.
+See http://en.wikipedia.org/wiki/Principal_component_analysis
+
+The sample below is the function that takes two matrices. The first
+function stores a set of vectors (a row per vector) that is used to
+calculate PCA. The second function stores another "test" set of vectors
+(a row per vector). First, these vectors are compressed with PCA, then
+reconstructed back, and then the reconstruction error norm is computed
+and printed for each vector. :
+
+@code{.cpp}
+using namespace cv;
+
+PCA compressPCA(const Mat& pcaset, int maxComponents,
+ const Mat& testset, Mat& compressed)
+{
+ PCA pca(pcaset, // pass the data
+ Mat(), // we do not have a pre-computed mean vector,
+ // so let the PCA engine to compute it
+ PCA::DATA_AS_ROW, // indicate that the vectors
+ // are stored as matrix rows
+ // (use PCA::DATA_AS_COL if the vectors are
+ // the matrix columns)
+ maxComponents // specify, how many principal components to retain
+ );
+ // if there is no test data, just return the computed basis, ready-to-use
+ if( !testset.data )
+ return pca;
+ CV_Assert( testset.cols == pcaset.cols );
+
+ compressed.create(testset.rows, maxComponents, testset.type());
+
+ Mat reconstructed;
+ for( int i = 0; i < testset.rows; i++ )
+ {
+ Mat vec = testset.row(i), coeffs = compressed.row(i), reconstructed;
+ // compress the vector, the result will be stored
+ // in the i-th row of the output matrix
+ pca.project(vec, coeffs);
+ // and then reconstruct it
+ pca.backProject(coeffs, reconstructed);
+ // and measure the error
+ printf("%d. diff = %g\n", i, norm(vec, reconstructed, NORM_L2));
+ }
+ return pca;
+}
+@endcode
+@sa calcCovarMatrix, mulTransposed, SVD, dft, dct
+*/
+class CV_EXPORTS PCA
+{
+public:
+ enum Flags { DATA_AS_ROW = 0, //!< indicates that the input samples are stored as matrix rows
+ DATA_AS_COL = 1, //!< indicates that the input samples are stored as matrix columns
+ USE_AVG = 2 //!
+ };
+
+ /** @brief default constructor
+
+ The default constructor initializes an empty %PCA structure. The other
+ constructors initialize the structure and call PCA::operator()().
+ */
+ PCA();
+
+ /** @overload
+ @param data input samples stored as matrix rows or matrix columns.
+ @param mean optional mean value; if the matrix is empty (@c noArray()),
+ the mean is computed from the data.
+ @param flags operation flags; currently the parameter is only used to
+ specify the data layout (PCA::Flags)
+ @param maxComponents maximum number of components that %PCA should
+ retain; by default, all the components are retained.
+ */
+ PCA(InputArray data, InputArray mean, int flags, int maxComponents = 0);
+
+ /** @overload
+ @param data input samples stored as matrix rows or matrix columns.
+ @param mean optional mean value; if the matrix is empty (noArray()),
+ the mean is computed from the data.
+ @param flags operation flags; currently the parameter is only used to
+ specify the data layout (PCA::Flags)
+ @param retainedVariance Percentage of variance that PCA should retain.
+ Using this parameter will let the PCA decided how many components to
+ retain but it will always keep at least 2.
+ */
+ PCA(InputArray data, InputArray mean, int flags, double retainedVariance);
+
+ /** @brief performs %PCA
+
+ The operator performs %PCA of the supplied dataset. It is safe to reuse
+ the same PCA structure for multiple datasets. That is, if the structure
+ has been previously used with another dataset, the existing internal
+ data is reclaimed and the new eigenvalues, @ref eigenvectors , and @ref
+ mean are allocated and computed.
+
+ The computed eigenvalues are sorted from the largest to the smallest and
+ the corresponding eigenvectors are stored as eigenvectors rows.
+
+ @param data input samples stored as the matrix rows or as the matrix
+ columns.
+ @param mean optional mean value; if the matrix is empty (noArray()),
+ the mean is computed from the data.
+ @param flags operation flags; currently the parameter is only used to
+ specify the data layout. (Flags)
+ @param maxComponents maximum number of components that PCA should
+ retain; by default, all the components are retained.
+ */
+ PCA& operator()(InputArray data, InputArray mean, int flags, int maxComponents = 0);
+
+ /** @overload
+ @param data input samples stored as the matrix rows or as the matrix
+ columns.
+ @param mean optional mean value; if the matrix is empty (noArray()),
+ the mean is computed from the data.
+ @param flags operation flags; currently the parameter is only used to
+ specify the data layout. (PCA::Flags)
+ @param retainedVariance Percentage of variance that %PCA should retain.
+ Using this parameter will let the %PCA decided how many components to
+ retain but it will always keep at least 2.
+ */
+ PCA& operator()(InputArray data, InputArray mean, int flags, double retainedVariance);
+
+ /** @brief Projects vector(s) to the principal component subspace.
+
+ The methods project one or more vectors to the principal component
+ subspace, where each vector projection is represented by coefficients in
+ the principal component basis. The first form of the method returns the
+ matrix that the second form writes to the result. So the first form can
+ be used as a part of expression while the second form can be more
+ efficient in a processing loop.
+ @param vec input vector(s); must have the same dimensionality and the
+ same layout as the input data used at %PCA phase, that is, if
+ DATA_AS_ROW are specified, then `vec.cols==data.cols`
+ (vector dimensionality) and `vec.rows` is the number of vectors to
+ project, and the same is true for the PCA::DATA_AS_COL case.
+ */
+ Mat project(InputArray vec) const;
+
+ /** @overload
+ @param vec input vector(s); must have the same dimensionality and the
+ same layout as the input data used at PCA phase, that is, if
+ DATA_AS_ROW are specified, then `vec.cols==data.cols`
+ (vector dimensionality) and `vec.rows` is the number of vectors to
+ project, and the same is true for the PCA::DATA_AS_COL case.
+ @param result output vectors; in case of PCA::DATA_AS_COL, the
+ output matrix has as many columns as the number of input vectors, this
+ means that `result.cols==vec.cols` and the number of rows match the
+ number of principal components (for example, `maxComponents` parameter
+ passed to the constructor).
+ */
+ void project(InputArray vec, OutputArray result) const;
+
+ /** @brief Reconstructs vectors from their PC projections.
+
+ The methods are inverse operations to PCA::project. They take PC
+ coordinates of projected vectors and reconstruct the original vectors.
+ Unless all the principal components have been retained, the
+ reconstructed vectors are different from the originals. But typically,
+ the difference is small if the number of components is large enough (but
+ still much smaller than the original vector dimensionality). As a
+ result, PCA is used.
+ @param vec coordinates of the vectors in the principal component
+ subspace, the layout and size are the same as of PCA::project output
+ vectors.
+ */
+ Mat backProject(InputArray vec) const;
+
+ /** @overload
+ @param vec coordinates of the vectors in the principal component
+ subspace, the layout and size are the same as of PCA::project output
+ vectors.
+ @param result reconstructed vectors; the layout and size are the same as
+ of PCA::project input vectors.
+ */
+ void backProject(InputArray vec, OutputArray result) const;
+
+ /** @brief write and load PCA matrix
+
+*/
+ void write(FileStorage& fs ) const;
+ void read(const FileNode& fs);
+
+ Mat eigenvectors; //!< eigenvectors of the covariation matrix
+ Mat eigenvalues; //!< eigenvalues of the covariation matrix
+ Mat mean; //!< mean value subtracted before the projection and added after the back projection
+};
+
+/** @example pca.cpp
+ An example using %PCA for dimensionality reduction while maintaining an amount of variance
+ */
+
+/**
+ @brief Linear Discriminant Analysis
+ @todo document this class
+ */
+class CV_EXPORTS LDA
+{
+public:
+ /** @brief constructor
+ Initializes a LDA with num_components (default 0).
+ */
+ explicit LDA(int num_components = 0);
+
+ /** Initializes and performs a Discriminant Analysis with Fisher's
+ Optimization Criterion on given data in src and corresponding labels
+ in labels. If 0 (or less) number of components are given, they are
+ automatically determined for given data in computation.
+ */
+ LDA(InputArrayOfArrays src, InputArray labels, int num_components = 0);
+
+ /** Serializes this object to a given filename.
+ */
+ void save(const String& filename) const;
+
+ /** Deserializes this object from a given filename.
+ */
+ void load(const String& filename);
+
+ /** Serializes this object to a given cv::FileStorage.
+ */
+ void save(FileStorage& fs) const;
+
+ /** Deserializes this object from a given cv::FileStorage.
+ */
+ void load(const FileStorage& node);
+
+ /** destructor
+ */
+ ~LDA();
+
+ /** Compute the discriminants for data in src (row aligned) and labels.
+ */
+ void compute(InputArrayOfArrays src, InputArray labels);
+
+ /** Projects samples into the LDA subspace.
+ src may be one or more row aligned samples.
+ */
+ Mat project(InputArray src);
+
+ /** Reconstructs projections from the LDA subspace.
+ src may be one or more row aligned projections.
+ */
+ Mat reconstruct(InputArray src);
+
+ /** Returns the eigenvectors of this LDA.
+ */
+ Mat eigenvectors() const { return _eigenvectors; }
+
+ /** Returns the eigenvalues of this LDA.
+ */
+ Mat eigenvalues() const { return _eigenvalues; }
+
+ static Mat subspaceProject(InputArray W, InputArray mean, InputArray src);
+ static Mat subspaceReconstruct(InputArray W, InputArray mean, InputArray src);
+
+protected:
+ bool _dataAsRow; // unused, but needed for 3.0 ABI compatibility.
+ int _num_components;
+ Mat _eigenvectors;
+ Mat _eigenvalues;
+ void lda(InputArrayOfArrays src, InputArray labels);
+};
+
+/** @brief Singular Value Decomposition
+
+Class for computing Singular Value Decomposition of a floating-point
+matrix. The Singular Value Decomposition is used to solve least-square
+problems, under-determined linear systems, invert matrices, compute
+condition numbers, and so on.
+
+If you want to compute a condition number of a matrix or an absolute value of
+its determinant, you do not need `u` and `vt`. You can pass
+flags=SVD::NO_UV|... . Another flag SVD::FULL_UV indicates that full-size u
+and vt must be computed, which is not necessary most of the time.
+
+@sa invert, solve, eigen, determinant
+*/
+class CV_EXPORTS SVD
+{
+public:
+ enum Flags {
+ /** allow the algorithm to modify the decomposed matrix; it can save space and speed up
+ processing. currently ignored. */
+ MODIFY_A = 1,
+ /** indicates that only a vector of singular values `w` is to be processed, while u and vt
+ will be set to empty matrices */
+ NO_UV = 2,
+ /** when the matrix is not square, by default the algorithm produces u and vt matrices of
+ sufficiently large size for the further A reconstruction; if, however, FULL_UV flag is
+ specified, u and vt will be full-size square orthogonal matrices.*/
+ FULL_UV = 4
+ };
+
+ /** @brief the default constructor
+
+ initializes an empty SVD structure
+ */
+ SVD();
+
+ /** @overload
+ initializes an empty SVD structure and then calls SVD::operator()
+ @param src decomposed matrix.
+ @param flags operation flags (SVD::Flags)
+ */
+ SVD( InputArray src, int flags = 0 );
+
+ /** @brief the operator that performs SVD. The previously allocated u, w and vt are released.
+
+ The operator performs the singular value decomposition of the supplied
+ matrix. The u,`vt` , and the vector of singular values w are stored in
+ the structure. The same SVD structure can be reused many times with
+ different matrices. Each time, if needed, the previous u,`vt` , and w
+ are reclaimed and the new matrices are created, which is all handled by
+ Mat::create.
+ @param src decomposed matrix.
+ @param flags operation flags (SVD::Flags)
+ */
+ SVD& operator ()( InputArray src, int flags = 0 );
+
+ /** @brief decomposes matrix and stores the results to user-provided matrices
+
+ The methods/functions perform SVD of matrix. Unlike SVD::SVD constructor
+ and SVD::operator(), they store the results to the user-provided
+ matrices:
+
+ @code{.cpp}
+ Mat A, w, u, vt;
+ SVD::compute(A, w, u, vt);
+ @endcode
+
+ @param src decomposed matrix
+ @param w calculated singular values
+ @param u calculated left singular vectors
+ @param vt transposed matrix of right singular values
+ @param flags operation flags - see SVD::SVD.
+ */
+ static void compute( InputArray src, OutputArray w,
+ OutputArray u, OutputArray vt, int flags = 0 );
+
+ /** @overload
+ computes singular values of a matrix
+ @param src decomposed matrix
+ @param w calculated singular values
+ @param flags operation flags - see SVD::Flags.
+ */
+ static void compute( InputArray src, OutputArray w, int flags = 0 );
+
+ /** @brief performs back substitution
+ */
+ static void backSubst( InputArray w, InputArray u,
+ InputArray vt, InputArray rhs,
+ OutputArray dst );
+
+ /** @brief solves an under-determined singular linear system
+
+ The method finds a unit-length solution x of a singular linear system
+ A\*x = 0. Depending on the rank of A, there can be no solutions, a
+ single solution or an infinite number of solutions. In general, the
+ algorithm solves the following problem:
+ \f[dst = \arg \min _{x: \| x \| =1} \| src \cdot x \|\f]
+ @param src left-hand-side matrix.
+ @param dst found solution.
+ */
+ static void solveZ( InputArray src, OutputArray dst );
+
+ /** @brief performs a singular value back substitution.
+
+ The method calculates a back substitution for the specified right-hand
+ side:
+
+ \f[\texttt{x} = \texttt{vt} ^T \cdot diag( \texttt{w} )^{-1} \cdot \texttt{u} ^T \cdot \texttt{rhs} \sim \texttt{A} ^{-1} \cdot \texttt{rhs}\f]
+
+ Using this technique you can either get a very accurate solution of the
+ convenient linear system, or the best (in the least-squares terms)
+ pseudo-solution of an overdetermined linear system.
+
+ @param rhs right-hand side of a linear system (u\*w\*v')\*dst = rhs to
+ be solved, where A has been previously decomposed.
+
+ @param dst found solution of the system.
+
+ @note Explicit SVD with the further back substitution only makes sense
+ if you need to solve many linear systems with the same left-hand side
+ (for example, src ). If all you need is to solve a single system
+ (possibly with multiple rhs immediately available), simply call solve
+ add pass DECOMP_SVD there. It does absolutely the same thing.
+ */
+ void backSubst( InputArray rhs, OutputArray dst ) const;
+
+ /** @todo document */
+ template static
+ void compute( const Matx<_Tp, m, n>& a, Matx<_Tp, nm, 1>& w, Matx<_Tp, m, nm>& u, Matx<_Tp, n, nm>& vt );
+
+ /** @todo document */
+ template static
+ void compute( const Matx<_Tp, m, n>& a, Matx<_Tp, nm, 1>& w );
+
+ /** @todo document */
+ template static
+ void backSubst( const Matx<_Tp, nm, 1>& w, const Matx<_Tp, m, nm>& u, const Matx<_Tp, n, nm>& vt, const Matx<_Tp, m, nb>& rhs, Matx<_Tp, n, nb>& dst );
+
+ Mat u, w, vt;
+};
+
+/** @brief Random Number Generator
+
+Random number generator. It encapsulates the state (currently, a 64-bit
+integer) and has methods to return scalar random values and to fill
+arrays with random values. Currently it supports uniform and Gaussian
+(normal) distributions. The generator uses Multiply-With-Carry
+algorithm, introduced by G. Marsaglia (
+ ).
+Gaussian-distribution random numbers are generated using the Ziggurat
+algorithm ( ),
+introduced by G. Marsaglia and W. W. Tsang.
+*/
+class CV_EXPORTS RNG
+{
+public:
+ enum { UNIFORM = 0,
+ NORMAL = 1
+ };
+
+ /** @brief constructor
+
+ These are the RNG constructors. The first form sets the state to some
+ pre-defined value, equal to 2\*\*32-1 in the current implementation. The
+ second form sets the state to the specified value. If you passed state=0
+ , the constructor uses the above default value instead to avoid the
+ singular random number sequence, consisting of all zeros.
+ */
+ RNG();
+ /** @overload
+ @param state 64-bit value used to initialize the RNG.
+ */
+ RNG(uint64 state);
+ /**The method updates the state using the MWC algorithm and returns the
+ next 32-bit random number.*/
+ unsigned next();
+
+ /**Each of the methods updates the state using the MWC algorithm and
+ returns the next random number of the specified type. In case of integer
+ types, the returned number is from the available value range for the
+ specified type. In case of floating-point types, the returned value is
+ from [0,1) range.
+ */
+ operator uchar();
+ /** @overload */
+ operator schar();
+ /** @overload */
+ operator ushort();
+ /** @overload */
+ operator short();
+ /** @overload */
+ operator unsigned();
+ /** @overload */
+ operator int();
+ /** @overload */
+ operator float();
+ /** @overload */
+ operator double();
+
+ /** @brief returns a random integer sampled uniformly from [0, N).
+
+ The methods transform the state using the MWC algorithm and return the
+ next random number. The first form is equivalent to RNG::next . The
+ second form returns the random number modulo N , which means that the
+ result is in the range [0, N) .
+ */
+ unsigned operator ()();
+ /** @overload
+ @param N upper non-inclusive boundary of the returned random number.
+ */
+ unsigned operator ()(unsigned N);
+
+ /** @brief returns uniformly distributed integer random number from [a,b) range
+
+ The methods transform the state using the MWC algorithm and return the
+ next uniformly-distributed random number of the specified type, deduced
+ from the input parameter type, from the range [a, b) . There is a nuance
+ illustrated by the following sample:
+
+ @code{.cpp}
+ RNG rng;
+
+ // always produces 0
+ double a = rng.uniform(0, 1);
+
+ // produces double from [0, 1)
+ double a1 = rng.uniform((double)0, (double)1);
+
+ // produces float from [0, 1)
+ double b = rng.uniform(0.f, 1.f);
+
+ // produces double from [0, 1)
+ double c = rng.uniform(0., 1.);
+
+ // may cause compiler error because of ambiguity:
+ // RNG::uniform(0, (int)0.999999)? or RNG::uniform((double)0, 0.99999)?
+ double d = rng.uniform(0, 0.999999);
+ @endcode
+
+ The compiler does not take into account the type of the variable to
+ which you assign the result of RNG::uniform . The only thing that
+ matters to the compiler is the type of a and b parameters. So, if you
+ want a floating-point random number, but the range boundaries are
+ integer numbers, either put dots in the end, if they are constants, or
+ use explicit type cast operators, as in the a1 initialization above.
+ @param a lower inclusive boundary of the returned random numbers.
+ @param b upper non-inclusive boundary of the returned random numbers.
+ */
+ int uniform(int a, int b);
+ /** @overload */
+ float uniform(float a, float b);
+ /** @overload */
+ double uniform(double a, double b);
+
+ /** @brief Fills arrays with random numbers.
+
+ @param mat 2D or N-dimensional matrix; currently matrices with more than
+ 4 channels are not supported by the methods, use Mat::reshape as a
+ possible workaround.
+ @param distType distribution type, RNG::UNIFORM or RNG::NORMAL.
+ @param a first distribution parameter; in case of the uniform
+ distribution, this is an inclusive lower boundary, in case of the normal
+ distribution, this is a mean value.
+ @param b second distribution parameter; in case of the uniform
+ distribution, this is a non-inclusive upper boundary, in case of the
+ normal distribution, this is a standard deviation (diagonal of the
+ standard deviation matrix or the full standard deviation matrix).
+ @param saturateRange pre-saturation flag; for uniform distribution only;
+ if true, the method will first convert a and b to the acceptable value
+ range (according to the mat datatype) and then will generate uniformly
+ distributed random numbers within the range [saturate(a), saturate(b)),
+ if saturateRange=false, the method will generate uniformly distributed
+ random numbers in the original range [a, b) and then will saturate them,
+ it means, for example, that
+ theRNG().fill(mat_8u, RNG::UNIFORM, -DBL_MAX, DBL_MAX) will likely
+ produce array mostly filled with 0's and 255's, since the range (0, 255)
+ is significantly smaller than [-DBL_MAX, DBL_MAX).
+
+ Each of the methods fills the matrix with the random values from the
+ specified distribution. As the new numbers are generated, the RNG state
+ is updated accordingly. In case of multiple-channel images, every
+ channel is filled independently, which means that RNG cannot generate
+ samples from the multi-dimensional Gaussian distribution with
+ non-diagonal covariance matrix directly. To do that, the method
+ generates samples from multi-dimensional standard Gaussian distribution
+ with zero mean and identity covariation matrix, and then transforms them
+ using transform to get samples from the specified Gaussian distribution.
+ */
+ void fill( InputOutputArray mat, int distType, InputArray a, InputArray b, bool saturateRange = false );
+
+ /** @brief Returns the next random number sampled from the Gaussian distribution
+ @param sigma standard deviation of the distribution.
+
+ The method transforms the state using the MWC algorithm and returns the
+ next random number from the Gaussian distribution N(0,sigma) . That is,
+ the mean value of the returned random numbers is zero and the standard
+ deviation is the specified sigma .
+ */
+ double gaussian(double sigma);
+
+ uint64 state;
+};
+
+/** @brief Mersenne Twister random number generator
+
+Inspired by http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/CODES/mt19937ar.c
+@todo document
+ */
+class CV_EXPORTS RNG_MT19937
+{
+public:
+ RNG_MT19937();
+ RNG_MT19937(unsigned s);
+ void seed(unsigned s);
+
+ unsigned next();
+
+ operator int();
+ operator unsigned();
+ operator float();
+ operator double();
+
+ unsigned operator ()(unsigned N);
+ unsigned operator ()();
+
+ /** @brief returns uniformly distributed integer random number from [a,b) range
+
+*/
+ int uniform(int a, int b);
+ /** @brief returns uniformly distributed floating-point random number from [a,b) range
+
+*/
+ float uniform(float a, float b);
+ /** @brief returns uniformly distributed double-precision floating-point random number from [a,b) range
+
+*/
+ double uniform(double a, double b);
+
+private:
+ enum PeriodParameters {N = 624, M = 397};
+ unsigned state[N];
+ int mti;
+};
+
+//! @} core_array
+
+//! @addtogroup core_cluster
+//! @{
+
+/** @example kmeans.cpp
+ An example on K-means clustering
+*/
+
+/** @brief Finds centers of clusters and groups input samples around the clusters.
+
+The function kmeans implements a k-means algorithm that finds the centers of cluster_count clusters
+and groups the input samples around the clusters. As an output, \f$\texttt{labels}_i\f$ contains a
+0-based cluster index for the sample stored in the \f$i^{th}\f$ row of the samples matrix.
+
+@note
+- (Python) An example on K-means clustering can be found at
+ opencv_source_code/samples/python/kmeans.py
+@param data Data for clustering. An array of N-Dimensional points with float coordinates is needed.
+Examples of this array can be:
+- Mat points(count, 2, CV_32F);
+- Mat points(count, 1, CV_32FC2);
+- Mat points(1, count, CV_32FC2);
+- std::vector\ points(sampleCount);
+@param K Number of clusters to split the set by.
+@param bestLabels Input/output integer array that stores the cluster indices for every sample.
+@param criteria The algorithm termination criteria, that is, the maximum number of iterations and/or
+the desired accuracy. The accuracy is specified as criteria.epsilon. As soon as each of the cluster
+centers moves by less than criteria.epsilon on some iteration, the algorithm stops.
+@param attempts Flag to specify the number of times the algorithm is executed using different
+initial labellings. The algorithm returns the labels that yield the best compactness (see the last
+function parameter).
+@param flags Flag that can take values of cv::KmeansFlags
+@param centers Output matrix of the cluster centers, one row per each cluster center.
+@return The function returns the compactness measure that is computed as
+\f[\sum _i \| \texttt{samples} _i - \texttt{centers} _{ \texttt{labels} _i} \| ^2\f]
+after every attempt. The best (minimum) value is chosen and the corresponding labels and the
+compactness value are returned by the function. Basically, you can use only the core of the
+function, set the number of attempts to 1, initialize labels each time using a custom algorithm,
+pass them with the ( flags = KMEANS_USE_INITIAL_LABELS ) flag, and then choose the best
+(most-compact) clustering.
+*/
+CV_EXPORTS_W double kmeans( InputArray data, int K, InputOutputArray bestLabels,
+ TermCriteria criteria, int attempts,
+ int flags, OutputArray centers = noArray() );
+
+//! @} core_cluster
+
+//! @addtogroup core_basic
+//! @{
+
+/////////////////////////////// Formatted output of cv::Mat ///////////////////////////
+
+/** @todo document */
+class CV_EXPORTS Formatted
+{
+public:
+ virtual const char* next() = 0;
+ virtual void reset() = 0;
+ virtual ~Formatted();
+};
+
+/** @todo document */
+class CV_EXPORTS Formatter
+{
+public:
+ enum { FMT_DEFAULT = 0,
+ FMT_MATLAB = 1,
+ FMT_CSV = 2,
+ FMT_PYTHON = 3,
+ FMT_NUMPY = 4,
+ FMT_C = 5
+ };
+
+ virtual ~Formatter();
+
+ virtual Ptr format(const Mat& mtx) const = 0;
+
+ virtual void set32fPrecision(int p = 8) = 0;
+ virtual void set64fPrecision(int p = 16) = 0;
+ virtual void setMultiline(bool ml = true) = 0;
+
+ static Ptr get(int fmt = FMT_DEFAULT);
+
+};
+
+static inline
+String& operator << (String& out, Ptr fmtd)
+{
+ fmtd->reset();
+ for(const char* str = fmtd->next(); str; str = fmtd->next())
+ out += cv::String(str);
+ return out;
+}
+
+static inline
+String& operator << (String& out, const Mat& mtx)
+{
+ return out << Formatter::get()->format(mtx);
+}
+
+//////////////////////////////////////// Algorithm ////////////////////////////////////
+
+class CV_EXPORTS Algorithm;
+
+template struct ParamType {};
+
+
+/** @brief This is a base class for all more or less complex algorithms in OpenCV
+
+especially for classes of algorithms, for which there can be multiple implementations. The examples
+are stereo correspondence (for which there are algorithms like block matching, semi-global block
+matching, graph-cut etc.), background subtraction (which can be done using mixture-of-gaussians
+models, codebook-based algorithm etc.), optical flow (block matching, Lucas-Kanade, Horn-Schunck
+etc.).
+
+Here is example of SIFT use in your application via Algorithm interface:
+@code
+ #include "opencv2/opencv.hpp"
+ #include "opencv2/xfeatures2d.hpp"
+ using namespace cv::xfeatures2d;
+
+ Ptr sift = SIFT::create();
+ FileStorage fs("sift_params.xml", FileStorage::READ);
+ if( fs.isOpened() ) // if we have file with parameters, read them
+ {
+ sift->read(fs["sift_params"]);
+ fs.release();
+ }
+ else // else modify the parameters and store them; user can later edit the file to use different parameters
+ {
+ sift->setContrastThreshold(0.01f); // lower the contrast threshold, compared to the default value
+ {
+ WriteStructContext ws(fs, "sift_params", CV_NODE_MAP);
+ sift->write(fs);
+ }
+ }
+ Mat image = imread("myimage.png", 0), descriptors;
+ vector keypoints;
+ sift->detectAndCompute(image, noArray(), keypoints, descriptors);
+@endcode
+ */
+class CV_EXPORTS_W Algorithm
+{
+public:
+ Algorithm();
+ virtual ~Algorithm();
+
+ /** @brief Clears the algorithm state
+ */
+ CV_WRAP virtual void clear() {}
+
+ /** @brief Stores algorithm parameters in a file storage
+ */
+ virtual void write(FileStorage& fs) const { (void)fs; }
+
+ /** @brief Reads algorithm parameters from a file storage
+ */
+ virtual void read(const FileNode& fn) { (void)fn; }
+
+ /** @brief Returns true if the Algorithm is empty (e.g. in the very beginning or after unsuccessful read
+ */
+ virtual bool empty() const { return false; }
+
+ /** @brief Reads algorithm from the file node
+
+ This is static template method of Algorithm. It's usage is following (in the case of SVM):
+ @code
+ Ptr svm = Algorithm::read(fn);
+ @endcode
+ In order to make this method work, the derived class must overwrite Algorithm::read(const
+ FileNode& fn) and also have static create() method without parameters
+ (or with all the optional parameters)
+ */
+ template static Ptr<_Tp> read(const FileNode& fn)
+ {
+ Ptr<_Tp> obj = _Tp::create();
+ obj->read(fn);
+ return !obj->empty() ? obj : Ptr<_Tp>();
+ }
+
+ /** @brief Loads algorithm from the file
+
+ @param filename Name of the file to read.
+ @param objname The optional name of the node to read (if empty, the first top-level node will be used)
+
+ This is static template method of Algorithm. It's usage is following (in the case of SVM):
+ @code
+ Ptr svm = Algorithm::load("my_svm_model.xml");
+ @endcode
+ In order to make this method work, the derived class must overwrite Algorithm::read(const
+ FileNode& fn).
+ */
+ template static Ptr<_Tp> load(const String& filename, const String& objname=String())
+ {
+ FileStorage fs(filename, FileStorage::READ);
+ FileNode fn = objname.empty() ? fs.getFirstTopLevelNode() : fs[objname];
+ Ptr<_Tp> obj = _Tp::create();
+ obj->read(fn);
+ return !obj->empty() ? obj : Ptr<_Tp>();
+ }
+
+ /** @brief Loads algorithm from a String
+
+ @param strModel The string variable containing the model you want to load.
+ @param objname The optional name of the node to read (if empty, the first top-level node will be used)
+
+ This is static template method of Algorithm. It's usage is following (in the case of SVM):
+ @code
+ Ptr svm = Algorithm::loadFromString(myStringModel);
+ @endcode
+ */
+ template static Ptr<_Tp> loadFromString(const String& strModel, const String& objname=String())
+ {
+ FileStorage fs(strModel, FileStorage::READ + FileStorage::MEMORY);
+ FileNode fn = objname.empty() ? fs.getFirstTopLevelNode() : fs[objname];
+ Ptr<_Tp> obj = _Tp::create();
+ obj->read(fn);
+ return !obj->empty() ? obj : Ptr<_Tp>();
+ }
+
+ /** Saves the algorithm to a file.
+ In order to make this method work, the derived class must implement Algorithm::write(FileStorage& fs). */
+ CV_WRAP virtual void save(const String& filename) const;
+
+ /** Returns the algorithm string identifier.
+ This string is used as top level xml/yml node tag when the object is saved to a file or string. */
+ CV_WRAP virtual String getDefaultName() const;
+};
+
+struct Param {
+ enum { INT=0, BOOLEAN=1, REAL=2, STRING=3, MAT=4, MAT_VECTOR=5, ALGORITHM=6, FLOAT=7,
+ UNSIGNED_INT=8, UINT64=9, UCHAR=11 };
+};
+
+
+
+template<> struct ParamType
+{
+ typedef bool const_param_type;
+ typedef bool member_type;
+
+ enum { type = Param::BOOLEAN };
+};
+
+template<> struct ParamType
+{
+ typedef int const_param_type;
+ typedef int member_type;
+
+ enum { type = Param::INT };
+};
+
+template<> struct ParamType
+{
+ typedef double const_param_type;
+ typedef double member_type;
+
+ enum { type = Param::REAL };
+};
+
+template<> struct ParamType
+{
+ typedef const String& const_param_type;
+ typedef String member_type;
+
+ enum { type = Param::STRING };
+};
+
+template<> struct ParamType
+{
+ typedef const Mat& const_param_type;
+ typedef Mat member_type;
+
+ enum { type = Param::MAT };
+};
+
+template<> struct ParamType >
+{
+ typedef const std::vector& const_param_type;
+ typedef std::vector member_type;
+
+ enum { type = Param::MAT_VECTOR };
+};
+
+template<> struct ParamType
+{
+ typedef const Ptr& const_param_type;
+ typedef Ptr member_type;
+
+ enum { type = Param::ALGORITHM };
+};
+
+template<> struct ParamType
+{
+ typedef float const_param_type;
+ typedef float member_type;
+
+ enum { type = Param::FLOAT };
+};
+
+template<> struct ParamType
+{
+ typedef unsigned const_param_type;
+ typedef unsigned member_type;
+
+ enum { type = Param::UNSIGNED_INT };
+};
+
+template<> struct ParamType
+{
+ typedef uint64 const_param_type;
+ typedef uint64 member_type;
+
+ enum { type = Param::UINT64 };
+};
+
+template<> struct ParamType
+{
+ typedef uchar const_param_type;
+ typedef uchar member_type;
+
+ enum { type = Param::UCHAR };
+};
+
+//! @} core_basic
+
+} //namespace cv
+
+#include "opencv2/core/operations.hpp"
+#include "opencv2/core/cvstd.inl.hpp"
+#include "opencv2/core/utility.hpp"
+#include "opencv2/core/optim.hpp"
+
+#endif /*__OPENCV_CORE_HPP__*/
diff --git a/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/opencv310/include/opencv2/core/affine.hpp b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/opencv310/include/opencv2/core/affine.hpp
new file mode 100644
index 0000000..2bce5b9
--- /dev/null
+++ b/CW-Engine-SDK-v5.3.4.190903-Windows/CW-Engine-SDK-v5.3.4.190903-Windows/Demo_MFC/opencv310/include/opencv2/core/affine.hpp
@@ -0,0 +1,522 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef __OPENCV_CORE_AFFINE3_HPP__
+#define __OPENCV_CORE_AFFINE3_HPP__
+
+#ifdef __cplusplus
+
+#include
+
+namespace cv
+{
+
+//! @addtogroup core
+//! @{
+
+ /** @brief Affine transform
+ @todo document
+ */
+ template
+ class Affine3
+ {
+ public:
+ typedef T float_type;
+ typedef Matx Mat3;
+ typedef Matx Mat4;
+ typedef Vec Vec3;
+
+ Affine3();
+
+ //! Augmented affine matrix
+ Affine3(const Mat4& affine);
+
+ //! Rotation matrix
+ Affine3(const Mat3& R, const Vec3& t = Vec3::all(0));
+
+ //! Rodrigues vector
+ Affine3(const Vec3& rvec, const Vec3& t = Vec3::all(0));
+
+ //! Combines all contructors above. Supports 4x4, 4x3, 3x3, 1x3, 3x1 sizes of data matrix
+ explicit Affine3(const Mat& data, const Vec3& t = Vec3::all(0));
+
+ //! From 16th element array
+ explicit Affine3(const float_type* vals);
+
+ //! Create identity transform
+ static Affine3 Identity();
+
+ //! Rotation matrix
+ void rotation(const Mat3& R);
+
+ //! Rodrigues vector
+ void rotation(const Vec3& rvec);
+
+ //! Combines rotation methods above. Suports 3x3, 1x3, 3x1 sizes of data matrix;
+ void rotation(const Mat& data);
+
+ void linear(const Mat3& L);
+ void translation(const Vec3& t);
+
+ Mat3 rotation() const;
+ Mat3 linear() const;
+ Vec3 translation() const;
+
+ //! Rodrigues vector
+ Vec3 rvec() const;
+
+ Affine3 inv(int method = cv::DECOMP_SVD) const;
+
+ //! a.rotate(R) is equivalent to Affine(R, 0) * a;
+ Affine3 rotate(const Mat3& R) const;
+
+ //! a.rotate(rvec) is equivalent to Affine(rvec, 0) * a;
+ Affine3 rotate(const Vec3& rvec) const;
+
+ //! a.translate(t) is equivalent to Affine(E, t) * a;
+ Affine3 translate(const Vec3& t) const;
+
+ //! a.concatenate(affine) is equivalent to affine * a;
+ Affine3 concatenate(const Affine3& affine) const;
+
+ template operator Affine3() const;
+
+ template Affine3 cast() const;
+
+ Mat4 matrix;
+
+#if defined EIGEN_WORLD_VERSION && defined EIGEN_GEOMETRY_MODULE_H
+ Affine3(const Eigen::Transform& affine);
+ Affine3(const Eigen::Transform& affine);
+ operator Eigen::Transform() const;
+ operator Eigen::Transform() const;
+#endif
+ };
+
+ template static
+ Affine3 operator*(const Affine3& affine1, const Affine3& affine2);
+
+ template static
+ V operator*(const Affine3& affine, const V& vector);
+
+ typedef Affine3 Affine3f;
+ typedef Affine3 Affine3d;
+
+ static Vec3f operator*(const Affine3f& affine, const Vec3f& vector);
+ static Vec3d operator*(const Affine3d& affine, const Vec3d& vector);
+
+ template class DataType< Affine3<_Tp> >
+ {
+ public:
+ typedef Affine3<_Tp> value_type;
+ typedef Affine3::work_type> work_type;
+ typedef _Tp channel_type;
+
+ enum { generic_type = 0,
+ depth = DataType::depth,
+ channels = 16,
+ fmt = DataType::fmt + ((channels - 1) << 8),
+ type = CV_MAKETYPE(depth, channels)
+ };
+
+ typedef Vec vec_type;
+ };
+
+//! @} core
+
+}
+
+//! @cond IGNORED
+
+///////////////////////////////////////////////////////////////////////////////////
+// Implementaiton
+
+template inline
+cv::Affine3::Affine3()
+ : matrix(Mat4::eye())
+{}
+
+template inline
+cv::Affine3::Affine3(const Mat4& affine)
+ : matrix(affine)
+{}
+
+template inline
+cv::Affine3::Affine3(const Mat3& R, const Vec3& t)
+{
+ rotation(R);
+ translation(t);
+ matrix.val[12] = matrix.val[13] = matrix.val[14] = 0;
+ matrix.val[15] = 1;
+}
+
+template inline
+cv::Affine3::Affine3(const Vec3& _rvec, const Vec3& t)
+{
+ rotation(_rvec);
+ translation(t);
+ matrix.val[12] = matrix.val[13] = matrix.val[14] = 0;
+ matrix.val[15] = 1;
+}
+
+template inline
+cv::Affine3::Affine3(const cv::Mat& data, const Vec3& t)
+{
+ CV_Assert(data.type() == cv::DataType::type);
+
+ if (data.cols == 4 && data.rows == 4)
+ {
+ data.copyTo(matrix);
+ return;
+ }
+ else if (data.cols == 4 && data.rows == 3)
+ {
+ rotation(data(Rect(0, 0, 3, 3)));
+ translation(data(Rect(3, 0, 1, 3)));
+ return;
+ }
+
+ rotation(data);
+ translation(t);
+ matrix.val[12] = matrix.val[13] = matrix.val[14] = 0;
+ matrix.val[15] = 1;
+}
+
+template inline
+cv::Affine3::Affine3(const float_type* vals) : matrix(vals)
+{}
+
+template inline
+cv::Affine3 cv::Affine3::Identity()
+{
+ return Affine3(cv::Affine3::Mat4::eye());
+}
+
+template inline
+void cv::Affine3::rotation(const Mat3& R)
+{
+ linear(R);
+}
+
+template inline
+void cv::Affine3::rotation(const Vec3& _rvec)
+{
+ double rx = _rvec[0], ry = _rvec[1], rz = _rvec[2];
+ double theta = std::sqrt(rx*rx + ry*ry + rz*rz);
+
+ if (theta < DBL_EPSILON)
+ rotation(Mat3::eye());
+ else
+ {
+ const double I[] = { 1, 0, 0, 0, 1, 0, 0, 0, 1 };
+
+ double c = std::cos(theta);
+ double s = std::sin(theta);
+ double c1 = 1. - c;
+ double itheta = (theta != 0) ? 1./theta : 0.;
+
+ rx *= itheta; ry *= itheta; rz *= itheta;
+
+ double rrt[] = { rx*rx, rx*ry, rx*rz, rx*ry, ry*ry, ry*rz, rx*rz, ry*rz, rz*rz };
+ double _r_x_[] = { 0, -rz, ry, rz, 0, -rx, -ry, rx, 0 };
+ Mat3 R;
+
+ // R = cos(theta)*I + (1 - cos(theta))*r*rT + sin(theta)*[r_x]
+ // where [r_x] is [0 -rz ry; rz 0 -rx; -ry rx 0]
+ for(int k = 0; k < 9; ++k)
+ R.val[k] = static_cast(c*I[k] + c1*rrt[k] + s*_r_x_[k]);
+
+ rotation(R);
+ }
+}
+
+//Combines rotation methods above. Suports 3x3, 1x3, 3x1 sizes of data matrix;
+template inline
+void cv::Affine3::rotation(const cv::Mat& data)
+{
+ CV_Assert(data.type() == cv::DataType::type);
+
+ if (data.cols == 3 && data.rows == 3)
+ {
+ Mat3 R;
+ data.copyTo(R);
+ rotation(R);
+ }
+ else if ((data.cols == 3 && data.rows == 1) || (data.cols == 1 && data.rows == 3))
+ {
+ Vec3 _rvec;
+ data.reshape(1, 3).copyTo(_rvec);
+ rotation(_rvec);
+ }
+ else
+ CV_Assert(!"Input marix can be 3x3, 1x3 or 3x1");
+}
+
+template inline
+void cv::Affine3::linear(const Mat3& L)
+{
+ matrix.val[0] = L.val[0]; matrix.val[1] = L.val[1]; matrix.val[ 2] = L.val[2];
+ matrix.val[4] = L.val[3]; matrix.val[5] = L.val[4]; matrix.val[ 6] = L.val[5];
+ matrix.val[8] = L.val[6]; matrix.val[9] = L.val[7]; matrix.val[10] = L.val[8];
+}
+
+template inline
+void cv::Affine3::translation(const Vec3& t)
+{
+ matrix.val[3] = t[0]; matrix.val[7] = t[1]; matrix.val[11] = t[2];
+}
+
+template inline
+typename cv::Affine3::Mat3 cv::Affine3::rotation() const
+{
+ return linear();
+}
+
+template inline
+typename cv::Affine3::Mat3 cv::Affine3::linear() const
+{
+ typename cv::Affine3::Mat3 R;
+ R.val[0] = matrix.val[0]; R.val[1] = matrix.val[1]; R.val[2] = matrix.val[ 2];
+ R.val[3] = matrix.val[4]; R.val[4] = matrix.val[5]; R.val[5] = matrix.val[ 6];
+ R.val[6] = matrix.val[8]; R.val[7] = matrix.val[9]; R.val[8] = matrix.val[10];
+ return R;
+}
+
+template inline
+typename cv::Affine3::Vec3 cv::Affine3::translation() const
+{
+ return Vec3(matrix.val[3], matrix.val[7], matrix.val[11]);
+}
+
+template inline
+typename cv::Affine3::Vec3 cv::Affine3::rvec() const
+{
+ cv::Vec3d w;
+ cv::Matx33d u, vt, R = rotation();
+ cv::SVD::compute(R, w, u, vt, cv::SVD::FULL_UV + cv::SVD::MODIFY_A);
+ R = u * vt;
+
+ double rx = R.val[7] - R.val[5];
+ double ry = R.val[2] - R.val[6];
+ double rz = R.val[3] - R.val[1];
+
+ double s = std::sqrt((rx*rx + ry*ry + rz*rz)*0.25);
+ double c = (R.val[0] + R.val[4] + R.val[8] - 1) * 0.5;
+ c = c > 1.0 ? 1.0 : c < -1.0 ? -1.0 : c;
+ double theta = acos(c);
+
+ if( s < 1e-5 )
+ {
+ if( c > 0 )
+ rx = ry = rz = 0;
+ else
+ {
+ double t;
+ t = (R.val[0] + 1) * 0.5;
+ rx = std::sqrt(std::max(t, 0.0));
+ t = (R.val[4] + 1) * 0.5;
+ ry = std::sqrt(std::max(t, 0.0)) * (R.val[1] < 0 ? -1.0 : 1.0);
+ t = (R.val[8] + 1) * 0.5;
+ rz = std::sqrt(std::max(t, 0.0)) * (R.val[2] < 0 ? -1.0 : 1.0);
+
+ if( fabs(rx) < fabs(ry) && fabs(rx) < fabs(rz) && (R.val[5] > 0) != (ry*rz > 0) )
+ rz = -rz;
+ theta /= std::sqrt(rx*rx + ry*ry + rz*rz);
+ rx *= theta;
+ ry *= theta;
+ rz *= theta;
+ }
+ }
+ else
+ {
+ double vth = 1/(2*s);
+ vth *= theta;
+ rx *= vth; ry *= vth; rz *= vth;
+ }
+
+ return cv::Vec3d(rx, ry, rz);
+}
+
+template inline
+cv::Affine3 cv::Affine3::inv(int method) const
+{
+ return matrix.inv(method);
+}
+
+template inline
+cv::Affine3 cv::Affine3::rotate(const Mat3& R) const
+{
+ Mat3 Lc = linear();
+ Vec3 tc = translation();
+ Mat4 result;
+ result.val[12] = result.val[13] = result.val[14] = 0;
+ result.val[15] = 1;
+
+ for(int j = 0; j < 3; ++j)
+ {
+ for(int i = 0; i < 3; ++i)
+ {
+ float_type value = 0;
+ for(int k = 0; k < 3; ++k)
+ value += R(j, k) * Lc(k, i);
+ result(j, i) = value;
+ }
+
+ result(j, 3) = R.row(j).dot(tc.t());
+ }
+ return result;
+}
+
+template inline
+cv::Affine3 cv::Affine3::rotate(const Vec3& _rvec) const
+{
+ return rotate(Affine3f(_rvec).rotation());
+}
+
+template inline
+cv::Affine3 cv::Affine3