├── image ├── readme ├── tooth.jpg ├── toy.jpg ├── uml.jpg ├── show_pcl.jpg ├── calib_window.jpg ├── main_window.jpg └── calib_process.jpg ├── README.md └── src ├── readme ├── 源代码说明.txt ├── demo0316.h ├── Camera.h ├── gxbUnpackPhase.h ├── demo0316Dlg.h ├── gxbPhaseMatch.h ├── CvvImage.h ├── demo0316.cpp ├── Projector.h ├── VtkViewer.h ├── CameraCalibrator.h ├── VtkViewer.cpp ├── CameraStatus.h ├── CvvImage.cpp ├── gxbUnpackPhase.cpp ├── StereoCalib.h ├── demo0316Dlg.cpp └── CameraDefine.H /image/readme: -------------------------------------------------------------------------------- 1 | 软件界面及实际扫描效果 2 | -------------------------------------------------------------------------------- /image/tooth.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xunbing/3DScanner/HEAD/image/tooth.jpg -------------------------------------------------------------------------------- /image/toy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xunbing/3DScanner/HEAD/image/toy.jpg -------------------------------------------------------------------------------- /image/uml.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xunbing/3DScanner/HEAD/image/uml.jpg -------------------------------------------------------------------------------- /image/show_pcl.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xunbing/3DScanner/HEAD/image/show_pcl.jpg -------------------------------------------------------------------------------- /image/calib_window.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xunbing/3DScanner/HEAD/image/calib_window.jpg -------------------------------------------------------------------------------- /image/main_window.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xunbing/3DScanner/HEAD/image/main_window.jpg -------------------------------------------------------------------------------- /image/calib_process.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xunbing/3DScanner/HEAD/image/calib_process.jpg -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 3DScanner 2 | 三维扫描相关算法 3 | 4 | 包括多频外差相位求解、相机标定、点云后处理、点云可视化等相关算法 5 | 6 | /image/ 三维扫描仪实物图及软件操作界面 7 | 8 | /src/ 源代码 9 | -------------------------------------------------------------------------------- /src/readme: -------------------------------------------------------------------------------- 1 | 一、模块介绍 2 | 相机驱动: 3 | Camera.h 4 | CameraApi.h 5 | CameraDefine.H 6 | CameraStatus.h 7 | 标定: 8 | CameraCalibrator.h 9 | StereoCalib.h 10 | 点云可视化: 11 | VtkViewer.h 12 | VtkViewer.cpp 13 | 投影仪: 14 | Projector.h 15 | 多频外差相位展开: 16 | gxbUnpackPhase.h 17 | gxbUnpackPhase.cpp 18 | 双目匹配: 19 | gxbPhaseMatch.h 20 | 图片可视化: 21 | CvvImage.h 22 | CvvImage.cpp 23 | 主程序窗口: 24 | demo0316Dlg.h 25 | demo0316Dlg.cpp 26 | 二、环境说明 27 | 开发环境:win7 64位 、visual studio 2015 28 | 算法包:opencv3.1.1、pcl1.8.0、MFC 29 | 运行环境:16G内存,AMD速龙Ⅱ主频3Ghz 30 | -------------------------------------------------------------------------------- /src/源代码说明.txt: -------------------------------------------------------------------------------- 1 | 一、模块介绍 2 | 相机驱动: 3 | Camera.h 4 | CameraApi.h 5 | CameraDefine.H 6 | CameraStatus.h 7 | 标定: 8 | CameraCalibrator.h 9 | StereoCalib.h 10 | 点云可视化: 11 | VtkViewer.h 12 | VtkViewer.cpp 13 | 投影仪: 14 | Projector.h 15 | 多频外差相位展开: 16 | gxbUnpackPhase.h 17 | gxbUnpackPhase.cpp 18 | 双目匹配: 19 | gxbPhaseMatch.h 20 | 图片可视化: 21 | CvvImage.h 22 | CvvImage.cpp 23 | 主程序窗口: 24 | demo0316Dlg.h 25 | demo0316Dlg.cpp 26 | 二、环境说明 27 | 开发环境:win7 64位 、visual studio 2015 28 | 算法包:opencv3.1.1、pcl1.8.0 29 | 运行环境:16G内存,AMD速龙Ⅱ主频3Ghz -------------------------------------------------------------------------------- /src/demo0316.h: -------------------------------------------------------------------------------- 1 | 2 | // demo0316.h : PROJECT_NAME 应用程序的主头文件 3 | // 4 | 5 | #pragma once 6 | 7 | #ifndef __AFXWIN_H__ 8 | #error "在包含此文件之前包含“stdafx.h”以生成 PCH 文件" 9 | #endif 10 | 11 | #include "resource.h" // 主符号 12 | 13 | 14 | // Cdemo0316App: 15 | // 有关此类的实现,请参阅 demo0316.cpp 16 | // 17 | 18 | class Cdemo0316App : public CWinApp 19 | { 20 | public: 21 | Cdemo0316App(); 22 | 23 | // 重写 24 | public: 25 | virtual BOOL InitInstance(); 26 | // 实现 27 | 28 | DECLARE_MESSAGE_MAP() 29 | }; 30 | extern Cdemo0316App theApp; -------------------------------------------------------------------------------- /src/Camera.h: -------------------------------------------------------------------------------- 1 | #include "CameraApi.h" 2 | #include 3 | class Camera 4 | { 5 | int Width = 2048; 6 | int Height = 1536; 7 | public: 8 | tSdkCameraDevInfo pCameraList[2]; 9 | int piNums = 2; 10 | CameraHandle pCameraHandle[2]; 11 | int OpenCamera() 12 | { 13 | std::cout << "初始化sdk(中文模式):" << CameraSdkInit(1) << std::endl;//初始化sdk(中文模式) 14 | std::cout << "枚举设备:" << CameraEnumerateDevice(pCameraList, &piNums) << std::endl;//枚举设备 15 | std::cout << "初始化相机:" << CameraInit(&pCameraList[0], -1, -1, &pCameraHandle[0]) << std::endl;//初始化相机 16 | std::cout << "初始化相机:" << CameraInit(&pCameraList[1], -1, -1, &pCameraHandle[1]) << std::endl;//初始化相机 17 | std::cout << "左相机进入图像采集模式:" << CameraPlay(pCameraHandle[0]) << std::endl;//左相机进入图像采集模式 18 | std::cout << "右相机进入图像采集模式:" << CameraPlay(pCameraHandle[1]) << std::endl;//右相机进入图像采集模式 19 | return 1; 20 | } 21 | int CloseCamera() 22 | { 23 | CameraUnInit(pCameraHandle[0]); //逆初始化 24 | CameraUnInit(pCameraHandle[1]);//逆初始化 25 | return 1; 26 | } 27 | }; -------------------------------------------------------------------------------- /src/gxbUnpackPhase.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | class gxbUnpackPhase 3 | { 4 | 5 | int W = 2048;//照片宽度 6 | int H = 1536;//照片高度 7 | int nstep = 5;//相移步数 8 | double PI = 3.14159265358979; 9 | ///针对1280pixel幅面的相机 10 | //int p1 = 13; 11 | //int p2 = 14; 12 | //int p3 = 15; 13 | ///针对2048pixel幅面的相机 14 | int p1 = 16; 15 | int p2 = 17; 16 | int p3 = 18; 17 | 18 | public: 19 | // 20 | int gxbInit(int w, int h, int step); 21 | int gxbGetWrappedPhase(int step, unsigned char **&Arrayofphase, double *PHASE, int size, int index, int row); 22 | int gxbPhaseResult(unsigned char **&Img, double *phase); 23 | int gxbGetPhase(unsigned char**img, double *phase); 24 | int gxbPhaseflitter(double *PHASE); 25 | int gxbRemoveBg(unsigned char *bgImgb, unsigned char *bgImgw, double *PHASE); 26 | int gxbRegionGrow(unsigned char**&pImg, double *Phase); 27 | int writemyphase(int index, int w, int h, double *phasel, double *phaser); 28 | int gxbReduceUselessPhase(double *&finalPhase, double *cp_abPhase1, double *cp_abPhase2, double *&Diff1, double *&Diff2); 29 | 30 | }; -------------------------------------------------------------------------------- /src/demo0316Dlg.h: -------------------------------------------------------------------------------- 1 | 2 | // demo0316Dlg.h : 头文件 3 | // 4 | #include "CameraApi.h" 5 | #pragma once 6 | 7 | 8 | // Cdemo0316Dlg 对话框 9 | class Cdemo0316Dlg : public CDialogEx 10 | { 11 | // 构造 12 | public: 13 | Cdemo0316Dlg(CWnd* pParent = NULL); // 标准构造函数 14 | 15 | // 对话框数据 16 | #ifdef AFX_DESIGN_TIME 17 | enum { IDD = IDD_DEMO0316_DIALOG }; 18 | #endif 19 | 20 | protected: 21 | virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 22 | 23 | 24 | // 实现 25 | protected: 26 | HICON m_hIcon; 27 | 28 | // 生成的消息映射函数 29 | virtual BOOL OnInitDialog(); 30 | afx_msg void OnSysCommand(UINT nID, LPARAM lParam); 31 | afx_msg void OnPaint(); 32 | afx_msg HCURSOR OnQueryDragIcon(); 33 | DECLARE_MESSAGE_MAP() 34 | public: 35 | afx_msg void OnBnClickedOpencalibwnd(); 36 | afx_msg void OnBnClickedBtnCheck(); 37 | 38 | 39 | int Width = 2048; 40 | int Height = 1536; 41 | double *phaseL = new double[Width*Height]; 42 | double *phaseR = new double[Width*Height]; 43 | unsigned char * dataL = new unsigned char[Width*Height * 3]; 44 | unsigned char * dataR = new unsigned char[Width*Height * 3]; 45 | 46 | 47 | afx_msg void OnBnClickedBtnScan(); 48 | }; -------------------------------------------------------------------------------- /src/gxbPhaseMatch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "stdafx.h" 3 | #include 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | #include 9 | class gxbPhaseMatch 10 | { 11 | 12 | public: 13 | int phaseMatch(int W, int H, double *&phaseL, double *&phaseR, double *&D) 14 | { 15 | cout << "正在进行相位匹配..." << endl; 16 | for (int i = 0; i < H; i++) 17 | { 18 | for (int j = 0; j < W; j++) 19 | { 20 | for (int k = 0; k < W; k++) 21 | { 22 | if (fabs(phaseL[i*W + j] - phaseR[i*W + k]) < 0.01&&phaseL[i*W + j] != 0 && phaseR[i*W + k] != 0) 23 | { 24 | D[i*W + j] = abs(j - k); 25 | break; 26 | } 27 | } 28 | } 29 | } 30 | return 0; 31 | } 32 | int createPointCloud(int W, int H, double *&D, char *filename,double focousX,double focousY,double B,Mat Q) 33 | { 34 | cout << "正在保存点云.." << endl; 35 | ofstream out; 36 | out.open(filename, ofstream::out); 37 | for (int y = 0; y < H; y++) 38 | { 39 | //double qx = q[0][1] * y + q[0][3], qy = q[1][1] * y + q[1][3]; 40 | //double qz = q[2][1] * y + q[2][3], qw = q[3][1] * y + q[3][3]; 41 | for (int x = 0; x < W; x++) 42 | { 43 | 44 | if (D[y*W + x] > 10) 45 | { 46 | double d = D[y*W + x]; 47 | 48 | //double Z =focousX*(-1*B) / d; 49 | //double X = x*Z/ focousX; 50 | //double Y = y*Z/ focousY; 51 | double Ww = (-1 * B) / d; 52 | double X = (x + Q.at(0, 3))/Ww; 53 | double Y = -1*(y + Q.at(1, 3))/Ww; 54 | double Z = Q.at(2, 3) / Ww; 55 | 56 | out << X << " " << Y << " " << Z << endl; 57 | } 58 | } 59 | } 60 | return 0; 61 | } 62 | }; -------------------------------------------------------------------------------- /src/CvvImage.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include "stdafx.h" 3 | using namespace cv; 4 | #pragma once 5 | 6 | #ifndef CVVIMAGE_CLASS_DEF 7 | 8 | #define CVVIMAGE_CLASS_DEF 9 | #include 10 | using namespace cv; 11 | class CvvImage 12 | 13 | { 14 | 15 | public: 16 | 17 | CvvImage(); 18 | 19 | virtual ~CvvImage(); 20 | 21 | 22 | 23 | virtual bool Create( int width, int height, int bits_per_pixel, int image_origin = 0 ); 24 | 25 | 26 | 27 | virtual bool Load( const char* filename, int desired_color = 1 ); 28 | 29 | 30 | 31 | virtual bool LoadRect( const char* filename, 32 | 33 | int desired_color, CvRect r ); 34 | 35 | #if defined WIN32 || defined _WIN32 36 | 37 | virtual bool LoadRect( const char* filename, 38 | 39 | int desired_color, RECT r ) 40 | 41 | { 42 | 43 | return LoadRect( filename, desired_color, 44 | 45 | cvRect( r.left, r.top, r.right - r.left, r.bottom - r.top )); 46 | 47 | } 48 | 49 | #endif 50 | 51 | 52 | 53 | virtual bool Save( const char* filename ); 54 | 55 | 56 | 57 | virtual void CopyOf( CvvImage& image, int desired_color = -1 ); 58 | 59 | virtual void CopyOf( IplImage* img, int desired_color = -1 ); 60 | 61 | IplImage* GetImage() { return m_img; }; 62 | 63 | virtual void Destroy(void); 64 | 65 | 66 | 67 | int Width() { return !m_img ? 0 : !m_img->roi ? m_img->width : m_img->roi->width; }; 68 | 69 | int Height() { return !m_img ? 0 : !m_img->roi ? m_img->height : m_img->roi->height;}; 70 | 71 | int Bpp() { return m_img ? (m_img->depth & 255)*m_img->nChannels : 0; }; 72 | 73 | virtual void Fill( int color ); 74 | 75 | 76 | 77 | virtual void Show( const char* window ); 78 | 79 | 80 | 81 | #if defined WIN32 || defined _WIN32 82 | 83 | 84 | 85 | virtual void Show( HDC dc, int x, int y, int width, int height, 86 | 87 | int from_x = 0, int from_y = 0 ); 88 | 89 | 90 | 91 | virtual void DrawToHDC( HDC hDCDst, RECT* pDstRect ); 92 | 93 | #endif 94 | 95 | protected: 96 | 97 | IplImage* m_img; 98 | 99 | }; 100 | 101 | //typedef CvvImage CImage; 102 | namespace cv 103 | { 104 | typedef CvvImage CImage; 105 | } 106 | #endif -------------------------------------------------------------------------------- /src/demo0316.cpp: -------------------------------------------------------------------------------- 1 | 2 | // demo0316.cpp : 定义应用程序的类行为。 3 | // 4 | 5 | #include "stdafx.h" 6 | #include "demo0316.h" 7 | #include "demo0316Dlg.h" 8 | 9 | #ifdef _DEBUG 10 | #define new DEBUG_NEW 11 | #endif 12 | 13 | 14 | // Cdemo0316App 15 | 16 | BEGIN_MESSAGE_MAP(Cdemo0316App, CWinApp) 17 | ON_COMMAND(ID_HELP, &CWinApp::OnHelp) 18 | END_MESSAGE_MAP() 19 | 20 | 21 | // Cdemo0316App 构造 22 | 23 | Cdemo0316App::Cdemo0316App() 24 | { 25 | // 支持重新启动管理器 26 | m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART; 27 | 28 | // TODO: 在此处添加构造代码, 29 | // 将所有重要的初始化放置在 InitInstance 中 30 | } 31 | 32 | // 唯一的一个 Cdemo0316App 对象 33 | 34 | Cdemo0316App theApp; 35 | 36 | 37 | // Cdemo0316App 初始化 38 | 39 | BOOL Cdemo0316App::InitInstance() 40 | { 41 | // 如果一个运行在 Windows XP 上的应用程序清单指定要 42 | // 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式, 43 | //则需要 InitCommonControlsEx()。 否则,将无法创建窗口。 44 | INITCOMMONCONTROLSEX InitCtrls; 45 | InitCtrls.dwSize = sizeof(InitCtrls); 46 | // 将它设置为包括所有要在应用程序中使用的 47 | // 公共控件类。 48 | InitCtrls.dwICC = ICC_WIN95_CLASSES; 49 | InitCommonControlsEx(&InitCtrls); 50 | 51 | CWinApp::InitInstance(); 52 | 53 | 54 | AfxEnableControlContainer(); 55 | 56 | // 创建 shell 管理器,以防对话框包含 57 | // 任何 shell 树视图控件或 shell 列表视图控件。 58 | CShellManager *pShellManager = new CShellManager; 59 | 60 | // 激活“Windows Native”视觉管理器,以便在 MFC 控件中启用主题 61 | CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows)); 62 | 63 | // 标准初始化 64 | // 如果未使用这些功能并希望减小 65 | // 最终可执行文件的大小,则应移除下列 66 | // 不需要的特定初始化例程 67 | // 更改用于存储设置的注册表项 68 | // TODO: 应适当修改该字符串, 69 | // 例如修改为公司或组织名 70 | SetRegistryKey(_T("应用程序向导生成的本地应用程序")); 71 | 72 | Cdemo0316Dlg dlg; 73 | m_pMainWnd = &dlg; 74 | INT_PTR nResponse = dlg.DoModal(); 75 | if (nResponse == IDOK) 76 | { 77 | // TODO: 在此放置处理何时用 78 | // “确定”来关闭对话框的代码 79 | } 80 | else if (nResponse == IDCANCEL) 81 | { 82 | // TODO: 在此放置处理何时用 83 | // “取消”来关闭对话框的代码 84 | } 85 | else if (nResponse == -1) 86 | { 87 | TRACE(traceAppMsg, 0, "警告: 对话框创建失败,应用程序将意外终止。\n"); 88 | TRACE(traceAppMsg, 0, "警告: 如果您在对话框上使用 MFC 控件,则无法 #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS。\n"); 89 | } 90 | 91 | // 删除上面创建的 shell 管理器。 92 | if (pShellManager != NULL) 93 | { 94 | delete pShellManager; 95 | } 96 | 97 | #ifndef _AFXDLL 98 | ControlBarCleanUp(); 99 | #endif 100 | 101 | // 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序, 102 | // 而不是启动应用程序的消息泵。 103 | return FALSE; 104 | } 105 | 106 | -------------------------------------------------------------------------------- /src/Projector.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "stdafx.h" 3 | #include "CameraApi.h" 4 | #include 5 | using namespace cv; 6 | double PI = 3.14159265358979; 7 | class Projector 8 | { 9 | private: 10 | int p1 = 16; 11 | int p2 = 17; 12 | int p3 = 18; 13 | public: 14 | int gxbCreateProjImg(int index, unsigned char*data, int proW) 15 | { 16 | int colorRange = 255; 17 | if (index >= 1 && index <= 5) 18 | { 19 | for (int i = 0; i < proW; i++) 20 | { 21 | int remainer1 = i % p1; 22 | int result1 = int((sin((2.0f * PI / p1 * remainer1 + 2.0f * PI*(index - 1) / 5.0)) + 1) / 2.0 * colorRange + 0.5f); 23 | data[i] = result1; 24 | } 25 | } 26 | else if (index >= 6 && index <= 10) 27 | { 28 | for (int i = 0; i < proW; i++) 29 | { 30 | int remainer2 = i % p2; 31 | int result2 = int((sin((2.0f * PI / p2 * remainer2 + 2.0f * PI*(index - 6) / 5.0)) + 1) / 2.0 * colorRange + 0.5f); 32 | data[i] = result2; 33 | } 34 | } 35 | else if (index >= 11 && index <= 15) 36 | { 37 | for (int i = 0; i < proW; i++) 38 | { 39 | int remainer3 = i % p3; 40 | int result3 = int((sin((2.0f * PI / p3 * remainer3 + 2.0f * PI*(index - 11) / 5.0)) + 1) / 2.0 * colorRange + 0.5f); 41 | data[i] = result3; 42 | } 43 | } 44 | else if (index == 16) 45 | { 46 | for (int i = 0; i < proW; i++) 47 | { 48 | data[i] = 0; 49 | } 50 | } 51 | else if (index == 17) 52 | { 53 | for (int i = 0; i < proW; i++) 54 | { 55 | data[i] = colorRange; 56 | } 57 | } 58 | return 0; 59 | } 60 | int gxbProAndPic(int proW, int proH, unsigned char*&proImg, unsigned char**&pImgL, unsigned char**&pImgR) 61 | { 62 | 63 | unsigned char*dataForPro = new unsigned char[proW]; 64 | float timeExpose = 0; 65 | int timeFlag = 0; 66 | unsigned char * rgbL = 0; 67 | unsigned char * rgbR = 0; 68 | char* wndname = "Proimg"; 69 | for (int i = 0; i < 17; i++) 70 | { 71 | gxbCreateProjImg(i + 1, dataForPro, proW); 72 | for (int k = 0; k < proH; k++) 73 | { 74 | for (int j = 0; j < proW; j++) 75 | { 76 | proImg[k*proW + j] = dataForPro[j]; 77 | } 78 | } 79 | Mat proShow = Mat(proH, proW, CV_8UC1, proImg); 80 | //imwrite(rasname, proShow); 81 | namedWindow(wndname, WINDOW_AUTOSIZE); 82 | setWindowProperty(wndname, CV_WND_PROP_FULLSCREEN, CV_WINDOW_FULLSCREEN); 83 | moveWindow(wndname, 1920, 0); 84 | imshow(wndname, proShow); 85 | if (i == 0) 86 | waitKey(400); 87 | else 88 | waitKey(300); 89 | 90 | 91 | } 92 | return 0; 93 | } 94 | }; -------------------------------------------------------------------------------- /src/VtkViewer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "afxwin.h" 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | #include 20 | 21 | #include 22 | #include 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | #include 37 | #include 38 | #include 39 | 40 | #include 41 | VTK_MODULE_INIT(vtkRenderingOpenGL2) 42 | VTK_MODULE_INIT(vtkInteractionStyle) 43 | VTK_MODULE_INIT(vtkRenderingFreeType) 44 | 45 | using Pointf = struct _Pointf { 46 | float x; 47 | float y; 48 | float z; 49 | float r; 50 | float g; 51 | float b; 52 | }; 53 | 54 | class CVtkViewer : public CStatic 55 | { 56 | DECLARE_DYNAMIC(CVtkViewer) 57 | 58 | public: 59 | CVtkViewer(); 60 | virtual ~CVtkViewer(); 61 | 62 | vtkSmartPointer actor; 63 | void ReadPointCloud(std::vector&); 64 | 65 | public: 66 | //3.2 重载CvtkView类PreSubclassWindow()函数和OnPaint()函数 67 | //PreSubclassWindow函数负责创建VTK可视化管线,OnPaint()函数负责客户区内场景渲染。 68 | //vtkAcor,vtkRenderer,vtkRenderWindow,vtkRenderWindowInteractor四个部分。当然根据需要还可以设置vtkRenderWindowInteractorStyle,以及光照,材质,颜色等。 69 | //在CvtkView类头文件中定义相关对象,并在PreSubclassWindow函数中实例化和构建可视化管线 70 | void PreSubclassWindow(); 71 | void SetImageData(vtkSmartPointer ImageData); 72 | void SetupReslice(); 73 | void MoveWindow(CRect); 74 | 75 | private: 76 | vtkSmartPointer< vtkImagePlaneWidget > m_ImagePlaneWidget; 77 | vtkSmartPointer< vtkResliceCursorWidget> m_ResliceCursorWidget; 78 | vtkSmartPointer< vtkResliceCursor > m_ResliceCursor; 79 | vtkSmartPointer< vtkResliceCursorThickLineRepresentation > m_ResliceCursorRep; 80 | 81 | vtkSmartPointer m_Renderer; 82 | vtkSmartPointer m_RenderWindow; 83 | vtkSmartPointer m_ImageData; 84 | 85 | //m_Direction为方向标志,取值分别为0,1和2,分别代表X轴,Y轴和Z轴方向, 86 | int m_Direction; 87 | 88 | protected: 89 | DECLARE_MESSAGE_MAP() 90 | }; 91 | -------------------------------------------------------------------------------- /src/CameraCalibrator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "stdafx.h" 3 | class CameraCalibrator 4 | { 5 | private: 6 | //世界坐标 7 | std::vector < std::vector> objectPoints; 8 | //图像坐标 9 | std::vector > imagePoints ; 10 | //输出矩阵 11 | cv::Mat camerMatirx; 12 | cv::Mat disCoeffs; 13 | std::vectorrvecs, tvecs; 14 | //标记 15 | int flag; 16 | //去畸变参数 17 | cv::Mat map1, map2; 18 | //是否去畸变 19 | bool mustInitUndistort; 20 | 21 | ///保存点数据 22 | void addPoints(const std::vector&imageConers, const std::vector&objectConers) 23 | { 24 | imagePoints.push_back(imageConers); 25 | objectPoints.push_back(objectConers); 26 | } 27 | public: 28 | CameraCalibrator() :flag(0), mustInitUndistort(true) {} 29 | //打开棋盘图片,提取角点 30 | int addChessboardPoints(unsigned char **imgList,int Height,int Width, int num,cv::Size &boardSize) 31 | { 32 | std::vectorimageConers; 33 | std::vectorobjectConers; 34 | //输入角点的世界坐标 35 | for (int i = 0; i < boardSize.height; i++) 36 | { 37 | for (int j = 0; j < boardSize.width; j++) 38 | { 39 | objectConers.push_back(cv::Point3f(i, j, 0.0f)); 40 | } 41 | } 42 | //计算角点在图像中的坐标 43 | cv::Mat image; 44 | int success = 0; 45 | for (int i = 0; i < num; i++) 46 | { 47 | image = Mat(Height,Width,CV_8UC1,imgList[i]); 48 | //找到角点坐标 49 | 50 | bool found = cv::findChessboardCorners(image, boardSize, imageConers); 51 | cv::cornerSubPix(image, 52 | imageConers, 53 | cv::Size(5, 5), 54 | cv::Size(-1, -1), 55 | cv::TermCriteria(cv::TermCriteria::MAX_ITER + cv::TermCriteria::EPS, 56 | 30, 0.1)); 57 | 58 | printf("imageConers.size():%d\n", imageConers.size()); 59 | if (imageConers.size() == boardSize.area()) 60 | { 61 | addPoints(imageConers, objectConers); 62 | success++; 63 | } 64 | //画出角点 65 | cv::drawChessboardCorners(image, boardSize, imageConers, found); 66 | //cv::imshow("Corners on Chessboard", image); 67 | //cv::waitKey(100); 68 | } 69 | printf("success:%d\n",success); 70 | printf("角点已找出\n"); 71 | return success; 72 | } 73 | 74 | //相机标定 75 | double calibrate(cv::Size&imageSize) 76 | { 77 | printf("开始标定...\n"); 78 | mustInitUndistort = true; 79 | //相机标定 80 | return cv::calibrateCamera(objectPoints, imagePoints, imageSize, 81 | camerMatirx, disCoeffs, rvecs, tvecs, flag); 82 | } 83 | ///去畸变 84 | cv::Mat remap(const cv::Mat &image) 85 | { 86 | cv::Mat undistorted; 87 | if (mustInitUndistort) 88 | { 89 | //计算畸变参数 90 | cv::initUndistortRectifyMap(camerMatirx, disCoeffs, 91 | cv::Mat(), cv::Mat(), image.size(), CV_32FC1, map1, map2); 92 | mustInitUndistort = false; 93 | } 94 | //应用映射函数 95 | cv::remap(image, undistorted, map1, map2, cv::INTER_LINEAR); 96 | return undistorted; 97 | } 98 | //常成员函数,获得相机内参数矩阵、投影矩阵数据 99 | cv::Mat getCameraMatrix() const { return camerMatirx; } 100 | cv::Mat getDistCoeffs() const { return disCoeffs; } 101 | std::vectorgetR() { return rvecs; }; 102 | std::vectorgetT() { return tvecs; }; 103 | }; -------------------------------------------------------------------------------- /src/VtkViewer.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "VtkViewer.h" 3 | 4 | IMPLEMENT_DYNAMIC(CVtkViewer, CStatic) 5 | 6 | CVtkViewer::CVtkViewer() 7 | { 8 | //在实例化时需要注意,该视图类在默认情况下渲染的是vtkResliceCursorWidget对象的输出, 9 | //因此需要为vtkResliceCursorWidget对象指定相应的vtkRenderer对象, 10 | //m_ResliceCursorWidget->SetInteractor(m_RenderWindow->GetInteractor()); 11 | //m_ResliceCursorWidget->SetDefaultRenderer(m_Renderer); 12 | } 13 | 14 | CVtkViewer::~CVtkViewer() 15 | { 16 | } 17 | 18 | void CVtkViewer::ReadPointCloud(std::vector& pointcloud) { 19 | // 点云全部显示同样的颜色 20 | vtkPoints * points = vtkPoints::New(); 21 | int n = pointcloud.size(); int idx = 0; 22 | for (int i = 0; i < n; ++i){ 23 | points->InsertPoint(i, pointcloud[i].x, pointcloud[i].y, pointcloud[i].z); 24 | } 25 | 26 | vtkPolyVertex * polyvertex = vtkPolyVertex::New(); 27 | polyvertex->GetPointIds()->SetNumberOfIds(n); 28 | for (int i = 0; i < n; ++i){ 29 | polyvertex->GetPointIds()->SetId(i, i); 30 | } 31 | 32 | vtkUnstructuredGrid * grid = vtkUnstructuredGrid::New(); 33 | grid->SetPoints(points); 34 | grid->InsertNextCell(polyvertex->GetCellType(), polyvertex->GetPointIds()); 35 | 36 | vtkDataSetMapper * map = vtkDataSetMapper::New(); 37 | map->SetInputData(grid); 38 | 39 | vtkActor * actor = vtkActor::New(); 40 | actor->SetMapper(map); 41 | actor->GetProperty()->SetColor(0.194, 0.562, 0.75); 42 | 43 | m_Renderer->AddActor(actor); 44 | m_Renderer->SetBackground(0, 0, 0); 45 | m_Renderer->ResetCamera(); 46 | m_RenderWindow->Render(); 47 | 48 | map->Delete(); 49 | grid->Delete(); 50 | actor->Delete(); 51 | points->Delete(); 52 | polyvertex->Delete(); 53 | } 54 | 55 | void CVtkViewer::PreSubclassWindow() 56 | { 57 | // TODO: Add your specialized code here and/or call the base class 58 | CRect rect; 59 | GetClientRect(rect); 60 | 61 | m_Renderer = vtkSmartPointer::New(); 62 | m_RenderWindow = vtkSmartPointer::New(); 63 | m_RenderWindow->SetParentId(this->m_hWnd); 64 | m_RenderWindow->SetSize(rect.Width(), rect.Height()); 65 | m_RenderWindow->AddRenderer(m_Renderer); 66 | 67 | if (m_RenderWindow->GetInteractor() == NULL) 68 | { 69 | vtkSmartPointer RenderWindowInteractor = 70 | vtkSmartPointer::New(); 71 | RenderWindowInteractor->SetRenderWindow(m_RenderWindow); 72 | RenderWindowInteractor->Initialize(); 73 | } 74 | 75 | m_RenderWindow->Start(); 76 | CStatic::PreSubclassWindow(); 77 | } 78 | 79 | void CVtkViewer::SetImageData(vtkSmartPointer ImageData) 80 | { 81 | if (ImageData == NULL) return; 82 | 83 | m_ImageData = ImageData; 84 | SetupReslice(); 85 | } 86 | void CVtkViewer::SetupReslice() 87 | { 88 | if (m_ImageData == NULL) return; 89 | int dims[3]; 90 | m_ImageData->GetDimensions(dims); 91 | 92 | ////////////////////////////////////////////////////////////////////////// 93 | m_ImagePlaneWidget->SetInputData(m_ImageData); 94 | m_ImagePlaneWidget->SetPlaneOrientation(m_Direction); 95 | m_ImagePlaneWidget->SetSliceIndex(dims[m_Direction] / 2); 96 | m_ImagePlaneWidget->On(); 97 | m_ImagePlaneWidget->InteractionOn(); 98 | 99 | ////////////////////////////////////////////////////////////////////////// 100 | m_ResliceCursor->SetCenter(m_ImageData->GetCenter()); 101 | m_ResliceCursor->SetImage(m_ImageData); 102 | m_ResliceCursor->SetThickMode(0); 103 | 104 | //m_ResliceCursorRep->GetResliceCursorActor()->GetCursorAlgorithm()->SetResliceCursor(m_ResliceCursor); 105 | //m_ResliceCursorRep->GetResliceCursorActor()->GetCursorAlgorithm()->SetReslicePlaneNormal(m_Direction); 106 | 107 | m_ResliceCursorWidget->SetEnabled(1); 108 | m_Renderer->ResetCamera(); 109 | 110 | ////////////////////////////////////////////////////////////////////////// 111 | double range[2]; 112 | m_ImageData->GetScalarRange(range); 113 | m_ResliceCursorWidget->GetResliceCursorRepresentation()-> 114 | SetWindowLevel(range[1] - range[0], (range[0] + range[1]) / 2.0); 115 | m_ImagePlaneWidget->SetWindowLevel(range[1] - range[0], (range[0] + range[1]) / 2.0); 116 | } 117 | 118 | void CVtkViewer::MoveWindow(CRect rect) { 119 | m_RenderWindow->SetSize(rect.Width(), rect.Height()); 120 | CStatic::MoveWindow(rect); 121 | } 122 | 123 | BEGIN_MESSAGE_MAP(CVtkViewer, CStatic) 124 | END_MESSAGE_MAP() -------------------------------------------------------------------------------- /src/CameraStatus.h: -------------------------------------------------------------------------------- 1 | #ifndef __CAMERA_STATUS_DEF__ 2 | #define __CAMERA_STATUS_DEF__ 3 | 4 | typedef int CameraSdkStatus; 5 | 6 | 7 | /*常用的宏*/ 8 | #define SDK_SUCCESS(_FUC_) (_FUC_ == CAMERA_STATUS_SUCCESS) 9 | 10 | #define SDK_UNSUCCESS(_FUC_) (_FUC_ != CAMERA_STATUS_SUCCESS) 11 | 12 | #define SDK_UNSUCCESS_RETURN(_FUC_,RET) if((RET = _FUC_) != CAMERA_STATUS_SUCCESS)\ 13 | {\ 14 | return RET;\ 15 | } 16 | 17 | #define SDK_UNSUCCESS_BREAK(_FUC_) if(_FUC_ != CAMERA_STATUS_SUCCESS)\ 18 | {\ 19 | break;\ 20 | } 21 | 22 | 23 | /* 常用错误 */ 24 | 25 | #define CAMERA_STATUS_SUCCESS 0 // 操作成功 26 | #define CAMERA_STATUS_FAILED -1 // 操作失败 27 | #define CAMERA_STATUS_INTERNAL_ERROR -2 // 内部错误 28 | #define CAMERA_STATUS_UNKNOW -3 // 未知错误 29 | #define CAMERA_STATUS_NOT_SUPPORTED -4 // 不支持该功能 30 | #define CAMERA_STATUS_NOT_INITIALIZED -5 // 初始化未完成 31 | #define CAMERA_STATUS_PARAMETER_INVALID -6 // 参数无效 32 | #define CAMERA_STATUS_PARAMETER_OUT_OF_BOUND -7 // 参数越界 33 | #define CAMERA_STATUS_UNENABLED -8 // 未使能 34 | #define CAMERA_STATUS_USER_CANCEL -9 // 用户手动取消了,比如roi面板点击取消,返回 35 | #define CAMERA_STATUS_PATH_NOT_FOUND -10 // 注册表中没有找到对应的路径 36 | #define CAMERA_STATUS_SIZE_DISMATCH -11 // 获得图像数据长度和定义的尺寸不匹配 37 | #define CAMERA_STATUS_TIME_OUT -12 // 超时错误 38 | #define CAMERA_STATUS_IO_ERROR -13 // 硬件IO错误 39 | #define CAMERA_STATUS_COMM_ERROR -14 // 通讯错误 40 | #define CAMERA_STATUS_BUS_ERROR -15 // 总线错误 41 | #define CAMERA_STATUS_NO_DEVICE_FOUND -16 // 没有发现设备 42 | #define CAMERA_STATUS_NO_LOGIC_DEVICE_FOUND -17 // 未找到逻辑设备 43 | #define CAMERA_STATUS_DEVICE_IS_OPENED -18 // 设备已经打开 44 | #define CAMERA_STATUS_DEVICE_IS_CLOSED -19 // 设备已经关闭 45 | #define CAMERA_STATUS_DEVICE_VEDIO_CLOSED -20 // 没有打开设备视频,调用录像相关的函数时,如果相机视频没有打开,则回返回该错误。 46 | #define CAMERA_STATUS_NO_MEMORY -21 // 没有足够系统内存 47 | #define CAMERA_STATUS_FILE_CREATE_FAILED -22 // 创建文件失败 48 | #define CAMERA_STATUS_FILE_INVALID -23 // 文件格式无效 49 | #define CAMERA_STATUS_WRITE_PROTECTED -24 // 写保护,不可写 50 | #define CAMERA_STATUS_GRAB_FAILED -25 // 数据采集失败 51 | #define CAMERA_STATUS_LOST_DATA -26 // 数据丢失,不完整 52 | #define CAMERA_STATUS_EOF_ERROR -27 // 未接收到帧结束符 53 | #define CAMERA_STATUS_BUSY -28 // 正忙(上一次操作还在进行中),此次操作不能进行 54 | #define CAMERA_STATUS_WAIT -29 // 需要等待(进行操作的条件不成立),可以再次尝试 55 | #define CAMERA_STATUS_IN_PROCESS -30 // 正在进行,已经被操作过 56 | #define CAMERA_STATUS_IIC_ERROR -31 // IIC传输错误 57 | #define CAMERA_STATUS_SPI_ERROR -32 // SPI传输错误 58 | #define CAMERA_STATUS_USB_CONTROL_ERROR -33 // USB控制传输错误 59 | #define CAMERA_STATUS_USB_BULK_ERROR -34 // USB BULK传输错误 60 | #define CAMERA_STATUS_SOCKET_INIT_ERROR -35 // 网络传输套件初始化失败 61 | #define CAMERA_STATUS_GIGE_FILTER_INIT_ERROR -36 // 网络相机内核过滤驱动初始化失败,请检查是否正确安装了驱动,或者重新安装。 62 | #define CAMERA_STATUS_NET_SEND_ERROR -37 // 网络数据发送错误 63 | #define CAMERA_STATUS_DEVICE_LOST -38 // 与网络相机失去连接,心跳检测超时 64 | #define CAMERA_STATUS_DATA_RECV_LESS -39 // 接收到的字节数比请求的少 65 | #define CAMERA_STATUS_FUNCTION_LOAD_FAILED -40 // 从文件中加载程序失败 66 | #define CAMERA_STATUS_CRITICAL_FILE_LOST -41 // 程序运行所必须的文件丢失。 67 | #define CAMERA_STATUS_SENSOR_ID_DISMATCH -42 // 固件和程序不匹配,原因是下载了错误的固件。 68 | #define CAMERA_STATUS_OUT_OF_RANGE -43 // 参数超出有效范围。 69 | #define CAMERA_STATUS_REGISTRY_ERROR -44 // 安装程序注册错误。请重新安装程序,或者运行安装目录Setup/Installer.exe 70 | #define CAMERA_STATUS_ACCESS_DENY -45 // 禁止访问。指定相机已经被其他程序占用时,再申请访问该相机,会返回该状态。(一个相机不能被多个程序同时访问) 71 | #define CAMERA_STATUS_CAMERA_NEED_RESET -46 // 表示相机需要复位后才能正常使用,此时请让相机断电重启,或者重启操作系统后,便可正常使用。 72 | #define CAMERA_STATUS_ISP_MOUDLE_NOT_INITIALIZED -47 // ISP模块未初始化 73 | #define CAMERA_STATUS_ISP_DATA_CRC_ERROR -48 // 数据校验错误 74 | #define CAMERA_STATUS_MV_TEST_FAILED -49 // 数据测试失败 75 | #define CAMERA_STATUS_INTERNAL_ERR1 -50 // 内部错误1 76 | #define CAMERA_STATUS_U3V_NO_CONTROL_EP -51 // U3V控制端点未找到 77 | #define CAMERA_STATUS_U3V_CONTROL_ERROR -52 // U3V控制通讯错误 78 | 79 | 80 | 81 | 82 | 83 | //和AIA制定的标准相同 84 | /*#define CAMERA_AIA_SUCCESS 0x0000 */ 85 | #define CAMERA_AIA_PACKET_RESEND 0x0100 //该帧需要重传 86 | #define CAMERA_AIA_NOT_IMPLEMENTED 0x8001 //设备不支持的命令 87 | #define CAMERA_AIA_INVALID_PARAMETER 0x8002 //命令参数非法 88 | #define CAMERA_AIA_INVALID_ADDRESS 0x8003 //不可访问的地址 89 | #define CAMERA_AIA_WRITE_PROTECT 0x8004 //访问的对象不可写 90 | #define CAMERA_AIA_BAD_ALIGNMENT 0x8005 //访问的地址没有按照要求对齐 91 | #define CAMERA_AIA_ACCESS_DENIED 0x8006 //没有访问权限 92 | #define CAMERA_AIA_BUSY 0x8007 //命令正在处理中 93 | #define CAMERA_AIA_DEPRECATED 0x8008 //0x8008-0x0800B 0x800F 该指令已经废弃 94 | #define CAMERA_AIA_PACKET_UNAVAILABLE 0x800C //包无效 95 | #define CAMERA_AIA_DATA_OVERRUN 0x800D //数据溢出,通常是收到的数据比需要的多 96 | #define CAMERA_AIA_INVALID_HEADER 0x800E //数据包头部中某些区域与协议不匹配 97 | #define CAMERA_AIA_PACKET_NOT_YET_AVAILABLE 0x8010 //图像分包数据还未准备好,多用于触发模式,应用程序访问超时 98 | #define CAMERA_AIA_PACKET_AND_PREV_REMOVED_FROM_MEMORY 0x8011 //需要访问的分包已经不存在。多用于重传时数据已经不在缓冲区中 99 | #define CAMERA_AIA_PACKET_REMOVED_FROM_MEMORY 0x8012 //CAMERA_AIA_PACKET_AND_PREV_REMOVED_FROM_MEMORY 100 | #define CAMERA_AIA_NO_REF_TIME 0x0813 //没有参考时钟源。多用于时间同步的命令执行时 101 | #define CAMERA_AIA_PACKET_TEMPORARILY_UNAVAILABLE 0x0814 //由于信道带宽问题,当前分包暂时不可用,需稍后进行访问 102 | #define CAMERA_AIA_OVERFLOW 0x0815 //设备端数据溢出,通常是队列已满 103 | #define CAMERA_AIA_ACTION_LATE 0x0816 //命令执行已经超过有效的指定时间 104 | #define CAMERA_AIA_ERROR 0x8FFF //错误 105 | 106 | 107 | 108 | 109 | 110 | #endif 111 | -------------------------------------------------------------------------------- /src/CvvImage.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "CvvImage.h" 3 | ////////////////////////////////////////////////////////////////////// 4 | // Construction/Destruction 5 | ////////////////////////////////////////////////////////////////////// 6 | CV_INLINE RECT NormalizeRect( RECT r ); 7 | CV_INLINE RECT NormalizeRect( RECT r ) 8 | { 9 | int t; 10 | if( r.left > r.right ) 11 | { 12 | t = r.left; 13 | r.left = r.right; 14 | r.right = t; 15 | } 16 | if( r.top > r.bottom ) 17 | { 18 | t = r.top; 19 | r.top = r.bottom; 20 | r.bottom = t; 21 | } 22 | 23 | return r; 24 | } 25 | CV_INLINE CvRect RectToCvRect( RECT sr ); 26 | CV_INLINE CvRect RectToCvRect( RECT sr ) 27 | { 28 | sr = NormalizeRect( sr ); 29 | return cvRect( sr.left, sr.top, sr.right - sr.left, sr.bottom - sr.top ); 30 | } 31 | CV_INLINE RECT CvRectToRect( CvRect sr ); 32 | CV_INLINE RECT CvRectToRect( CvRect sr ) 33 | { 34 | RECT dr; 35 | dr.left = sr.x; 36 | dr.top = sr.y; 37 | dr.right = sr.x + sr.width; 38 | dr.bottom = sr.y + sr.height; 39 | 40 | return dr; 41 | } 42 | CV_INLINE IplROI RectToROI( RECT r ); 43 | CV_INLINE IplROI RectToROI( RECT r ) 44 | { 45 | IplROI roi; 46 | r = NormalizeRect( r ); 47 | roi.xOffset = r.left; 48 | roi.yOffset = r.top; 49 | roi.width = r.right - r.left; 50 | roi.height = r.bottom - r.top; 51 | roi.coi = 0; 52 | 53 | return roi; 54 | } 55 | void FillBitmapInfo( BITMAPINFO* bmi, int width, int height, int bpp, int origin ) 56 | { 57 | assert( bmi && width >= 0 && height >= 0 && (bpp == 8 || bpp == 24 || bpp == 32)); 58 | 59 | BITMAPINFOHEADER* bmih = &(bmi->bmiHeader); 60 | 61 | memset( bmih, 0, sizeof(*bmih)); 62 | bmih->biSize = sizeof(BITMAPINFOHEADER); 63 | bmih->biWidth = width; 64 | bmih->biHeight = origin ? abs(height) : -abs(height); 65 | bmih->biPlanes = 1; 66 | bmih->biBitCount = (unsigned short)bpp; 67 | bmih->biCompression = BI_RGB; 68 | if( bpp == 8 ) 69 | { 70 | RGBQUAD* palette = bmi->bmiColors; 71 | int i; 72 | for( i = 0; i < 256; i++ ) 73 | { 74 | palette[i].rgbBlue = palette[i].rgbGreen = palette[i].rgbRed = (BYTE)i; 75 | palette[i].rgbReserved = 0; 76 | } 77 | } 78 | } 79 | CvvImage::CvvImage() 80 | { 81 | m_img = 0; 82 | } 83 | void CvvImage::Destroy() 84 | { 85 | cvReleaseImage( &m_img ); 86 | } 87 | CvvImage::~CvvImage() 88 | { 89 | Destroy(); 90 | } 91 | bool CvvImage::Create( int w, int h, int bpp, int origin ) 92 | { 93 | const unsigned max_img_size = 10000; 94 | 95 | if( (bpp != 8 && bpp != 24 && bpp != 32) || 96 | (unsigned)w >= max_img_size || (unsigned)h >= max_img_size || 97 | (origin != IPL_ORIGIN_TL && origin != IPL_ORIGIN_BL)) 98 | { 99 | assert(0); // most probably, it is a programming error 100 | return false; 101 | } 102 | if( !m_img || Bpp() != bpp || m_img->width != w || m_img->height != h ) 103 | { 104 | if( m_img && m_img->nSize == sizeof(IplImage)) 105 | Destroy(); 106 | 107 | m_img = cvCreateImage( cvSize( w, h ), IPL_DEPTH_8U, bpp/8 ); 108 | } 109 | if( m_img ) 110 | m_img->origin = origin == 0 ? IPL_ORIGIN_TL : IPL_ORIGIN_BL; 111 | return m_img != 0; 112 | } 113 | void CvvImage::CopyOf( CvvImage& image, int desired_color ) 114 | { 115 | IplImage* img = image.GetImage(); 116 | if( img ) 117 | { 118 | CopyOf( img, desired_color ); 119 | } 120 | } 121 | #define HG_IS_IMAGE(img) \ 122 | ((img) != 0 && ((const IplImage*)(img))->nSize == sizeof(IplImage) && \ 123 | ((IplImage*)img)->imageData != 0) 124 | void CvvImage::CopyOf( IplImage* img, int desired_color ) 125 | { 126 | if( HG_IS_IMAGE(img) ) 127 | { 128 | int color = desired_color; 129 | CvSize size = cvGetSize( img ); 130 | if( color < 0 ) 131 | color = img->nChannels > 1; 132 | if( Create( size.width, size.height, 133 | (!color ? 1 : img->nChannels > 1 ? img->nChannels : 3)*8, 134 | img->origin )) 135 | { 136 | cvConvertImage( img, m_img, 0 ); 137 | } 138 | } 139 | } 140 | bool CvvImage::Load( const char* filename, int desired_color ) 141 | { 142 | IplImage* img = cvLoadImage( filename, desired_color ); 143 | if( !img ) 144 | return false; 145 | 146 | CopyOf( img, desired_color ); 147 | cvReleaseImage( &img ); 148 | 149 | return true; 150 | } 151 | bool CvvImage::LoadRect( const char* filename, 152 | int desired_color, CvRect r ) 153 | { 154 | if( r.width < 0 || r.height < 0 ) return false; 155 | 156 | IplImage* img = cvLoadImage( filename, desired_color ); 157 | if( !img ) 158 | return false; 159 | if( r.width == 0 || r.height == 0 ) 160 | { 161 | r.width = img->width; 162 | r.height = img->height; 163 | r.x = r.y = 0; 164 | } 165 | if( r.x > img->width || r.y > img->height || 166 | r.x + r.width < 0 || r.y + r.height < 0 ) 167 | { 168 | cvReleaseImage( &img ); 169 | return false; 170 | } 171 | 172 | if( r.x < 0 ) 173 | { 174 | r.width += r.x; 175 | r.x = 0; 176 | } 177 | if( r.y < 0 ) 178 | { 179 | r.height += r.y; 180 | r.y = 0; 181 | } 182 | if( r.x + r.width > img->width ) 183 | r.width = img->width - r.x; 184 | 185 | if( r.y + r.height > img->height ) 186 | r.height = img->height - r.y; 187 | cvSetImageROI( img, r ); 188 | CopyOf( img, desired_color ); 189 | cvReleaseImage( &img ); 190 | return true; 191 | } 192 | bool CvvImage::Save( const char* filename ) 193 | { 194 | if( !m_img ) 195 | return false; 196 | cvSaveImage( filename, m_img ); 197 | return true; 198 | } 199 | void CvvImage::Show( const char* window ) 200 | { 201 | if( m_img ) 202 | cvShowImage( window, m_img ); 203 | } 204 | void CvvImage::Show( HDC dc, int x, int y, int w, int h, int from_x, int from_y ) 205 | { 206 | if( m_img && m_img->depth == IPL_DEPTH_8U ) 207 | { 208 | uchar buffer[sizeof(BITMAPINFOHEADER) + 1024]; 209 | BITMAPINFO* bmi = (BITMAPINFO*)buffer; 210 | int bmp_w = m_img->width, bmp_h = m_img->height; 211 | FillBitmapInfo( bmi, bmp_w, bmp_h, Bpp(), m_img->origin ); 212 | from_x = MIN( MAX( from_x, 0 ), bmp_w - 1 ); 213 | from_y = MIN( MAX( from_y, 0 ), bmp_h - 1 ); 214 | int sw = MAX( MIN( bmp_w - from_x, w ), 0 ); 215 | int sh = MAX( MIN( bmp_h - from_y, h ), 0 ); 216 | SetDIBitsToDevice( 217 | dc, x, y, sw, sh, from_x, from_y, from_y, sh, 218 | m_img->imageData + from_y*m_img->widthStep, 219 | bmi, DIB_RGB_COLORS ); 220 | } 221 | } 222 | void CvvImage::DrawToHDC( HDC hDCDst, RECT* pDstRect ) 223 | { 224 | if( pDstRect && m_img && m_img->depth == IPL_DEPTH_8U && m_img->imageData ) 225 | { 226 | uchar buffer[sizeof(BITMAPINFOHEADER) + 1024]; 227 | BITMAPINFO* bmi = (BITMAPINFO*)buffer; 228 | int bmp_w = m_img->width, bmp_h = m_img->height; 229 | CvRect roi = cvGetImageROI( m_img ); 230 | CvRect dst = RectToCvRect( *pDstRect ); 231 | if( roi.width == dst.width && roi.height == dst.height ) 232 | { 233 | Show( hDCDst, dst.x, dst.y, dst.width, dst.height, roi.x, roi.y ); 234 | return; 235 | } 236 | if( roi.width > dst.width ) 237 | { 238 | SetStretchBltMode( 239 | hDCDst, // handle to device context 240 | HALFTONE ); 241 | } 242 | else 243 | { 244 | SetStretchBltMode( 245 | hDCDst, // handle to device context 246 | COLORONCOLOR ); 247 | } 248 | FillBitmapInfo( bmi, bmp_w, bmp_h, Bpp(), m_img->origin ); 249 | ::StretchDIBits( 250 | hDCDst, 251 | dst.x, dst.y, dst.width, dst.height, 252 | roi.x, roi.y, roi.width, roi.height, 253 | m_img->imageData, bmi, DIB_RGB_COLORS, SRCCOPY ); 254 | } 255 | } 256 | void CvvImage::Fill( int color ) 257 | { 258 | cvSet( m_img, cvScalar(color&255,(color>>8)&255,(color>>16)&255,(color>>24)&255) ); 259 | } -------------------------------------------------------------------------------- /src/gxbUnpackPhase.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "gxbUnpackPhase.h" 3 | #include 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | #include 9 | //初始化 10 | int gxbUnpackPhase::gxbInit(int w, int h, int step) 11 | { 12 | W = w; 13 | H = h; 14 | nstep = step; 15 | return 0; 16 | } 17 | //消除背景 18 | int gxbUnpackPhase::gxbRemoveBg(unsigned char *bgImgb, unsigned char *bgImgw, double *PHASE) 19 | { 20 | cv::Mat *bg = new cv::Mat[2]; 21 | bg[0] = cv::Mat(H, W, CV_8UC1, bgImgb); 22 | bg[1] = cv::Mat(H, W, CV_8UC1, bgImgw); 23 | bool *judge = new bool[W*H]; 24 | 25 | //黑白相减 26 | for (int i = 0; i < H; i++) 27 | { 28 | for (int j = 0; j < W; j++) 29 | { 30 | int ij = i*W + j; 31 | if (bgImgw[ij] - bgImgb[ij] > 5) 32 | { 33 | bgImgw[ij] = bgImgw[ij] - bgImgb[ij]; 34 | } 35 | else 36 | bgImgw[ij] = 0; 37 | //if (bg[1].at(i, j) - bg[0].at(i, j) > 5) 38 | // bg[1].at(i, j) = bg[1].at(i, j) - bg[0].at(i, j); 39 | //else 40 | // bg[1].at(i, j) = 0; 41 | } 42 | } 43 | //中值滤波减少椒盐噪声 44 | cv::medianBlur(bg[1], bg[1], 3); 45 | 46 | cv::Mat bg_copy1 = cv::Mat(H, W, CV_8UC1, bgImgw); 47 | //二值化 48 | cv::threshold(bg_copy1, bg_copy1, 0, 255, CV_THRESH_BINARY); 49 | 50 | blur(bg_copy1, bg_copy1, cv::Size(3, 3)); 51 | cv::Mat detected_edges; 52 | /// 运行Canny算子 53 | Canny(bg_copy1, detected_edges, 40, 120, 3); 54 | 55 | /// 使用 Canny算子输出边缘作为掩码显示原图像 56 | cv::Mat dst; 57 | dst = cv::Scalar::all(0); 58 | bg_copy1.copyTo(dst, detected_edges); 59 | 60 | cv::Mat element = cv::getStructuringElement(cv::MORPH_ELLIPSE, 61 | cv::Size(2 * 3 + 1, 2 * 3 + 1), 62 | cv::Point(1, 1)); 63 | ///膨胀操作 64 | dilate(dst, dst, element); 65 | threshold(dst, dst, 10, 255, CV_THRESH_BINARY); 66 | for (int i = 0; i < H; i++) 67 | { 68 | for (int j = 0; j < W; j++) 69 | { 70 | if (dst.data[i*W + j] == 255) 71 | { 72 | PHASE[i*W + j] = 0; 73 | } 74 | } 75 | } 76 | cv::Mat element2 = cv::getStructuringElement(0, cv::Size(3, 3)); 77 | // 腐蚀操作 78 | cv::erode(bg_copy1, bg_copy1, element2); 79 | for (int i = 1; i < H; i++) 80 | { 81 | for (int j = 1; j < W; j++) 82 | { 83 | int weight = 0; 84 | if (bgImgw[i*W + j] == 255) 85 | { 86 | //八连通区域检测 87 | if (i < H - 1 && j < W - 1) 88 | { 89 | if (bgImgw[i*W + j - 1] == 0) 90 | weight++; 91 | if (bgImgw[i*W + j + 1] == 0) 92 | weight++; 93 | if (bgImgw[(i - 1)*W + j] == 0) 94 | weight++; 95 | if (bgImgw[(i + 1)*W + j] == 0) 96 | weight++; 97 | if (bgImgw[(i - 1)*W + j - 1] == 0) 98 | weight++; 99 | if (bgImgw[(i + 1)*W + j + 1] == 0) 100 | weight++; 101 | if (bgImgw[(i - 1)*W + j + 1] == 0) 102 | weight++; 103 | if (bgImgw[(i + 1)*W + j - 1] == 0) 104 | weight++; 105 | } 106 | if (weight <= 3) 107 | judge[i*W + j] = TRUE; 108 | else 109 | judge[i*W + j] = FALSE; 110 | } 111 | else 112 | { 113 | judge[i*W + j] = FALSE; 114 | //bg[1].at(i, j) = 0; 115 | } 116 | } 117 | } 118 | for (int k = 0; k < 17; k++) 119 | { 120 | for (int i = 0; i < H; i++) 121 | { 122 | for (int j = 0; j < W; j++) 123 | { 124 | if (i < H - 1 && j < W - 1) 125 | { 126 | if (!judge[i*W + j]) 127 | { 128 | PHASE[i*W + j] = 0; 129 | } 130 | } 131 | } 132 | } 133 | } 134 | delete[]judge; 135 | return 0; 136 | } 137 | //相位滤波 138 | int gxbUnpackPhase::gxbPhaseflitter(double *PHASE) 139 | { 140 | double *phasej1 = new double[W*H]; 141 | memset(phasej1, 0, W*H); 142 | for (int i = 1; i < H - 1; i++) 143 | { 144 | for (int j = 1; j < W - 1; j++) 145 | { 146 | if (fabs(PHASE[i*W + j + 1] - PHASE[i*W + j]) > 6) 147 | { 148 | phasej1[i*W + j] = 1; 149 | phasej1[i*W + j - 1] = 1; 150 | phasej1[i*W + j + 1] = 1; 151 | phasej1[i*W + j + 2] = 1; 152 | } 153 | } 154 | } 155 | for (int i = 1; i < H - 1; i++) 156 | { 157 | for (int j = 1; j < W - 1; j++) 158 | { 159 | if (phasej1[i*W + j] == 1) 160 | PHASE[i*W + j] = 0; 161 | } 162 | } 163 | ///上下左右八连通滤波 164 | double *phasej = new double[W*H]; 165 | for (int i = 0; i < W*H; i++) 166 | { 167 | phasej[i] = 0; 168 | } 169 | double aver = 0; 170 | 171 | for (int i = 1; i < H - 1; i++) 172 | { 173 | for (int j = 1; j < W - 1; j++) 174 | { 175 | aver = (PHASE[i*W + j] + PHASE[(i - 1)*W + j] + PHASE[(i + 1)*W + j] + PHASE[i*W + j - 1] + PHASE[i*W + j + 1] + PHASE[(i - 1)*W + j - 1] + PHASE[(i - 1)*W + j + 1] + PHASE[(i + 1)*W + j + 1] + PHASE[(i + 1)*W + j - 1]) / 9; 176 | if (fabs(aver - PHASE[i*W + j]) > 0.1) 177 | phasej[i*W + j] = 1; 178 | } 179 | } 180 | 181 | for (int i = 1; i < H - 1; i++) 182 | { 183 | for (int j = 1; j < W - 1; j++) 184 | { 185 | if (phasej[i*W + j] == 1) 186 | PHASE[i*W + j] = 0; 187 | } 188 | } 189 | delete[]phasej; 190 | return 0; 191 | } 192 | //求包裹相位 193 | int gxbUnpackPhase::gxbGetWrappedPhase(int step, unsigned char **&Arrayofphase, double *PHASE, int size, int index, int row) 194 | { 195 | /*........... 196 | This part of the code is confidential and not open to the public. 197 | sorry!!! 198 | ............*/ 199 | } 200 | //求展开相位 201 | int gxbUnpackPhase::gxbPhaseResult(unsigned char **&Img, double *phase) 202 | { 203 | /*........... 204 | This part of the code is confidential and not open to the public. 205 | sorry!!! 206 | ............*/ 207 | } 208 | //边缘处理 209 | int gxbUnpackPhase::gxbRegionGrow(unsigned char**&pImg, double *Phase) 210 | { 211 | int *Judge = new int[W*H]; 212 | memset(Judge, 0, W * H); 213 | double *tmpPhaselr = new double[W*H]; 214 | double *tmpPhaseud = new double[W*H]; 215 | unsigned char *data = new unsigned char[W*H]; 216 | unsigned char *result = new unsigned char[W*H]; 217 | memset(data, 0, W*H); 218 | for (int i = 1; i < H - 1; i++) 219 | { 220 | for (int j = 1; j < W - 1; j++) 221 | { 222 | //cout << Phase[i*W + j] << endl; 223 | tmpPhaselr[i*W + j] = Phase[i*W + j + 1] - Phase[i*W + j]; 224 | if (fabs(tmpPhaselr[i*W + j]) > 5) 225 | data[i*W + j] = 255; 226 | /*data[i*W + j] = uchar((tmpPhaselr[i*W + j]+PI) / (132 * 2 * PI)*24 * 255);*/ 227 | } 228 | } 229 | for (int i = 1; i < H - 1; i++) 230 | { 231 | for (int j = 1; j < W - 1; j++) 232 | { 233 | tmpPhaseud[i*W + j] = Phase[i*W + j] - Phase[(i - 1)*W + j]; 234 | if (fabs(tmpPhaseud[i*W + j]) > 5) 235 | data[i*W + j] = 255; 236 | } 237 | } 238 | cv::Mat showCont = cv::Mat(H, W, CV_8UC1, data); 239 | 240 | cv::threshold(showCont, showCont, 50, 255, 0); 241 | cv::Mat element = cv::getStructuringElement(cv::MORPH_ELLIPSE, 242 | cv::Size(2 * 1 + 1, 2 * 1 + 1), 243 | cv::Point(1, 1)); 244 | ///膨胀操作 245 | cv::dilate(showCont, showCont, element); 246 | unsigned char*Img = showCont.data; 247 | 248 | memset(result, 0, W*H); 249 | cv::Point2i pt = cv::Point2i(1, 1); 250 | cv::Point2i ptGrowing; //待生长点位置 251 | int nGrowLable = 0; //标记是否生长过 252 | int nSrcValue = 0; //生长起点灰度值 253 | int nCurValue = 0; //当前生长点灰度值 254 | 255 | //生长方向顺序数据 256 | int DIR[8][2] = { { -1,-1 },{ 0,-1 },{ 1,-1 },{ 1,0 },{ 1,1 },{ 0,1 },{ -1,1 },{ -1,0 } }; 257 | std::vector vcGrowPt; //生长点栈 258 | std::vector vcSize; 259 | for (int p = 1; p < H - 1; p++) 260 | { 261 | for (int k = 1; k < W - 1; k++) 262 | { 263 | if (Img[p*W + k] == 255 && result[p*W + k] == 0)//种子点满足要求且未被访问过 264 | { 265 | pt = cv::Point2i(k, p); 266 | vcGrowPt.push_back(pt);//将生长点压入栈中 267 | vcSize.push_back(pt);//记录生长区域的面积用于判断 268 | 269 | result[pt.y*W + pt.x] = 255; //标记生长点 270 | nSrcValue = Img[pt.y*W + pt.x]; //记录生长点的灰度值 271 | 272 | while (!vcGrowPt.empty()) //生长栈不为空则生长 273 | { 274 | pt = vcGrowPt.back(); //取出一个生长点 275 | vcGrowPt.pop_back(); 276 | 277 | //分别对八个方向上的点进行生长 278 | for (int i = 0; i < 9; ++i) 279 | { 280 | ptGrowing.x = pt.x + DIR[i][0]; 281 | ptGrowing.y = pt.y + DIR[i][1]; 282 | //检查是否是边缘点 283 | if (ptGrowing.x < 0 || ptGrowing.y < 0 || ptGrowing.x >(W - 1) || (ptGrowing.y > H - 1)) 284 | continue; 285 | 286 | nGrowLable = result[ptGrowing.y*W + ptGrowing.x]; //当前待生长点的灰度值 287 | 288 | if (nGrowLable == 0) //如果标记点还没有被生长 289 | { 290 | nCurValue = Img[ptGrowing.y*W + ptGrowing.x]; 291 | //cout << "生长点:" << ptGrowing << " 灰度值:" << nCurValue << endl; 292 | if (nCurValue == 255) //在阈值范围内则生长 293 | { 294 | result[ptGrowing.y*W + ptGrowing.x] = 255; //标记为白色 295 | Judge[ptGrowing.y*W + ptGrowing.x] = 1; 296 | vcGrowPt.push_back(ptGrowing); //将下一个生长点压入栈中 297 | vcSize.push_back(ptGrowing); 298 | } 299 | } 300 | } 301 | } 302 | //如果生长区域的像素少于20个,则放弃该边缘,蒙版Mask的相关区域重新归0 303 | if (vcSize.size() < 30) 304 | { 305 | for (int i = 0; i < vcSize.size(); i++) 306 | { 307 | Judge[vcSize[i].y*W + vcSize[i].x] = 0; 308 | } 309 | } 310 | vcSize.clear(); 311 | } 312 | else 313 | continue; 314 | } 315 | } 316 | for (int i = 0; i < H; i++) 317 | { 318 | for (int j = 0; j < W; j++) 319 | { 320 | int ij = i*W + j; 321 | if (Judge[ij] == 1) 322 | { 323 | pImg[0][ij] = 255; 324 | } 325 | else 326 | { 327 | pImg[0][ij] = 0; 328 | } 329 | } 330 | } 331 | delete[]Judge; 332 | delete[]data; 333 | delete[]tmpPhaseud; 334 | delete[]tmpPhaselr; 335 | return 0; 336 | } 337 | 338 | //放在一个函数内 339 | int gxbUnpackPhase::gxbGetPhase(unsigned char**img, double *phase) 340 | { 341 | 342 | clock_t start = clock(); 343 | gxbPhaseResult(img, phase); 344 | clock_t end = clock(); 345 | cout << "解相位耗时" << end - start <<"ms"<< endl; 346 | gxbPhaseflitter(phase); 347 | gxbRemoveBg(img[15], img[16], phase); 348 | gxbRegionGrow(img, phase); 349 | 350 | 351 | return 0; 352 | } 353 | //文件写 354 | int gxbUnpackPhase::writemyphase(int index, int w, int h, double *phasel, double *phaser) 355 | { 356 | cout << "正在把相位写入文件" << endl; 357 | clock_t start = clock(); 358 | string filel = "myphase/phaseL.txt"; 359 | string filer = "myphase/phaseR.txt"; 360 | ofstream outl, outr; 361 | outl.open(filel.c_str(), ofstream::out); 362 | outr.open(filer.c_str(), ofstream::out); 363 | if (index != -1) 364 | { 365 | //for (int i = 0; i < h; i++) 366 | { 367 | for (int j = 0; j < w; j++) 368 | { 369 | outl << phasel[index*w + j] < -6 && cp_abPhase1[p + 1] - cp_abPhase1[p] < 0) 391 | { 392 | finalPhase[p] = -4; 393 | cout << 1; 394 | } 395 | } 396 | if (cp_abPhase2[p] < 82 && p < W - 1) 397 | { 398 | Diff2[p] = cp_abPhase2[p + 1] - cp_abPhase2[p]; 399 | if (cp_abPhase2[p + 1] - cp_abPhase2[p] > -6 && cp_abPhase2[p + 1] - cp_abPhase2[p] < 0) 400 | finalPhase[p] = -4; 401 | } 402 | } 403 | 404 | string name1 = "myphase/diff1.txt"; 405 | string name2 = "myphase/diff2.txt"; 406 | ofstream out1, out2; 407 | out1.open(name1.c_str(), ofstream::out); 408 | out2.open(name2.c_str(), ofstream::out); 409 | for (int j = 0; j < W; j++) 410 | { 411 | out1 << Diff1[j] << endl; 412 | out2 << Diff2[j] << endl; 413 | } 414 | return 0; 415 | } 416 | -------------------------------------------------------------------------------- /src/StereoCalib.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | using namespace std; 19 | using namespace cv; 20 | 21 | class StereoCalibrator 22 | { 23 | private: 24 | int Height = 1536; 25 | int Width = 2048; 26 | double aee = 0; 27 | double RMSError = 0; 28 | public: 29 | Mat rmap[2][2]; 30 | Mat cameraMatrix[2], distCoeffs[2]; 31 | Mat R, T, E, F; 32 | Mat R1, R2, P1, P2, Q; 33 | int print_help() 34 | { 35 | cout << 36 | " Given a list of chessboard images, the number of corners (nx, ny)\n" 37 | " on the chessboards, and a flag: useCalibrated for \n" 38 | " calibrated (0) or\n" 39 | " uncalibrated \n" 40 | " (1: use cvStereoCalibrate(), 2: compute fundamental\n" 41 | " matrix separately) stereo. \n" 42 | " Calibrate the cameras and display the\n" 43 | " rectified results along with the computed disparity images. \n" << endl; 44 | cout << "Usage:\n ./stereo_calib -w= -h= -s= \n" << endl; 45 | return 0; 46 | } 47 | 48 | 49 | void 50 | StereoCalib(unsigned char **&ArrayofImg, int ImgNum, Size boardSize, float squareSize, bool displayCorners, bool useCalibrated, bool showRectified) 51 | { 52 | if (ImgNum % 2 != 0) 53 | { 54 | cout << "Error: the image list contains odd (non-even) number of elements\n"; 55 | return; 56 | } 57 | 58 | const int maxScale = 2; 59 | // ARRAY AND VECTOR STORAGE: 60 | //imagePoints数组中的两个元素分别用来记录左右图像的角点 61 | vector > imagePoints[2]; 62 | vector > objectPoints; 63 | Size imageSize; 64 | 65 | ///int i, j, k, nimages = (int)imagelist.size() / 2; 66 | int i, j, k, nimages = ImgNum / 2; 67 | 68 | imagePoints[0].resize(nimages); 69 | imagePoints[1].resize(nimages); 70 | //合法图像列表 71 | ///vector goodImageList; 72 | vector goodImg; 73 | //unsigned char**goodImg = new unsigned char*[ImgNum]; 74 | //for (int p = 0; p < ImgNum; p++) 75 | //{ 76 | // goodImg[p] = new unsigned char[Width*Height]; 77 | //} 78 | //第i幅图像,k=0表示左图像,k=1表示右图像,j表示成功匹配的图像对数 79 | for (i = j = 0; i < nimages; i++) 80 | { 81 | for (k = 0; k < 2; k++) 82 | { 83 | ///const string& filename = imagelist[i * 2 + k]; 84 | //Mat img = imread(filename, 0); 85 | Mat img = Mat(Height, Width, CV_8UC1, ArrayofImg[i * 2 + k]); 86 | //imshow("image", img); 87 | 88 | if (img.empty()) 89 | break; 90 | if (imageSize == Size()) 91 | imageSize = img.size(); 92 | else if (img.size() != imageSize) 93 | { 94 | cout << "The image " << i * 2 + k << " has the size different from the first image size. Skipping the pair\n"; 95 | break; 96 | } 97 | bool found = false; 98 | // 99 | vector& corners = imagePoints[k][j]; 100 | for (int scale = 1; scale <= maxScale; scale++) 101 | { 102 | Mat timg; 103 | if (scale == 1) 104 | timg = img; 105 | else 106 | resize(img, timg, Size(), scale, scale); 107 | found = findChessboardCorners(timg, boardSize, corners); 108 | // CALIB_CB_ADAPTIVE_THRESH | CALIB_CB_NORMALIZE_IMAGE); 109 | if (found) 110 | { 111 | if (scale > 1) 112 | { 113 | Mat cornersMat(corners); 114 | cornersMat *= 1. / scale; 115 | } 116 | break; 117 | } 118 | } 119 | if (displayCorners) 120 | { 121 | ///cout << filename << endl; 122 | Mat cimg, cimg1; 123 | cvtColor(img, cimg, COLOR_GRAY2BGR); 124 | drawChessboardCorners(cimg, boardSize, corners, found); 125 | double sf =1024. / MAX(img.rows, img.cols); 126 | resize(cimg, cimg1, Size(), sf, sf); 127 | if (displayCorners) 128 | { 129 | ///cout << filename << endl; 130 | Mat cimg, cimg1; 131 | cvtColor(img, cimg, COLOR_GRAY2BGR); 132 | drawChessboardCorners(cimg, boardSize, corners, found); 133 | double sf = 1024. / MAX(img.rows, img.cols); 134 | resize(cimg, cimg1, Size(), sf, sf); 135 | namedWindow("corners", 1); 136 | imshow("corners", cimg1); 137 | //destroyWindow("corners"); 138 | char c = (char)waitKey(10); 139 | if (c == 27 || c == 'q' || c == 'Q') //Allow ESC to quit 140 | exit(-1); 141 | } 142 | imshow("corners", cimg1); 143 | char c = (char)waitKey(10); 144 | if (c == 27 || c == 'q' || c == 'Q') //Allow ESC to quit 145 | exit(-1); 146 | } 147 | else 148 | putchar('.'); 149 | if (!found) 150 | break; 151 | cornerSubPix(img, corners, Size(11, 11), Size(-1, -1), 152 | TermCriteria(TermCriteria::COUNT + TermCriteria::EPS, 153 | 30, 0.01)); 154 | } 155 | if (k == 2) 156 | { 157 | goodImg.push_back(i * 2); 158 | goodImg.push_back(i * 2 + 1); 159 | ///goodImageList.push_back(imagelist[i * 2]); 160 | ///goodImageList.push_back(imagelist[i * 2 + 1]); 161 | j++; 162 | } 163 | } 164 | destroyWindow("corners"); 165 | cout << j << " pairs have been successfully detected.\n"; 166 | nimages = j; 167 | if (nimages < 2) 168 | { 169 | cout << "Error: too little pairs to run the calibration\n"; 170 | return; 171 | } 172 | 173 | imagePoints[0].resize(nimages); 174 | imagePoints[1].resize(nimages); 175 | objectPoints.resize(nimages); 176 | //角点世界坐标系赋值 177 | for (i = 0; i < nimages; i++) 178 | { 179 | for (j = 0; j < boardSize.height; j++) 180 | for (k = 0; k < boardSize.width; k++) 181 | objectPoints[i].push_back(Point3f(k*squareSize, j*squareSize, 0)); 182 | } 183 | 184 | cout << "Running stereo calibration ...\n"; 185 | 186 | 187 | 188 | string cameraL_filename = "cameraL.yml"; 189 | string cameraR_filename = "cameraR.yml"; 190 | if (!cameraL_filename.empty()) 191 | { 192 | // reading intrinsic parameters 193 | FileStorage fs(cameraL_filename, FileStorage::READ); 194 | if (!fs.isOpened()) 195 | { 196 | printf("Failed to open file %s\n", cameraL_filename.c_str()); 197 | //return -1; 198 | } 199 | 200 | 201 | fs["cameraL_matrix"] >> cameraMatrix[0]; 202 | fs["distortionL_coefficients"] >> distCoeffs[0]; 203 | } 204 | if (!cameraR_filename.empty()) 205 | { 206 | // reading intrinsic parameters 207 | FileStorage fs(cameraR_filename, FileStorage::READ); 208 | if (!fs.isOpened()) 209 | { 210 | printf("Failed to open file %s\n", cameraR_filename.c_str()); 211 | //return -1; 212 | } 213 | 214 | 215 | fs["cameraR_matrix"] >> cameraMatrix[1]; 216 | fs["distortionR_coefficients"] >> distCoeffs[1]; 217 | } 218 | 219 | 220 | 221 | 222 | cameraMatrix[0] = initCameraMatrix2D(objectPoints, imagePoints[0], imageSize, 0); 223 | cameraMatrix[1] = initCameraMatrix2D(objectPoints, imagePoints[1], imageSize, 0); 224 | //E是本质矩阵,F为基础矩阵 225 | 226 | //发下这个distCoeffs和cameraMatrix居然是空的!!! 227 | 228 | 229 | 230 | 231 | double rms = stereoCalibrate(objectPoints, imagePoints[0], imagePoints[1], 232 | cameraMatrix[0], distCoeffs[0], 233 | cameraMatrix[1], distCoeffs[1], 234 | imageSize, R, T, E, F, 235 | //CALIB_FIX_ASPECT_RATIO + 236 | //CALIB_ZERO_TANGENT_DIST + 237 | CALIB_USE_INTRINSIC_GUESS, 238 | //CALIB_SAME_FOCAL_LENGTH + 239 | //CALIB_RATIONAL_MODEL + 240 | //CALIB_FIX_K3 + CALIB_FIX_K4 + CALIB_FIX_K5, 241 | TermCriteria(TermCriteria::COUNT + TermCriteria::EPS, 100, 1e-5)); 242 | //RMS:均方根值 243 | cout << "done with RMS error=" << rms << endl; 244 | RMSError = rms; 245 | // CALIBRATION QUALITY CHECK 246 | // because the output fundamental matrix implicitly 247 | // includes all the output information, 248 | // we can check the quality of calibration using the 249 | //Epipolar error: m2^t*F*m1=0 250 | double err = 0; 251 | int npoints = 0; 252 | vector lines[2]; 253 | for (i = 0; i < nimages; i++) 254 | { 255 | //npt表示单幅图像中角点的数目 256 | int npt = (int)imagePoints[0][i].size(); 257 | Mat imgpt[2]; 258 | for (k = 0; k < 2; k++) 259 | { 260 | //imgpt[0]表示左图像中第i幅图像的角点矩阵 261 | imgpt[k] = Mat(imagePoints[k][i]); 262 | //对图像中的所有角点进行畸变校正 263 | //undistortPoints(imgpt[k], imgpt[k], cameraMatrix[k], distCoeffs[k], Mat(), cameraMatrix[k]); 264 | //为一副图像中的点计算其在另一幅图像中对应的极线 265 | computeCorrespondEpilines(imgpt[k], k + 1, F, lines[k]); 266 | } 267 | for (j = 0; j < npt; j++) 268 | { 269 | double errij = fabs(imagePoints[0][i][j].x*lines[1][j][0] + 270 | imagePoints[0][i][j].y*lines[1][j][1] + lines[1][j][2]) + 271 | fabs(imagePoints[1][i][j].x*lines[0][j][0] + 272 | imagePoints[1][i][j].y*lines[0][j][1] + lines[0][j][2]); 273 | err += errij; 274 | } 275 | npoints += npt; 276 | } 277 | cout << "average epipolar err = " << err / npoints << endl; 278 | aee = err / npoints; 279 | 280 | 281 | //因为opencv标定不稳定,暂时不考虑畸变 282 | //distCoeffs[0] = Mat::ones(0, 5, CV_32F); 283 | //distCoeffs[1] = Mat::ones(0, 5, CV_32F); 284 | // save intrinsic parameters 285 | FileStorage fs("intrinsics.yml", FileStorage::WRITE); 286 | if (fs.isOpened()) 287 | { 288 | fs << "ML" << cameraMatrix[0] << "DL" << distCoeffs[0] << 289 | "MR" << cameraMatrix[1] << "D" << distCoeffs[1]; 290 | fs.release(); 291 | } 292 | else 293 | cout << "Error: can not save the intrinsic parameters\n"; 294 | 295 | 296 | Rect validRoi[2]; 297 | 298 | 299 | 300 | 301 | stereoRectify(cameraMatrix[0], distCoeffs[0], 302 | cameraMatrix[1], distCoeffs[1], 303 | imageSize, R, T, R1, R2, P1, P2, Q, 304 | CALIB_ZERO_DISPARITY,0.8, imageSize, &validRoi[0], &validRoi[1]); 305 | 306 | fs.open("extrinsics.yml", FileStorage::WRITE); 307 | if (fs.isOpened()) 308 | { 309 | fs << "R" << R << "T" << T << "R1" << R1 << "R2" << R2 << "P1" << P1 << "P2" << P2 << "Q" << Q; 310 | fs.release(); 311 | } 312 | else 313 | cout << "Error: can not save the extrinsic parameters\n"; 314 | 315 | // OpenCV can handle left-right 316 | // or up-down camera arrangements 317 | bool isVerticalStereo = fabs(P2.at(1, 3)) > fabs(P2.at(0, 3)); 318 | 319 | // COMPUTE AND DISPLAY RECTIFICATION 320 | if (!showRectified) 321 | return; 322 | 323 | 324 | // IF BY CALIBRATED (BOUGUET'S METHOD) 325 | if (useCalibrated) 326 | { 327 | // we already computed everything 328 | } 329 | // OR ELSE HARTLEY'S METHOD 330 | else 331 | // use intrinsic parameters of each camera, but 332 | // compute the rectification transformation directly 333 | // from the fundamental matrix 334 | { 335 | vector allimgpt[2]; 336 | for (k = 0; k < 2; k++) 337 | { 338 | for (i = 0; i < nimages; i++) 339 | std::copy(imagePoints[k][i].begin(), imagePoints[k][i].end(), back_inserter(allimgpt[k])); 340 | } 341 | F = findFundamentalMat(Mat(allimgpt[0]), Mat(allimgpt[1]), FM_8POINT, 0, 0); 342 | Mat H1, H2; 343 | stereoRectifyUncalibrated(Mat(allimgpt[0]), Mat(allimgpt[1]), F, imageSize, H1, H2, 3); 344 | 345 | R1 = cameraMatrix[0].inv()*H1*cameraMatrix[0]; 346 | R2 = cameraMatrix[1].inv()*H2*cameraMatrix[1]; 347 | P1 = cameraMatrix[0]; 348 | P2 = cameraMatrix[1]; 349 | } 350 | 351 | //Precompute maps for cv::remap() 352 | initUndistortRectifyMap(cameraMatrix[0], distCoeffs[0], R1, P1, imageSize, CV_16SC2, rmap[0][0], rmap[0][1]); 353 | initUndistortRectifyMap(cameraMatrix[1], distCoeffs[1], R2, P2, imageSize, CV_16SC2, rmap[1][0], rmap[1][1]); 354 | 355 | //for (i = 0; i < nimages; i++) 356 | //{ 357 | // for (k = 0; k < 2; k++) 358 | // { 359 | 360 | 361 | // Mat img = Mat(Height, Width, CV_8UC1, ArrayofImg[i * 2 + k]), rimg, cimg; 362 | // remap(img, rimg, rmap[k][0], rmap[k][1], INTER_LINEAR); 363 | // cvtColor(rimg, cimg, COLOR_GRAY2BGR); 364 | // Rect vroi(cvRound(validRoi[k].x*1), cvRound(validRoi[k].y*1), 365 | // cvRound(validRoi[k].width*1), cvRound(validRoi[k].height*1)); 366 | // rectangle(cimg, vroi, Scalar(0, 0, 255), 3, 8); 367 | // imshow("rimg", rimg); 368 | // imshow("cimg", cimg); 369 | // waitKey(-1); 370 | // } 371 | //} 372 | 373 | 374 | 375 | Mat canvas; 376 | double sf; 377 | int w, h; 378 | if (!isVerticalStereo) 379 | { 380 | sf = 600. / MAX(imageSize.width, imageSize.height); 381 | w = cvRound(imageSize.width*sf); 382 | h = cvRound(imageSize.height*sf); 383 | canvas.create(h, w * 2, CV_8UC3); 384 | } 385 | else 386 | { 387 | sf = 300. / MAX(imageSize.width, imageSize.height); 388 | w = cvRound(imageSize.width*sf); 389 | h = cvRound(imageSize.height*sf); 390 | canvas.create(h * 2, w, CV_8UC3); 391 | } 392 | 393 | for (i = 0; i < nimages; i++) 394 | { 395 | for (k = 0; k < 2; k++) 396 | { 397 | Mat img = Mat(Height, Width, CV_8UC1, ArrayofImg[i * 2 + k]), rimg, cimg; 398 | remap(img, rimg, rmap[k][0], rmap[k][1], INTER_LINEAR); 399 | cvtColor(rimg, cimg, COLOR_GRAY2BGR); 400 | Mat canvasPart = !isVerticalStereo ? canvas(Rect(w*k, 0, w, h)) : canvas(Rect(0, h*k, w, h)); 401 | resize(cimg, canvasPart, canvasPart.size(), 0, 0, INTER_AREA); 402 | if (useCalibrated) 403 | { 404 | Rect vroi(cvRound(validRoi[k].x*sf), cvRound(validRoi[k].y*sf), 405 | cvRound(validRoi[k].width*sf), cvRound(validRoi[k].height*sf)); 406 | rectangle(canvasPart, vroi, Scalar(0, 0, 255), 3, 8); 407 | } 408 | } 409 | 410 | if (!isVerticalStereo) 411 | for (j = 0; j < canvas.rows; j += 16) 412 | line(canvas, Point(0, j), Point(canvas.cols, j), Scalar(0, 255, 0), 1, 8); 413 | else 414 | for (j = 0; j < canvas.cols; j += 16) 415 | line(canvas, Point(j, 0), Point(j, canvas.rows), Scalar(0, 255, 0), 1, 8); 416 | namedWindow("rectified", 1); 417 | imshow("rectified", canvas); 418 | //waitKey(0); 419 | //system("pause"); 420 | char c = (char)waitKey(1000); 421 | if (c == 27 || c == 'q' || c == 'Q') 422 | break; 423 | } 424 | //system("pause"); 425 | destroyWindow("rectified"); 426 | destroyAllWindows(); 427 | } 428 | double getRMSError() 429 | { 430 | return RMSError; 431 | } 432 | double getAee() 433 | { 434 | return aee; 435 | } 436 | }; 437 | -------------------------------------------------------------------------------- /src/demo0316Dlg.cpp: -------------------------------------------------------------------------------- 1 | 2 | // demo0316Dlg.cpp : 实现文件 3 | // 4 | 5 | #include "stdafx.h" 6 | #include "demo0316.h" 7 | #include "demo0316Dlg.h" 8 | #include "afxdialogex.h" 9 | #include "VtkViewer.h" 10 | #include "CvvImage.h" 11 | #include "Camera.h" 12 | #include "StereoCalib.h" 13 | #include "gxbPhaseMatch.h" 14 | #include "gxbUnpackPhase.h" 15 | #include "Projector.h" 16 | #include 17 | using namespace cv; 18 | #ifdef _DEBUG 19 | #define new DEBUG_NEW 20 | #endif 21 | 22 | 23 | // 用于应用程序“关于”菜单项的 CAboutDlg 对话框 24 | 25 | class CAboutDlg : public CDialogEx 26 | { 27 | public: 28 | CAboutDlg(); 29 | 30 | // 对话框数据 31 | #ifdef AFX_DESIGN_TIME 32 | enum { IDD = IDD_ABOUTBOX }; 33 | #endif 34 | 35 | protected: 36 | virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 37 | 38 | // 实现 39 | protected: 40 | DECLARE_MESSAGE_MAP() 41 | }; 42 | 43 | CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX) 44 | { 45 | } 46 | 47 | void CAboutDlg::DoDataExchange(CDataExchange* pDX) 48 | { 49 | CDialogEx::DoDataExchange(pDX); 50 | } 51 | 52 | BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx) 53 | END_MESSAGE_MAP() 54 | 55 | //用于应用程序“相机标定”项的 CCalibDlg 标定对话框 56 | //j为传递图片流的公共下标 57 | static int j = 0; 58 | //IsCalibflag是否标定的标志位,默认为已标定 59 | static bool IsCalibflag = 1; 60 | class CCalibDlg : public CDialogEx 61 | { 62 | public: 63 | int Width = 2048; 64 | int Height = 1536; 65 | int ImgNumforCalib = 23; 66 | int m_NumOfCalib; 67 | unsigned char**ArrayImgforCalib = new unsigned char*[ImgNumforCalib * 2]; 68 | CCalibDlg(); 69 | Mat imgLeft, imgRight; 70 | unsigned char * dataL = new unsigned char[Width*Height * 3]; 71 | unsigned char * dataR = new unsigned char[Width*Height * 3]; 72 | // 对话框数据 73 | #ifdef AFX_DESIGN_TIME 74 | enum { IDD = IDD_DIALOG_CALIB }; 75 | #endif 76 | 77 | protected: 78 | virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 79 | virtual BOOL OnInitDialog(); 80 | // 实现 81 | protected: 82 | DECLARE_MESSAGE_MAP() 83 | public: 84 | void DrawPicToHDC(IplImage*img, UINT ID);//在picControl控件中显示图片 85 | afx_msg void OnBnClickedBtnOpencam(); 86 | afx_msg void OnBnClickedBtnCatch(); 87 | afx_msg void OnBnClickedBtnClosecam(); 88 | afx_msg void OnBnClickedBtnCalib(); 89 | 90 | afx_msg void OnBnClickedBtnSinglecalibleft(); 91 | afx_msg void OnBnClickedBtnSinglecalibright(); 92 | double m_RMS; 93 | double m_AEE; 94 | }; 95 | void CCalibDlg::DrawPicToHDC(IplImage*img, UINT ID) 96 | { 97 | CDC *pDC = GetDlgItem(ID)->GetDC(); 98 | HDC hDC = pDC->GetSafeHdc(); 99 | CRect rect; 100 | GetDlgItem(ID)->GetClientRect(&rect); 101 | CvvImage cimg; 102 | cimg.CopyOf(img); 103 | cimg.DrawToHDC(hDC, &rect); 104 | ReleaseDC(pDC); 105 | } 106 | CCalibDlg::CCalibDlg() : CDialogEx(IDD_DIALOG_CALIB) 107 | , m_NumOfCalib(0) 108 | , m_RMS(0) 109 | , m_AEE(0) 110 | { 111 | 112 | } 113 | 114 | void CCalibDlg::DoDataExchange(CDataExchange* pDX) 115 | { 116 | CDialogEx::DoDataExchange(pDX); 117 | DDX_Text(pDX, IDC_EDIT_CAMNUM, m_NumOfCalib); 118 | DDX_Text(pDX, IDC_EDIT_RMS, m_RMS); 119 | DDX_Text(pDX, IDC_EDIT_AEE, m_AEE); 120 | } 121 | 122 | BOOL CCalibDlg::OnInitDialog() 123 | { 124 | CDialogEx::OnInitDialog(); 125 | 126 | // 将“关于...”菜单项添加到系统菜单中。 127 | 128 | 129 | // 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动 130 | // 执行此操作 131 | 132 | for (int p = 0; p < ImgNumforCalib * 2; p++) 133 | { 134 | ArrayImgforCalib[p] = new unsigned char[Width*Height]; 135 | } 136 | // TODO: 在此添加额外的初始化代码 137 | 138 | return TRUE; // 除非将焦点设置到控件,否则返回 TRUE 139 | } 140 | 141 | BEGIN_MESSAGE_MAP(CCalibDlg, CDialogEx) 142 | ON_WM_PAINT() 143 | ON_BN_CLICKED(IDC_BTN_OPENCAM, &CCalibDlg::OnBnClickedBtnOpencam) 144 | ON_BN_CLICKED(IDC_BTN_CATCH, &CCalibDlg::OnBnClickedBtnCatch) 145 | ON_BN_CLICKED(IDC_BTN_CLOSECAM, &CCalibDlg::OnBnClickedBtnClosecam) 146 | ON_BN_CLICKED(IDC_BTN_CALIB, &CCalibDlg::OnBnClickedBtnCalib) 147 | ON_BN_CLICKED(IDC_BTN_SINGLECALIBLEFT, &CCalibDlg::OnBnClickedBtnSinglecalibleft) 148 | ON_BN_CLICKED(IDC_BTN_SINGLECALIBRIGHT, &CCalibDlg::OnBnClickedBtnSinglecalibright) 149 | END_MESSAGE_MAP() 150 | 151 | //用于应用程序“显示点云”项的 CCCheckCloud 标定对话框 152 | 153 | class CCCheckCloud : public CDialogEx 154 | { 155 | public: 156 | CCCheckCloud(); 157 | 158 | // 对话框数据 159 | #ifdef AFX_DESIGN_TIME 160 | enum { IDD = IDD_DIALOG_CHECK }; 161 | #endif 162 | 163 | protected: 164 | virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 165 | 166 | // 实现 167 | protected: 168 | DECLARE_MESSAGE_MAP() 169 | public: 170 | afx_msg void OnPaint(); 171 | afx_msg void OnBnClickedBtnOpencloud(); 172 | std::vector pointCloud[1]; 173 | int PointSize; 174 | int Editponitsize; 175 | CVtkViewer m_vtk2; 176 | char ln[1000]; 177 | FILE *f; 178 | int n, L; 179 | double d1, d2, d3, d4, d5, d6; 180 | CString Editfilepath; 181 | }; 182 | 183 | CCCheckCloud::CCCheckCloud() : CDialogEx(IDD_DIALOG_CHECK) 184 | { 185 | } 186 | 187 | void CCCheckCloud::DoDataExchange(CDataExchange* pDX) 188 | { 189 | CDialogEx::DoDataExchange(pDX); 190 | //DDX_Text(pDX, IDC_EDITshowsize, Editponitsize); 191 | DDX_Control(pDX, IDC_PIC_CHECK, m_vtk2); 192 | //DDX_Text(pDX, IDC_EDITshowpath, Editfilepath); 193 | } 194 | void CCCheckCloud::OnPaint() 195 | { 196 | CClientDC dc(this); 197 | CRect Rect; 198 | GetClientRect(&Rect); 199 | GetDlgItem(IDC_PIC_CHECK)->GetWindowRect(&Rect); 200 | m_vtk2.ReadPointCloud(pointCloud[0]); 201 | //m_vtk2.MoveWindow(Rect); 202 | m_vtk2.ShowWindow(SW_SHOW); 203 | 204 | if (IsIconic()) 205 | { 206 | CPaintDC dc(this); // 用于绘制的设备上下文 207 | 208 | SendMessage(WM_ICONERASEBKGND, reinterpret_cast(dc.GetSafeHdc()), 0); 209 | 210 | // 使图标在工作区矩形中居中 211 | int cxIcon = GetSystemMetrics(SM_CXICON); 212 | int cyIcon = GetSystemMetrics(SM_CYICON); 213 | CRect rect; 214 | GetClientRect(&rect); 215 | int x = (rect.Width() - cxIcon + 1) / 2; 216 | int y = (rect.Height() - cyIcon + 1) / 2; 217 | 218 | 219 | //m_vtk2.ReadPointCloud(pointCloud[0]); 220 | //m_vtk2.MoveWindow(rect); 221 | //m_vtk2.ShowWindow(SW_SHOW); 222 | 223 | // 绘制图标 224 | } 225 | else 226 | { 227 | CDialogEx::OnPaint(); 228 | } 229 | } 230 | BEGIN_MESSAGE_MAP(CCCheckCloud, CDialogEx) 231 | ON_WM_PAINT() 232 | ON_BN_CLICKED(IDC_BTN_OPENCLOUD, &CCCheckCloud::OnBnClickedBtnOpencloud) 233 | END_MESSAGE_MAP() 234 | // Cdemo0316Dlg 对话框 235 | Cdemo0316Dlg::Cdemo0316Dlg(CWnd* pParent /*=NULL*/) 236 | : CDialogEx(IDD_DEMO0316_DIALOG, pParent) 237 | { 238 | m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); 239 | } 240 | 241 | void Cdemo0316Dlg::DoDataExchange(CDataExchange* pDX) 242 | { 243 | CDialogEx::DoDataExchange(pDX); 244 | } 245 | 246 | BEGIN_MESSAGE_MAP(Cdemo0316Dlg, CDialogEx) 247 | ON_WM_SYSCOMMAND() 248 | ON_WM_PAINT() 249 | ON_WM_QUERYDRAGICON() 250 | ON_BN_CLICKED(IDC_OpenCalibWnd, &Cdemo0316Dlg::OnBnClickedOpencalibwnd) 251 | ON_BN_CLICKED(IDC_BTN_CHECK, &Cdemo0316Dlg::OnBnClickedBtnCheck) 252 | ON_BN_CLICKED(IDC_BTN_SCAN, &Cdemo0316Dlg::OnBnClickedBtnScan) 253 | END_MESSAGE_MAP() 254 | 255 | 256 | // Cdemo0316Dlg 消息处理程序 257 | 258 | BOOL Cdemo0316Dlg::OnInitDialog() 259 | { 260 | CDialogEx::OnInitDialog(); 261 | 262 | // 将“关于...”菜单项添加到系统菜单中。 263 | 264 | // IDM_ABOUTBOX 必须在系统命令范围内。 265 | ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); 266 | ASSERT(IDM_ABOUTBOX < 0xF000); 267 | 268 | CMenu* pSysMenu = GetSystemMenu(FALSE); 269 | if (pSysMenu != NULL) 270 | { 271 | BOOL bNameValid; 272 | CString strAboutMenu; 273 | bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX); 274 | ASSERT(bNameValid); 275 | if (!strAboutMenu.IsEmpty()) 276 | { 277 | pSysMenu->AppendMenu(MF_SEPARATOR); 278 | pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); 279 | } 280 | } 281 | 282 | // 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动 283 | // 执行此操作 284 | SetIcon(m_hIcon, TRUE); // 设置大图标 285 | SetIcon(m_hIcon, FALSE); // 设置小图标 286 | 287 | // TODO: 在此添加额外的初始化代码 288 | 289 | return TRUE; // 除非将焦点设置到控件,否则返回 TRUE 290 | } 291 | 292 | void Cdemo0316Dlg::OnSysCommand(UINT nID, LPARAM lParam) 293 | { 294 | if ((nID & 0xFFF0) == IDM_ABOUTBOX) 295 | { 296 | CAboutDlg dlgAbout; 297 | dlgAbout.DoModal(); 298 | } 299 | else 300 | { 301 | CDialogEx::OnSysCommand(nID, lParam); 302 | } 303 | } 304 | 305 | // 如果向对话框添加最小化按钮,则需要下面的代码 306 | // 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序, 307 | // 这将由框架自动完成。 308 | 309 | void Cdemo0316Dlg::OnPaint() 310 | { 311 | if (IsIconic()) 312 | { 313 | CPaintDC dc(this); // 用于绘制的设备上下文 314 | 315 | SendMessage(WM_ICONERASEBKGND, reinterpret_cast(dc.GetSafeHdc()), 0); 316 | 317 | // 使图标在工作区矩形中居中 318 | int cxIcon = GetSystemMetrics(SM_CXICON); 319 | int cyIcon = GetSystemMetrics(SM_CYICON); 320 | CRect rect; 321 | GetClientRect(&rect); 322 | int x = (rect.Width() - cxIcon + 1) / 2; 323 | int y = (rect.Height() - cyIcon + 1) / 2; 324 | 325 | // 绘制图标 326 | dc.DrawIcon(x, y, m_hIcon); 327 | } 328 | else 329 | { 330 | CDialogEx::OnPaint(); 331 | } 332 | } 333 | 334 | //当用户拖动最小化窗口时系统调用此函数取得光标显示。 335 | HCURSOR Cdemo0316Dlg::OnQueryDragIcon() 336 | { 337 | return static_cast(m_hIcon); 338 | } 339 | //打开标定对话框 340 | void Cdemo0316Dlg::OnBnClickedOpencalibwnd() 341 | { 342 | // TODO: 在此添加控件通知处理程序代码 343 | CCalibDlg ccalibDlg; 344 | ccalibDlg.DoModal(); 345 | } 346 | //打开查看点云对话框 347 | void Cdemo0316Dlg::OnBnClickedBtnCheck() 348 | { 349 | // TODO: 在此添加控件通知处理程序代码 350 | CCCheckCloud cccheckDlg; 351 | cccheckDlg.DoModal(); 352 | } 353 | //打开点云文件 354 | void CCCheckCloud::OnBnClickedBtnOpencloud() 355 | { 356 | // TODO: 在此添加控件通知处理程序代码 357 | pointCloud[0].clear(); 358 | CString filter; 359 | filter = "所有文件(*.*)||"; 360 | CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, filter, NULL); 361 | if (dlg.DoModal() == IDOK) 362 | { 363 | CString filepathname; 364 | filepathname = dlg.GetPathName(); 365 | Editfilepath = filepathname; 366 | MessageBox(Editfilepath); 367 | } 368 | CString fileinfo = Editfilepath; 369 | int len = WideCharToMultiByte(CP_ACP, 0, fileinfo, -1, NULL, 0, NULL, NULL); 370 | char *path = new char[len + 1]; 371 | WideCharToMultiByte(CP_ACP, 0, fileinfo, -1, path, len, NULL, NULL); 372 | f = fopen(path, "r"); 373 | n = 0; 374 | Pointf cloud; 375 | while (1) 376 | { 377 | if (NULL == fgets(ln, 1000, f)) 378 | break; 379 | L = strlen(ln); 380 | if ('\n' == ln[L - 1]) 381 | { 382 | n++; 383 | sscanf(ln, "%lf%lf%lf", &d1, &d2, &d3); 384 | cloud.x = d1; 385 | cloud.y = d2; 386 | cloud.z = d3; 387 | cloud.r = 255; 388 | cloud.g = 255; 389 | cloud.b = 255; 390 | pointCloud[0].push_back(cloud); 391 | //cout << d1 << " " << d2 << " " << d3 << " " << d4 << " " << d5 << " " << d6 << endl; 392 | } 393 | } 394 | fclose(f); 395 | PointSize = pointCloud[0].size(); 396 | SetDlgItemInt(IDC_EDIT_SIZE, pointCloud[0].size()); 397 | //SetDlgItemText(IDC_EDITshowpath, Editfilepath); 398 | UpdateData(); 399 | Invalidate(); 400 | } 401 | 402 | Camera Cam; 403 | StereoCalibrator scb; 404 | //打开相机 405 | void CCalibDlg::OnBnClickedBtnOpencam() 406 | { 407 | // TODO: 在此添加控件通知处理程序代码 408 | Cam.OpenCamera(); 409 | MessageBox(L"相机已打开"); 410 | 411 | } 412 | //拍照 413 | void CCalibDlg::OnBnClickedBtnCatch() 414 | { 415 | 416 | char picNamel[50]; 417 | char picNamer[50]; 418 | if (j < ImgNumforCalib*2 - 1) 419 | { 420 | dataL = CameraGetImageBufferEx(Cam.pCameraHandle[0], &Width, &Height, 2000); 421 | dataR = CameraGetImageBufferEx(Cam.pCameraHandle[1], &Width, &Height, 2000); 422 | imgLeft = Mat(Height, Width, CV_8UC3, dataL); 423 | imgRight = Mat(Height, Width, CV_8UC3, dataR); 424 | cvtColor(imgLeft, imgLeft, CV_RGB2GRAY); 425 | cvtColor(imgRight, imgRight, CV_RGB2GRAY); 426 | IplImage imgTmpL = imgLeft, imgTmpR = imgRight; 427 | IplImage *IplimgLeft = cvCloneImage(&imgTmpL); 428 | IplImage *IplimgRight = cvCloneImage(&imgTmpR); 429 | DrawPicToHDC(IplimgLeft, IDC_PIC_CALIB_LEFT); 430 | DrawPicToHDC(IplimgRight, IDC_PIC_CALIB_RIGHT); 431 | sprintf(picNamel, "./board/left%d.bmp", j/2); 432 | sprintf(picNamer, "./board/right%d.bmp", j/2); 433 | imwrite(picNamel, imgLeft); 434 | imwrite(picNamer, imgRight); 435 | memcpy(ArrayImgforCalib[j], imgLeft.data, Height*Width); 436 | memcpy(ArrayImgforCalib[j + 1], imgRight.data, Height*Width); 437 | j += 2; 438 | m_NumOfCalib = j/2; 439 | SetDlgItemInt(IDC_EDIT_CAMNUM, m_NumOfCalib); 440 | UpdateData(); 441 | } 442 | else 443 | { 444 | MessageBox(L"已达要求抓拍数"); 445 | } 446 | 447 | } 448 | //关闭相机 449 | void CCalibDlg::OnBnClickedBtnClosecam() 450 | { 451 | // TODO: 在此添加控件通知处理程序代码 452 | Cam.CloseCamera(); 453 | MessageBox(L"相机已关闭"); 454 | } 455 | //双目标定 456 | void CCalibDlg::OnBnClickedBtnCalib() 457 | { 458 | // TODO: 在此添加控件通知处理程序代码 459 | 460 | Size boardSize; 461 | 462 | boardSize.width = 10; 463 | boardSize.height = 8; 464 | float squareSize = 10.; 465 | scb.StereoCalib(ArrayImgforCalib, ImgNumforCalib * 2, boardSize, squareSize, true, true, true); 466 | m_AEE = scb.getAee(); 467 | m_RMS = scb.getRMSError(); 468 | IsCalibflag = 0; 469 | UpdateData(FALSE); 470 | Cam.CloseCamera(); 471 | MessageBox(L"标定已完成"); 472 | //while (1) 473 | //{ 474 | // dataL = CameraGetImageBufferEx(Cam.pCameraHandle[0], &Width, &Height, 2000); 475 | // dataR = CameraGetImageBufferEx(Cam.pCameraHandle[1], &Width, &Height, 2000); 476 | // imgLeft = Mat(Height, Width, CV_8UC3, dataL); 477 | // imgRight = Mat(Height, Width, CV_8UC3, dataR); 478 | // cvtColor(imgLeft, imgLeft, CV_RGB2GRAY); 479 | // cvtColor(imgRight, imgRight, CV_RGB2GRAY); 480 | // remap(imgLeft, imgLeft, scb.rmap[0][0], scb.rmap[0][1], INTER_LINEAR); 481 | // remap(imgRight, imgRight, scb.rmap[1][0], scb.rmap[1][1], INTER_LINEAR); 482 | // IplImage imgTmpL = imgLeft, imgTmpR = imgRight; 483 | // IplImage *IplimgLeft = cvCloneImage(&imgTmpL); 484 | // IplImage *IplimgRight = cvCloneImage(&imgTmpR); 485 | // DrawPicToHDC(IplimgLeft, IDC_PIC_CALIB_LEFT); 486 | // DrawPicToHDC(IplimgRight, IDC_PIC_CALIB_RIGHT); 487 | // char c = (char)waitKey(1000); 488 | // if (c == 27 || c == 'q' || c == 'Q') 489 | 490 | // { 491 | // Cam.CloseCamera(); 492 | // MessageBox(L"相机已关闭"); 493 | // break; 494 | // } 495 | //} 496 | } 497 | //扫描 498 | void Cdemo0316Dlg::OnBnClickedBtnScan() 499 | { 500 | // TODO: 在此添加控件通知处理程序代码 501 | Size imageSize = Size(2048, 1536); 502 | Cam.OpenCamera(); 503 | Mat cameraMatrix[2], distCoeffs[2]; 504 | Mat R1, R2, P1, P2, Q, T; 505 | if (IsCalibflag == 1) 506 | { 507 | string intrinsics_filename = "intrinsics.yml"; 508 | string extrinsics_filename = "extrinsics.yml"; 509 | if (!intrinsics_filename.empty()) 510 | { 511 | // reading intrinsic parameters 512 | FileStorage fs(intrinsics_filename, FileStorage::READ); 513 | if (!fs.isOpened()) 514 | { 515 | printf("Failed to open file %s\n", intrinsics_filename.c_str()); 516 | //return -1; 517 | } 518 | 519 | 520 | fs["ML"] >> cameraMatrix[0]; 521 | fs["MR"] >> cameraMatrix[1]; 522 | fs["DL"] >> distCoeffs[0]; 523 | fs["D"] >> distCoeffs[1]; 524 | distCoeffs[0] = Mat::ones(0, 5, CV_32F); 525 | distCoeffs[1] = Mat::ones(0, 5, CV_32F); 526 | } 527 | if (!extrinsics_filename.empty()) 528 | { 529 | // reading intrinsic parameters 530 | FileStorage fs(extrinsics_filename, FileStorage::READ); 531 | if (!fs.isOpened()) 532 | { 533 | printf("Failed to open file %s\n", extrinsics_filename.c_str()); 534 | //return -1; 535 | } 536 | 537 | 538 | fs["R1"] >> R1; 539 | fs["P1"] >> P1; 540 | fs["P2"] >> P2; 541 | fs["R2"] >> R2; 542 | fs["T"] >> T; 543 | fs["Q"] >> Q; 544 | } 545 | initUndistortRectifyMap(cameraMatrix[0], distCoeffs[0], R1, P1, imageSize, CV_16SC2, scb.rmap[0][0], scb.rmap[0][1]); 546 | initUndistortRectifyMap(cameraMatrix[1], distCoeffs[1], R2, P2, imageSize, CV_16SC2, scb.rmap[1][0], scb.rmap[1][1]); 547 | 548 | } 549 | 550 | Projector Pro; 551 | Mat imgLeft, imgRight; 552 | gxbUnpackPhase Unphase; 553 | int Width = 2048; 554 | int Height = 1536; 555 | int proW = 1280; 556 | int proH = 960; 557 | unsigned char *ProImg = new unsigned char[Width*Height]; 558 | unsigned char **pImgL = new unsigned char*[17]; 559 | unsigned char **pImgR = new unsigned char*[17]; 560 | char *picNamel = new char[20]; 561 | char *picNamer = new char[20]; 562 | 563 | for (int i = 0; i < 17; i++) 564 | { 565 | pImgL[i] = new unsigned char[Width*Height]; 566 | pImgR[i] = new unsigned char[Width*Height]; 567 | } 568 | unsigned char*dataForPro = new unsigned char[proW]; 569 | float timeExpose = 0; 570 | int timeFlag = 0; 571 | unsigned char * rgbL = 0; 572 | unsigned char * rgbR = 0; 573 | char* wndname = "Proimg"; 574 | for (int i = 0; i < 17; i++) 575 | { 576 | Pro.gxbCreateProjImg(i + 1, dataForPro, proW); 577 | for (int k = 0; k < proH; k++) 578 | { 579 | for (int j = 0; j < proW; j++) 580 | { 581 | ProImg[k*proW + j] = dataForPro[j]; 582 | } 583 | } 584 | Mat proShow = Mat(proH, proW, CV_8UC1, ProImg); 585 | //imwrite(rasname, proShow); 586 | namedWindow(wndname, WINDOW_AUTOSIZE); 587 | setWindowProperty(wndname, CV_WND_PROP_FULLSCREEN, CV_WINDOW_FULLSCREEN); 588 | moveWindow(wndname, 1920, 0); 589 | imshow(wndname, proShow); 590 | if (i == 0) 591 | waitKey(800); 592 | else 593 | waitKey(800); 594 | dataL = CameraGetImageBufferEx(Cam.pCameraHandle[0], &Width, &Height, 2000); 595 | dataR = CameraGetImageBufferEx(Cam.pCameraHandle[1], &Width, &Height, 2000); 596 | 597 | imgLeft = Mat(Height, Width, CV_8UC3, dataL); 598 | imgRight = Mat(Height, Width, CV_8UC3, dataR); 599 | cvtColor(imgLeft, imgLeft, CV_RGB2GRAY); 600 | cvtColor(imgRight, imgRight, CV_RGB2GRAY); 601 | if(i==1) 602 | imwrite("imgLeft.bmp", imgLeft); 603 | //双目校准 604 | remap(imgLeft, imgLeft, scb.rmap[0][0], scb.rmap[0][1], INTER_LINEAR); 605 | remap(imgRight, imgRight, scb.rmap[1][0], scb.rmap[1][1], INTER_LINEAR); 606 | sprintf(picNamel, "./picture/L%d.bmp", i); 607 | sprintf(picNamer, "./picture/R%d.bmp", i); 608 | imwrite(picNamel, imgLeft); 609 | imwrite(picNamer, imgRight); 610 | memcpy(pImgL[i], imgLeft.data, Height*Width); 611 | memcpy(pImgR[i], imgRight.data, Height*Width); 612 | 613 | //IplImage imgTmpL = imgLeft, imgTmpR = imgRight; 614 | //IplImage *IplimgLeft = cvCloneImage(&imgTmpL); 615 | //IplImage *IplimgRight = cvCloneImage(&imgTmpR); 616 | //IplImage *img_left_Change, *img_right_Change; 617 | //img_left_Change = cvCloneImage(IplimgLeft); 618 | //img_right_Change = cvCloneImage(IplimgRight); 619 | //memcpy_s(pImgL[i], img_left_Change->width * img_left_Change->height, img_left_Change->imageData, img_left_Change->width * img_left_Change->height); 620 | //memcpy_s(pImgR[i], img_right_Change->width * img_right_Change->height, img_right_Change->imageData, img_right_Change->width * img_right_Change->height); 621 | 622 | imgLeft = Mat(Height, Width, CV_8UC1, pImgL[i]); 623 | imgRight = Mat(Height, Width, CV_8UC1, pImgR[i]); 624 | resize(imgLeft, imgLeft, Size(640, 512)); 625 | namedWindow("imgLeft", WINDOW_AUTOSIZE); 626 | setWindowProperty("imgLeft", CV_WND_PROP_FULLSCREEN, CV_WINDOW_FULLSCREEN); 627 | moveWindow("imgLeft", 320, 284); 628 | imshow("imgLeft", imgLeft); 629 | resize(imgRight, imgRight, Size(640, 512)); 630 | namedWindow("imgRight", WINDOW_AUTOSIZE); 631 | setWindowProperty("imgRight", CV_WND_PROP_FULLSCREEN, CV_WINDOW_FULLSCREEN); 632 | moveWindow("imgRight", 960, 284); 633 | imshow("imgRight", imgRight); 634 | waitKey(300); 635 | 636 | } 637 | destroyAllWindows(); 638 | Unphase.gxbInit(Width, Height, 5); 639 | Unphase.gxbGetPhase(pImgL, phaseL); 640 | Unphase.gxbGetPhase(pImgR, phaseR); 641 | Unphase.writemyphase(600, Width, Height, phaseL, phaseR); 642 | gxbPhaseMatch PM; 643 | double *D = new double[Width*Height]; 644 | memset(D, 0, Width*Height); 645 | PM.phaseMatch(Width, Height, phaseL, phaseR, D); 646 | Mat XYZ; 647 | Mat shichaImg = Mat::zeros(Height, Width, CV_8UC1); 648 | 649 | cout << "正在生成视差图..." << endl; 650 | for (int k = 0; k < Height; k++) 651 | { 652 | for (int j = 0; j < Width; j++) 653 | { 654 | //shichaImg.data[k*Width + j] = (int)((D[k*Width + j]) / 2048.0 * 255); 655 | shichaImg.data[k*Width + j] = (int)(D[k*Width + j]); 656 | } 657 | } 658 | //reprojectImageTo3D(shichaImg, XYZ, Q, true, -1); 659 | // 660 | //ofstream out; 661 | //out.open("cloud.txt", ofstream::out); 662 | //for (int y = 10; y < Height; y++) 663 | //{ 664 | // //double qx = q[0][1] * y + q[0][3], qy = q[1][1] * y + q[1][3]; 665 | // //double qz = q[2][1] * y + q[2][3], qw = q[3][1] * y + q[3][3]; 666 | // for (int x = 0; x < Width; x++) 667 | // { 668 | 669 | // 670 | // { 671 | // double Z = XYZ.at(y,x)[2]; 672 | // double X = XYZ.at(y, x)[0]; 673 | // double Y = XYZ.at(y, x)[1];; 674 | // if(Z!=INFINITY&&Y != -INFINITY&&X != -INFINITY&&Z != -INFINITY&&Y != INFINITY&&X != INFINITY) 675 | // out << X << " " << Y << " " << Z << endl; 676 | // } 677 | // } 678 | //} 679 | 680 | 681 | if(IsCalibflag==1) 682 | PM.createPointCloud(Width, Height, D, "cloud.txt",cameraMatrix[0].at(0,0), cameraMatrix[0].at(1, 1), T.at(0, 0),Q); 683 | else 684 | PM.createPointCloud(Width, Height, D, "cloud.txt", scb.cameraMatrix[0].at(0, 0), scb.cameraMatrix[0].at(1, 1), scb.T.at(0, 0),scb.Q); 685 | 686 | resize(shichaImg, shichaImg, Size(Width / 2, Height / 2)); 687 | imshow("shicha", shichaImg); 688 | //imshow("XYZ",XYZ); 689 | imwrite("shicha.bmp", shichaImg); 690 | waitKey(-1); 691 | Cam.CloseCamera(); 692 | } 693 | 694 | //标定左相机 695 | #include "CameraCalibrator.h" 696 | void CCalibDlg::OnBnClickedBtnSinglecalibleft() 697 | { 698 | // TODO: 在此添加控件通知处理程序代码 699 | CameraCalibrator Cc; 700 | unsigned char **ArrayImgforCalib_left = new unsigned char*[ImgNumforCalib]; 701 | for (int p = 0; p < ImgNumforCalib; p++) 702 | { 703 | ArrayImgforCalib_left[p] = new unsigned char[Width*Height]; 704 | } 705 | for (int i = 0; i < ImgNumforCalib*2; i = i + 2) 706 | { 707 | memcpy(ArrayImgforCalib_left[i / 2], ArrayImgforCalib[i],Height*Width); 708 | } 709 | cv::Size boardSize(10, 8); 710 | Cc.addChessboardPoints(ArrayImgforCalib_left, Height, Width, ImgNumforCalib , boardSize); 711 | Cc.calibrate(Size(Height, Width)); 712 | 713 | cv::Mat cameraMatrix = Cc.getCameraMatrix(); 714 | cv::Mat disCoeffs = Cc.getDistCoeffs(); 715 | FileStorage fs("cameraL.yml", FileStorage::WRITE); 716 | if (fs.isOpened()) 717 | { 718 | fs << "cameraL_matrix" << cameraMatrix << "distortionL_coefficients" << disCoeffs; 719 | fs.release(); 720 | } 721 | MessageBox(L"左相机标定完成,结果保存至cameraL.yml"); 722 | } 723 | 724 | //标定右相机 725 | void CCalibDlg::OnBnClickedBtnSinglecalibright() 726 | { 727 | // TODO: 在此添加控件通知处理程序代码 728 | CameraCalibrator Cc; 729 | unsigned char **ArrayImgforCalib_right = new unsigned char*[ImgNumforCalib]; 730 | for (int p = 0; p < ImgNumforCalib; p++) 731 | { 732 | ArrayImgforCalib_right[p] = new unsigned char[Width*Height]; 733 | } 734 | for (int i = 0; i < ImgNumforCalib*2; i = i + 2) 735 | { 736 | memcpy(ArrayImgforCalib_right[i / 2], ArrayImgforCalib[i], Height*Width); 737 | } 738 | cv::Size boardSize(10, 8); 739 | Cc.addChessboardPoints(ArrayImgforCalib_right, Height, Width, ImgNumforCalib, boardSize); 740 | Cc.calibrate(Size(Height, Width)); 741 | 742 | cv::Mat cameraMatrix = Cc.getCameraMatrix(); 743 | cv::Mat disCoeffs = Cc.getDistCoeffs(); 744 | FileStorage fs("cameraR.yml", FileStorage::WRITE); 745 | if (fs.isOpened()) 746 | { 747 | fs << "cameraR_matrix" << cameraMatrix << "distortionR_coefficients" << disCoeffs; 748 | fs.release(); 749 | } 750 | MessageBox(L"右相机标定完成,结果保存至cameraR.yml"); 751 | } 752 | 753 | -------------------------------------------------------------------------------- /src/CameraDefine.H: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #ifndef _CAMERA_DEFINE_H_ 3 | #define _CAMERA_DEFINE_H_ 4 | 5 | #include "CameraStatus.h" 6 | 7 | #define MAX_CROSS_LINE 9 8 | 9 | //相机的句柄类型定义 10 | typedef int CameraHandle; 11 | 12 | 13 | 14 | 15 | //图像查表变换的方式 16 | typedef enum 17 | { 18 | LUTMODE_PARAM_GEN=0,//通过调节参数动态生成LUT表 19 | LUTMODE_PRESET, //使用预设的LUT表 20 | LUTMODE_USER_DEF //使用用户自定义的LUT表 21 | }emSdkLutMode; 22 | 23 | //相机的视频流控制 24 | typedef enum 25 | { 26 | RUNMODE_PLAY=0, //正常预览,捕获到图像就显示。(如果相机处于触发模式,则会等待触发帧的到来) 27 | RUNMODE_PAUSE, //暂停,会暂停相机的图像输出,同时也不会去捕获图像 28 | RUNMODE_STOP //停止相机工作。反初始化后,相机就处于停止模式 29 | }emSdkRunMode; 30 | 31 | //SDK内部显示接口的显示方式 32 | typedef enum 33 | { 34 | DISPLAYMODE_SCALE=0, //缩放显示模式,缩放到显示控件的尺寸 35 | DISPLAYMODE_REAL, //1:1显示模式,当图像尺寸大于显示控件的尺寸时,只显示局部 36 | DISPLAYMODE_2X, //放大2X 37 | DISPLAYMODE_4X, //放大4X 38 | DISPLAYMODE_8X, //放大8X 39 | DISPLAYMODE_16X //放大16X 40 | }emSdkDisplayMode; 41 | 42 | //录像状态 43 | typedef enum 44 | { 45 | RECORD_STOP = 0, //停止 46 | RECORD_START, //录像中 47 | RECORD_PAUSE //暂停 48 | }emSdkRecordMode; 49 | 50 | //图像的镜像操作 51 | typedef enum 52 | { 53 | MIRROR_DIRECTION_HORIZONTAL = 0,//水平镜像 54 | MIRROR_DIRECTION_VERTICAL //垂直镜像 55 | }emSdkMirrorDirection; 56 | 57 | //图像的旋转操作 58 | typedef enum 59 | { 60 | ROTATE_DIRECTION_0 = 0, // 不旋转 61 | ROTATE_DIRECTION_90, // 逆时针90度 62 | ROTATE_DIRECTION_180, // 逆时针180度 63 | ROTATE_DIRECTION_270, // 逆时针270度 64 | }emSdkRotateDirection; 65 | 66 | //相机视频的帧率 67 | typedef enum 68 | { 69 | FRAME_SPEED_LOW = 0, //低速模式 70 | FRAME_SPEED_NORMAL, //普通模式 71 | FRAME_SPEED_HIGH, //高速模式(需要较高的传输带宽,多设备共享传输带宽时会对帧率的稳定性有影响) 72 | FRAME_SPEED_SUPER //超高速模式(需要较高的传输带宽,多设备共享传输带宽时会对帧率的稳定性有影响) 73 | }emSdkFrameSpeed; 74 | 75 | //保存文件的格式类型 76 | typedef enum 77 | { 78 | FILE_JPG = 1,//JPG 79 | FILE_BMP = 2,//BMP 24bit 80 | FILE_RAW = 4,//相机输出的bayer格式文件,对于不支持bayer格式输出相机,无法保存为该格式 81 | FILE_PNG = 8, //PNG 24bit 82 | FILE_BMP_8BIT = 16,//BMP 8bit 83 | FILE_PNG_8BIT = 32, //PNG 8bit 84 | FILE_RAW_16BIT = 64 85 | }emSdkFileType; 86 | 87 | //相机中的图像传感器的工作模式 88 | typedef enum 89 | { 90 | CONTINUATION = 0,//连续采集模式 91 | SOFT_TRIGGER, //软件触发模式,由软件发送指令后,传感器开始采集指定帧数的图像,采集完成后,停止输出 92 | EXTERNAL_TRIGGER //硬件触发模式,当接收到外部信号,传感器开始采集指定帧数的图像,采集完成后,停止输出 93 | } emSdkSnapMode; 94 | 95 | //自动曝光时抗频闪的频闪 96 | typedef enum 97 | { 98 | LIGHT_FREQUENCY_50HZ = 0,//50HZ,一般的灯光都是50HZ 99 | LIGHT_FREQUENCY_60HZ //60HZ,主要是指显示器的 100 | }emSdkLightFrequency; 101 | 102 | //相机的配置参数,分为A,B,C,D 4组进行保存。 103 | typedef enum 104 | { 105 | PARAMETER_TEAM_DEFAULT = 0xff, 106 | PARAMETER_TEAM_A = 0, 107 | PARAMETER_TEAM_B = 1, 108 | PARAMETER_TEAM_C = 2, 109 | PARAMETER_TEAM_D = 3 110 | }emSdkParameterTeam; 111 | 112 | 113 | /*emSdkParameterMode 相机参数加载模式,参数加载分为从文件和从设备加载两种方式 114 | 115 | PARAM_MODE_BY_MODEL:所有同型号的相机共用ABCD四组参数文件。修改 116 | 一台相机的参数文件,会影响到整个同型号的 117 | 相机参数加载。 118 | 119 | PARAM_MODE_BY_NAME:所有设备名相同的相机,共用ABCD四组参数文件。 120 | 默认情况下,当电脑上只接了某型号一台相机时, 121 | 设备名都是一样的,而您希望某一台相机能够加载 122 | 不同的参数文件,则可以通过修改其设备名的方式 123 | 来让其加载指定的参数文件。 124 | 125 | PARAM_MODE_BY_SN:相机按照自己的唯一序列号来加载ABCD四组参数文件, 126 | 序列号在出厂时已经固化在相机内,每台相机的序列号 127 | 都不相同,通过这种方式,每台相机的参数文件都是独立的。 128 | 129 | 您可以根据自己的使用环境,灵活使用以上几种方式加载参数。例如,以 130 | MV-U300为例,您希望多台该型号的相机在您的 电脑上都共用4组参数,那么就 131 | 使用PARAM_MODE_BY_MODEL方式;如果您希望其中某一台或者某几台MV-U300能 132 | 使用自己参数文件而其余的MV-U300又要使用相同的参数文件,那么使用 133 | PARAM_MODE_BY_NAME方式;如果您希望每台MV-U300都使用不同的参数文件,那么 134 | 使用PARAM_MODE_BY_SN方式。 135 | 参数文件存在安装目录的 \Camera\Configs 目录下,以config为后缀名的文件。 136 | */ 137 | typedef enum 138 | { 139 | PARAM_MODE_BY_MODEL = 0, //根据相机型号名从文件中加载参数,例如MV-U300 140 | PARAM_MODE_BY_NAME, //根据设备昵称(tSdkCameraDevInfo.acFriendlyName)从文件中加载参数,例如MV-U300,该昵称可自定义 141 | PARAM_MODE_BY_SN, //根据设备的唯一序列号从文件中加载参数,序列号在出厂时已经写入设备,每台相机拥有不同的序列号。 142 | PARAM_MODE_IN_DEVICE //从设备的固态存储器中加载参数。不是所有的型号都支持从相机中读写参数组,由tSdkCameraCapbility.bParamInDevice决定 143 | }emSdkParameterMode; 144 | 145 | 146 | //SDK生成的相机配置页面掩码值 147 | typedef enum 148 | { 149 | PROP_SHEET_INDEX_EXPOSURE = 0, 150 | PROP_SHEET_INDEX_ISP_COLOR, 151 | PROP_SHEET_INDEX_ISP_LUT, 152 | PROP_SHEET_INDEX_ISP_SHAPE, 153 | PROP_SHEET_INDEX_VIDEO_FORMAT, 154 | PROP_SHEET_INDEX_RESOLUTION, 155 | PROP_SHEET_INDEX_IO_CTRL, 156 | PROP_SHEET_INDEX_TRIGGER_SET, 157 | PROP_SHEET_INDEX_OVERLAY, 158 | PROP_SHEET_INDEX_DEVICE_INFO 159 | }emSdkPropSheetMask; 160 | 161 | //SDK生成的相机配置页面的回调消息类型 162 | typedef enum 163 | { 164 | SHEET_MSG_LOAD_PARAM_DEFAULT = 0, //参数被恢复成默认后,触发该消息 165 | SHEET_MSG_LOAD_PARAM_GROUP, //加载指定参数组,触发该消息 166 | SHEET_MSG_LOAD_PARAM_FROMFILE, //从指定文件加载参数后,触发该消息 167 | SHEET_MSG_SAVE_PARAM_GROUP //当前参数组被保存时,触发该消息 168 | }emSdkPropSheetMsg; 169 | 170 | //可视化选择参考窗口的类型 171 | typedef enum 172 | { 173 | REF_WIN_AUTO_EXPOSURE = 0, 174 | REF_WIN_WHITE_BALANCE, 175 | }emSdkRefWinType; 176 | 177 | //可视化选择参考窗口的类型 178 | typedef enum 179 | { 180 | RES_MODE_PREVIEW = 0, 181 | RES_MODE_SNAPSHOT, 182 | }emSdkResolutionMode; 183 | 184 | //白平衡时色温模式 185 | typedef enum 186 | { 187 | CT_MODE_AUTO = 0, //自动识别色温 188 | CT_MODE_PRESET, //使用指定的预设色温 189 | CT_MODE_USER_DEF //自定义色温(增益和矩阵) 190 | }emSdkClrTmpMode; 191 | 192 | //LUT的颜色通道 193 | typedef enum 194 | { 195 | LUT_CHANNEL_ALL = 0,//R,B,G三通道同时调节 196 | LUT_CHANNEL_RED, //红色通道 197 | LUT_CHANNEL_GREEN, //绿色通道 198 | LUT_CHANNEL_BLUE, //蓝色通道 199 | }emSdkLutChannel; 200 | 201 | //ISP处理单元 202 | typedef enum 203 | { 204 | ISP_PROCESSSOR_PC = 0,//使用PC的软件ISP模块 205 | ISP_PROCESSSOR_DEVICE //使用相机自带的硬件ISP模块 206 | }emSdkIspProcessor; 207 | 208 | //闪光灯信号控制方式 209 | typedef enum 210 | { 211 | STROBE_SYNC_WITH_TRIG_AUTO = 0, //和触发信号同步,触发后,相机进行曝光时,自动生成STROBE信号。此时,有效极性可设置(CameraSetStrobePolarity)。 212 | STROBE_SYNC_WITH_TRIG_MANUAL, //和触发信号同步,触发后,STROBE延时指定的时间后(CameraSetStrobeDelayTime),再持续指定时间的脉冲(CameraSetStrobePulseWidth),有效极性可设置(CameraSetStrobePolarity)。 213 | STROBE_ALWAYS_HIGH, //始终为高,忽略STROBE信号的其他设置 214 | STROBE_ALWAYS_LOW //始终为低,忽略STROBE信号的其他设置 215 | }emStrobeControl; 216 | 217 | //硬件外触发的信号种类 218 | typedef enum 219 | { 220 | EXT_TRIG_LEADING_EDGE = 0, //上升沿触发,默认为该方式 221 | EXT_TRIG_TRAILING_EDGE, //下降沿触发 222 | EXT_TRIG_HIGH_LEVEL, //高电平触发,电平宽度决定曝光时间,仅部分型号的相机支持电平触发方式。 223 | EXT_TRIG_LOW_LEVEL, //低电平触发 224 | EXT_TRIG_DOUBLE_EDGE, //双边沿触发 225 | }emExtTrigSignal; 226 | 227 | //硬件外触发时的快门方式 228 | typedef enum 229 | { 230 | EXT_TRIG_EXP_STANDARD = 0, //标准方式,默认为该方式。 231 | EXT_TRIG_EXP_GRR, //全局复位方式,部分滚动快门的CMOS型号的相机支持该方式,配合外部机械快门,可以达到全局快门的效果,适合拍高速运动的物体 232 | }emExtTrigShutterMode; 233 | 234 | // 清晰度评估算法 235 | typedef enum 236 | { 237 | EVALUATE_DEFINITION_DEVIATION = 0, // 方差法 238 | EVALUATE_DEFINITION_SMD, // 相邻像素灰度方差法 239 | EVALUATE_DEFINITION_GRADIENT, // 梯度统计 240 | EVALUATE_DEFINITION_SOBEL, // Sobel 241 | EVALUATE_DEFINITION_ROBERT, // Robert 242 | EVALUATE_DEFINITION_LAPLACE, // Laplace 243 | 244 | EVALUATE_DEFINITION_ALG_MAX, 245 | }emEvaluateDefinitionAlgorith; 246 | 247 | // 文字输出标志 248 | typedef enum 249 | { 250 | CAMERA_DT_VCENTER = 0x1, // 垂直居中 251 | CAMERA_DT_BOTTOM = 0x2, // 底部对齐 252 | CAMERA_DT_HCENTER = 0x4, // 水平居中 253 | CAMERA_DT_RIGHT = 0x8, // 右对齐 254 | CAMERA_DT_SINGLELINE = 0x10, // 单行显示 255 | CAMERA_DT_ALPHA_BLEND = 0x20, // Alpha混合 256 | CAMERA_DT_ANTI_ALIASING = 0x40, // 抗锯齿 257 | }emCameraDrawTextFlags; 258 | 259 | // GPIO模式 260 | typedef enum 261 | { 262 | IOMODE_TRIG_INPUT = 0, //触发输入 263 | IOMODE_STROBE_OUTPUT, //闪光灯输出 264 | IOMODE_GP_INPUT, //通用型输入 265 | IOMODE_GP_OUTPUT, //通用型输出 266 | IOMODE_PWM_OUTPUT, //PWM型输出 267 | }emCameraGPIOMode; 268 | 269 | // 取图优先级 270 | typedef enum 271 | { 272 | CAMERA_GET_IMAGE_PRIORITY_OLDEST = 0, // 获取缓存中最旧的一帧 273 | CAMERA_GET_IMAGE_PRIORITY_NEWEST, // 获取缓存中最新的一帧(比此帧旧的将全部丢弃) 274 | CAMERA_GET_IMAGE_PRIORITY_NEXT, // 丢弃缓存中的所有帧,并且如果此刻相机正在曝光或传输将会被立即打断,等待接收下一帧(注意:某些型号的相机不支持此功能,对于不支持此功能的相机这个标志相当于CAMERA_GET_IMAGE_PRIORITY_OLDEST) 275 | }emCameraGetImagePriority; 276 | 277 | // 软触发功能标志 278 | typedef enum 279 | { 280 | CAMERA_ST_CLEAR_BUFFER_BEFORE = 0x1, // 在软触发之前先清空相机已缓存的帧 281 | }emCameraSoftTriggerExFlags; 282 | 283 | //相机的设备信息 284 | typedef struct 285 | { 286 | char acProductSeries[32]; // 产品系列 287 | char acProductName[32]; // 产品名称 288 | char acFriendlyName[32]; // 产品昵称,用户可自定义改昵称,保存在相机内,用于区分多个相机同时使用,可以用CameraSetFriendlyName接口改变该昵称,设备重启后生效。 289 | char acLinkName[32]; // 内核符号连接名,内部使用 290 | char acDriverVersion[32]; // 驱动版本 291 | char acSensorType[32]; // sensor类型 292 | char acPortType[32]; // 接口类型 293 | char acSn[32]; // 产品唯一序列号 294 | UINT uInstance; // 该型号相机在该电脑上的实例索引号,用于区分同型号多相机 295 | } tSdkCameraDevInfo; 296 | 297 | 298 | //CameraGetExtTrigCapability函数返回的外触发掩码表 299 | #define EXT_TRIG_MASK_GRR_SHUTTER 1 300 | #define EXT_TRIG_MASK_LEVEL_MODE 2 301 | #define EXT_TRIG_MASK_DOUBLE_EDGE 4 302 | 303 | //tSdkResolutionRange结构体中SKIP、 BIN、RESAMPLE模式的掩码值 304 | #define MASK_2X2_HD (1<<0) //硬件SKIP、BIN、重采样 2X2 305 | #define MASK_3X3_HD (1<<1) 306 | #define MASK_4X4_HD (1<<2) 307 | #define MASK_5X5_HD (1<<3) 308 | #define MASK_6X6_HD (1<<4) 309 | #define MASK_7X7_HD (1<<5) 310 | #define MASK_8X8_HD (1<<6) 311 | #define MASK_9X9_HD (1<<7) 312 | #define MASK_10X10_HD (1<<8) 313 | #define MASK_11X11_HD (1<<9) 314 | #define MASK_12X12_HD (1<<10) 315 | #define MASK_13X13_HD (1<<11) 316 | #define MASK_14X14_HD (1<<12) 317 | #define MASK_15X15_HD (1<<13) 318 | #define MASK_16X16_HD (1<<14) 319 | #define MASK_17X17_HD (1<<15) 320 | #define MASK_2X2_SW (1<<16) //软件SKIP、BIN、重采样 2X2 321 | #define MASK_3X3_SW (1<<17) 322 | #define MASK_4X4_SW (1<<18) 323 | #define MASK_5X5_SW (1<<19) 324 | #define MASK_6X6_SW (1<<20) 325 | #define MASK_7X7_SW (1<<21) 326 | #define MASK_8X8_SW (1<<22) 327 | #define MASK_9X9_SW (1<<23) 328 | #define MASK_10X10_SW (1<<24) 329 | #define MASK_11X11_SW (1<<25) 330 | #define MASK_12X12_SW (1<<26) 331 | #define MASK_13X13_SW (1<<27) 332 | #define MASK_14X14_SW (1<<28) 333 | #define MASK_15X15_SW (1<<29) 334 | #define MASK_16X16_SW (1<<30) 335 | #define MASK_17X17_SW (1<<31) 336 | 337 | //相机的分辨率设定范围,用于构件UI 338 | typedef struct 339 | { 340 | INT iHeightMax; //图像最大高度 341 | INT iHeightMin; //图像最小高度 342 | INT iWidthMax; //图像最大宽度 343 | INT iWidthMin; //图像最小宽度 344 | UINT uSkipModeMask; //SKIP模式掩码,为0,表示不支持SKIP 。bit0为1,表示支持SKIP 2x2 ;bit1为1,表示支持SKIP 3x3.... 345 | UINT uBinSumModeMask; //BIN(求和)模式掩码,为0,表示不支持BIN 。bit0为1,表示支持BIN 2x2 ;bit1为1,表示支持BIN 3x3.... 346 | UINT uBinAverageModeMask; //BIN(求均值)模式掩码,为0,表示不支持BIN 。bit0为1,表示支持BIN 2x2 ;bit1为1,表示支持BIN 3x3.... 347 | UINT uResampleMask; //硬件重采样的掩码 348 | } tSdkResolutionRange; 349 | 350 | 351 | //相机的分辨率描述 352 | typedef struct 353 | { 354 | INT iIndex; // 索引号,[0,N]表示预设的分辨率(N 为预设分辨率的最大个数,一般不超过20),OXFF 表示自定义分辨率(ROI) 355 | char acDescription[32]; // 该分辨率的描述信息。仅预设分辨率时该信息有效。自定义分辨率可忽略该信息 356 | UINT uBinSumMode; // BIN(求和)的模式,范围不能超过tSdkResolutionRange中uBinSumModeMask 357 | UINT uBinAverageMode; // BIN(求均值)的模式,范围不能超过tSdkResolutionRange中uBinAverageModeMask 358 | UINT uSkipMode; // 是否SKIP的尺寸,为0表示禁止SKIP模式,范围不能超过tSdkResolutionRange中uSkipModeMask 359 | UINT uResampleMask; // 硬件重采样的掩码 360 | INT iHOffsetFOV; // 采集视场相对于Sensor最大视场左上角的垂直偏移 361 | INT iVOffsetFOV; // 采集视场相对于Sensor最大视场左上角的水平偏移 362 | INT iWidthFOV; // 采集视场的宽度 363 | INT iHeightFOV; // 采集视场的高度 364 | INT iWidth; // 相机最终输出的图像的宽度 365 | INT iHeight; // 相机最终输出的图像的高度 366 | INT iWidthZoomHd; // 硬件缩放的宽度,不需要进行此操作的分辨率,此变量设置为0. 367 | INT iHeightZoomHd; // 硬件缩放的高度,不需要进行此操作的分辨率,此变量设置为0. 368 | INT iWidthZoomSw; // 软件缩放的宽度,不需要进行此操作的分辨率,此变量设置为0. 369 | INT iHeightZoomSw; // 软件缩放的高度,不需要进行此操作的分辨率,此变量设置为0. 370 | } tSdkImageResolution; 371 | 372 | //相机白平衡色温模式描述信息 373 | typedef struct 374 | { 375 | INT iIndex; // 模式索引号 376 | char acDescription[32]; // 描述信息 377 | } tSdkColorTemperatureDes; 378 | 379 | //相机帧率描述信息 380 | typedef struct 381 | { 382 | INT iIndex; // 帧率索引号,一般0对应于低速模式,1对应于普通模式,2对应于高速模式 383 | char acDescription[32]; // 描述信息 384 | } tSdkFrameSpeed; 385 | 386 | //相机曝光功能范围定义 387 | typedef struct 388 | { 389 | UINT uiTargetMin; //自动曝光亮度目标最小值 390 | UINT uiTargetMax; //自动曝光亮度目标最大值 391 | UINT uiAnalogGainMin; //模拟增益的最小值,单位为fAnalogGainStep中定义 392 | UINT uiAnalogGainMax; //模拟增益的最大值,单位为fAnalogGainStep中定义 393 | float fAnalogGainStep; //模拟增益每增加1,对应的增加的放大倍数。例如,uiAnalogGainMin一般为16,fAnalogGainStep一般为0.125,那么最小放大倍数就是16*0.125 = 2倍 394 | UINT uiExposeTimeMin; //手动模式下,曝光时间的最小值,单位:行。根据CameraGetExposureLineTime可以获得一行对应的时间(微秒),从而得到整帧的曝光时间 395 | UINT uiExposeTimeMax; //手动模式下,曝光时间的最大值,单位:行 396 | } tSdkExpose; 397 | 398 | //触发模式描述 399 | typedef struct 400 | { 401 | INT iIndex; //模式索引号 402 | char acDescription[32]; //该模式的描述信息 403 | } tSdkTrigger; 404 | 405 | //传输分包大小描述(主要是针对网络相机有效) 406 | typedef struct 407 | { 408 | INT iIndex; //分包大小索引号 409 | char acDescription[32]; //对应的描述信息 410 | UINT iPackSize; 411 | } tSdkPackLength; 412 | 413 | //预设的LUT表描述 414 | typedef struct 415 | { 416 | INT iIndex; //编号 417 | char acDescription[32]; //描述信息 418 | } tSdkPresetLut; 419 | 420 | //AE算法描述 421 | typedef struct 422 | { 423 | INT iIndex; //编号 424 | char acDescription[32]; //描述信息 425 | } tSdkAeAlgorithm; 426 | 427 | //RAW转RGB算法描述 428 | typedef struct 429 | { 430 | INT iIndex; //编号 431 | char acDescription[32]; //描述信息 432 | } tSdkBayerDecodeAlgorithm; 433 | 434 | 435 | //帧率统计信息 436 | typedef struct 437 | { 438 | INT iTotal; //当前采集的总帧数(包括错误帧) 439 | INT iCapture; //当前采集的有效帧的数量 440 | INT iLost; //当前丢帧的数量 441 | } tSdkFrameStatistic; 442 | 443 | //相机输出的图像数据格式 444 | typedef struct 445 | { 446 | INT iIndex; //格式种类编号 447 | char acDescription[32]; //描述信息 448 | UINT iMediaType; //对应的图像格式编码,如CAMERA_MEDIA_TYPE_BAYGR8,在本文件中有定义。 449 | } tSdkMediaType; 450 | 451 | //伽马的设定范围 452 | typedef struct 453 | { 454 | INT iMin; //最小值 455 | INT iMax; //最大值 456 | } tGammaRange; 457 | 458 | //对比度的设定范围 459 | typedef struct 460 | { 461 | INT iMin; //最小值 462 | INT iMax; //最大值 463 | } tContrastRange; 464 | 465 | //RGB三通道数字增益的设定范围 466 | typedef struct 467 | { 468 | INT iRGainMin; //红色增益的最小值 469 | INT iRGainMax; //红色增益的最大值 470 | INT iGGainMin; //绿色增益的最小值 471 | INT iGGainMax; //绿色增益的最大值 472 | INT iBGainMin; //蓝色增益的最小值 473 | INT iBGainMax; //蓝色增益的最大值 474 | } tRgbGainRange; 475 | 476 | //饱和度设定的范围 477 | typedef struct 478 | { 479 | INT iMin; //最小值 480 | INT iMax; //最大值 481 | } tSaturationRange; 482 | 483 | //锐化的设定范围 484 | typedef struct 485 | { 486 | INT iMin; //最小值 487 | INT iMax; //最大值 488 | } tSharpnessRange; 489 | 490 | //ISP模块的使能信息 491 | typedef struct 492 | { 493 | BOOL bMonoSensor; //表示该型号相机是否为黑白相机,如果是黑白相机,则颜色相关的功能都无法调节 494 | BOOL bWbOnce; //表示该型号相机是否支持手动白平衡功能 495 | BOOL bAutoWb; //表示该型号相机是否支持自动白平衡功能 496 | BOOL bAutoExposure; //表示该型号相机是否支持自动曝光功能 497 | BOOL bManualExposure; //表示该型号相机是否支持手动曝光功能 498 | BOOL bAntiFlick; //表示该型号相机是否支持抗频闪功能 499 | BOOL bDeviceIsp; //表示该型号相机是否支持硬件ISP功能 500 | BOOL bForceUseDeviceIsp;//bDeviceIsp和bForceUseDeviceIsp同时为TRUE时,表示强制只用硬件ISP,不可取消。 501 | BOOL bZoomHD; //相机硬件是否支持图像缩放输出(只能是缩小)。 502 | } tSdkIspCapacity; 503 | 504 | /* 定义整合的设备描述信息,这些信息可以用于动态构建UI */ 505 | typedef struct 506 | { 507 | 508 | tSdkTrigger *pTriggerDesc; // 触发模式 509 | INT iTriggerDesc; // 触发模式的个数,即pTriggerDesc数组的大小 510 | 511 | tSdkImageResolution *pImageSizeDesc;// 预设分辨率选择 512 | INT iImageSizeDesc; // 预设分辨率的个数,即pImageSizeDesc数组的大小 513 | 514 | tSdkColorTemperatureDes *pClrTempDesc;// 预设色温模式,用于白平衡 515 | INT iClrTempDesc; 516 | 517 | tSdkMediaType *pMediaTypeDesc; // 相机输出图像格式 518 | INT iMediaTypdeDesc; // 相机输出图像格式的种类个数,即pMediaTypeDesc数组的大小。 519 | 520 | tSdkFrameSpeed *pFrameSpeedDesc; // 可调节帧速类型,对应界面上普通 高速 和超级三种速度设置 521 | INT iFrameSpeedDesc; // 可调节帧速类型的个数,即pFrameSpeedDesc数组的大小。 522 | 523 | tSdkPackLength *pPackLenDesc; // 传输包长度,一般用于网络设备 524 | INT iPackLenDesc; // 可供选择的传输分包长度的个数,即pPackLenDesc数组的大小。 525 | 526 | INT iOutputIoCounts; // 可编程输出IO的个数 527 | INT iInputIoCounts; // 可编程输入IO的个数 528 | 529 | tSdkPresetLut *pPresetLutDesc; // 相机预设的LUT表 530 | INT iPresetLut; // 相机预设的LUT表的个数,即pPresetLutDesc数组的大小 531 | 532 | INT iUserDataMaxLen; // 指示该相机中用于保存用户数据区的最大长度。为0表示无。 533 | BOOL bParamInDevice; // 指示该设备是否支持从设备中读写参数组。1为支持,0不支持。 534 | 535 | tSdkAeAlgorithm *pAeAlmSwDesc; // 软件自动曝光算法描述 536 | int iAeAlmSwDesc; // 软件自动曝光算法个数 537 | 538 | tSdkAeAlgorithm *pAeAlmHdDesc; // 硬件自动曝光算法描述,为NULL表示不支持硬件自动曝光 539 | int iAeAlmHdDesc; // 硬件自动曝光算法个数,为0表示不支持硬件自动曝光 540 | 541 | tSdkBayerDecodeAlgorithm *pBayerDecAlmSwDesc; // 软件Bayer转换为RGB数据的算法描述 542 | int iBayerDecAlmSwDesc; // 软件Bayer转换为RGB数据的算法个数 543 | 544 | tSdkBayerDecodeAlgorithm *pBayerDecAlmHdDesc; // 硬件Bayer转换为RGB数据的算法描述,为NULL表示不支持 545 | int iBayerDecAlmHdDesc; // 硬件Bayer转换为RGB数据的算法个数,为0表示不支持 546 | 547 | /* 图像参数的调节范围定义,用于动态构建UI*/ 548 | tSdkExpose sExposeDesc; // 曝光的范围值 549 | tSdkResolutionRange sResolutionRange; // 分辨率范围描述 550 | tRgbGainRange sRgbGainRange; // 图像数字增益范围描述 551 | tSaturationRange sSaturationRange; // 饱和度范围描述 552 | tGammaRange sGammaRange; // 伽马范围描述 553 | tContrastRange sContrastRange; // 对比度范围描述 554 | tSharpnessRange sSharpnessRange; // 锐化范围描述 555 | tSdkIspCapacity sIspCapacity; // ISP能力描述 556 | 557 | 558 | } tSdkCameraCapbility; 559 | 560 | 561 | //图像帧头信息 562 | typedef struct 563 | { 564 | UINT uiMediaType; // 图像格式,Image Format 565 | UINT uBytes; // 图像数据字节数,Total bytes 566 | INT iWidth; // 图像的宽度,调用图像处理函数后,该变量可能被动态修改,来指示处理后的图像尺寸 567 | INT iHeight; // 图像的高度,调用图像处理函数后,该变量可能被动态修改,来指示处理后的图像尺寸 568 | INT iWidthZoomSw; // 软件缩放的宽度,不需要进行软件裁剪的图像,此变量设置为0. 569 | INT iHeightZoomSw; // 软件缩放的高度,不需要进行软件裁剪的图像,此变量设置为0. 570 | BOOL bIsTrigger; // 指示是否为触发帧 is trigger 571 | UINT uiTimeStamp; // 该帧的采集时间,单位0.1毫秒 572 | UINT uiExpTime; // 当前图像的曝光值,单位为微秒us 573 | float fAnalogGain; // 当前图像的模拟增益倍数 574 | INT iGamma; // 该帧图像的伽马设定值,仅当LUT模式为动态参数生成时有效,其余模式下为-1 575 | INT iContrast; // 该帧图像的对比度设定值,仅当LUT模式为动态参数生成时有效,其余模式下为-1 576 | INT iSaturation; // 该帧图像的饱和度设定值,对于黑白相机无意义,为0 577 | float fRgain; // 该帧图像处理的红色数字增益倍数,对于黑白相机无意义,为1 578 | float fGgain; // 该帧图像处理的绿色数字增益倍数,对于黑白相机无意义,为1 579 | float fBgain; // 该帧图像处理的蓝色数字增益倍数,对于黑白相机无意义,为1 580 | }tSdkFrameHead; 581 | 582 | //图像帧描述 583 | typedef struct sCameraFrame 584 | { 585 | tSdkFrameHead head; //帧头 586 | BYTE * pBuffer; //数据区 587 | }tSdkFrame; 588 | 589 | //图像捕获的回调函数定义 590 | typedef void (WINAPI* CAMERA_SNAP_PROC)(CameraHandle hCamera, BYTE *pFrameBuffer, tSdkFrameHead* pFrameHead,PVOID pContext); 591 | 592 | //SDK生成的相机配置页面的消息回调函数定义 593 | typedef void (WINAPI* CAMERA_PAGE_MSG_PROC)(CameraHandle hCamera,UINT MSG,UINT uParam,PVOID pContext); 594 | 595 | 596 | ////////////////////////////////////////////////////////////////////////// 597 | // Grabber 相关 598 | 599 | // Grabber统计信息 600 | typedef struct 601 | { 602 | int Width, Height; // 帧图像大小 603 | int Disp; // 显示帧数量 604 | int Capture; // 采集的有效帧的数量 605 | int Lost; // 丢帧的数量 606 | int Error; // 错帧的数量 607 | float DispFps; // 显示帧率 608 | float CapFps; // 捕获帧率 609 | }tSdkGrabberStat; 610 | 611 | // 图像捕获的回调函数定义 612 | typedef void (__stdcall *pfnCameraGrabberFrameCallback)( 613 | void* Grabber, 614 | BYTE *pFrameBuffer, 615 | tSdkFrameHead* pFrameHead, 616 | void* Context); 617 | 618 | // 帧监听函数定义 619 | typedef int (__stdcall *pfnCameraGrabberFrameListener)( 620 | void* Grabber, 621 | int Phase, 622 | BYTE *pFrameBuffer, 623 | tSdkFrameHead* pFrameHead, 624 | void* Context); 625 | 626 | // 异步抓图的回调函数定义 627 | typedef void (__stdcall *pfnCameraGrabberSaveImageComplete)( 628 | void* Grabber, 629 | void* Image, // 需要调用CameraImage_Destroy释放 630 | CameraSdkStatus Status, 631 | void* Context 632 | ); 633 | 634 | 635 | //----------------------------IMAGE FORMAT DEFINE------------------------------------ 636 | //----------------------------图像格式定义------------------------------------------- 637 | #define CAMERA_MEDIA_TYPE_MONO 0x01000000 638 | #define CAMERA_MEDIA_TYPE_RGB 0x02000000 639 | #define CAMERA_MEDIA_TYPE_COLOR 0x02000000 640 | #define CAMERA_MEDIA_TYPE_CUSTOM 0x80000000 641 | #define CAMERA_MEDIA_TYPE_COLOR_MASK 0xFF000000 642 | #define CAMERA_MEDIA_TYPE_OCCUPY1BIT 0x00010000 643 | #define CAMERA_MEDIA_TYPE_OCCUPY2BIT 0x00020000 644 | #define CAMERA_MEDIA_TYPE_OCCUPY4BIT 0x00040000 645 | #define CAMERA_MEDIA_TYPE_OCCUPY8BIT 0x00080000 646 | #define CAMERA_MEDIA_TYPE_OCCUPY10BIT 0x000A0000 647 | #define CAMERA_MEDIA_TYPE_OCCUPY12BIT 0x000C0000 648 | #define CAMERA_MEDIA_TYPE_OCCUPY16BIT 0x00100000 649 | #define CAMERA_MEDIA_TYPE_OCCUPY24BIT 0x00180000 650 | #define CAMERA_MEDIA_TYPE_OCCUPY32BIT 0x00200000 651 | #define CAMERA_MEDIA_TYPE_OCCUPY36BIT 0x00240000 652 | #define CAMERA_MEDIA_TYPE_OCCUPY48BIT 0x00300000 653 | #define CAMERA_MEDIA_TYPE_OCCUPY64BIT 0x00400000 654 | 655 | #define CAMERA_MEDIA_TYPE_EFFECTIVE_PIXEL_SIZE_MASK 0x00FF0000 656 | #define CAMERA_MEDIA_TYPE_EFFECTIVE_PIXEL_SIZE_SHIFT 16 657 | 658 | #define CAMERA_MEDIA_TYPE_PIXEL_SIZE(type) (((type) & CAMERA_MEDIA_TYPE_EFFECTIVE_PIXEL_SIZE_MASK) >> CAMERA_MEDIA_TYPE_EFFECTIVE_PIXEL_SIZE_SHIFT) 659 | 660 | 661 | #define CAMERA_MEDIA_TYPE_ID_MASK 0x0000FFFF 662 | #define CAMERA_MEDIA_TYPE_COUNT 0x46 663 | 664 | /*mono*/ 665 | #define CAMERA_MEDIA_TYPE_MONO1P (CAMERA_MEDIA_TYPE_MONO | CAMERA_MEDIA_TYPE_OCCUPY1BIT | 0x0037) 666 | #define CAMERA_MEDIA_TYPE_MONO2P (CAMERA_MEDIA_TYPE_MONO | CAMERA_MEDIA_TYPE_OCCUPY2BIT | 0x0038) 667 | #define CAMERA_MEDIA_TYPE_MONO4P (CAMERA_MEDIA_TYPE_MONO | CAMERA_MEDIA_TYPE_OCCUPY4BIT | 0x0039) 668 | #define CAMERA_MEDIA_TYPE_MONO8 (CAMERA_MEDIA_TYPE_MONO | CAMERA_MEDIA_TYPE_OCCUPY8BIT | 0x0001) 669 | #define CAMERA_MEDIA_TYPE_MONO8S (CAMERA_MEDIA_TYPE_MONO | CAMERA_MEDIA_TYPE_OCCUPY8BIT | 0x0002) 670 | #define CAMERA_MEDIA_TYPE_MONO10 (CAMERA_MEDIA_TYPE_MONO | CAMERA_MEDIA_TYPE_OCCUPY16BIT | 0x0003) 671 | #define CAMERA_MEDIA_TYPE_MONO10_PACKED (CAMERA_MEDIA_TYPE_MONO | CAMERA_MEDIA_TYPE_OCCUPY12BIT | 0x0004) 672 | #define CAMERA_MEDIA_TYPE_MONO12 (CAMERA_MEDIA_TYPE_MONO | CAMERA_MEDIA_TYPE_OCCUPY16BIT | 0x0005) 673 | #define CAMERA_MEDIA_TYPE_MONO12_PACKED (CAMERA_MEDIA_TYPE_MONO | CAMERA_MEDIA_TYPE_OCCUPY12BIT | 0x0006) 674 | #define CAMERA_MEDIA_TYPE_MONO14 (CAMERA_MEDIA_TYPE_MONO | CAMERA_MEDIA_TYPE_OCCUPY16BIT | 0x0025) 675 | #define CAMERA_MEDIA_TYPE_MONO16 (CAMERA_MEDIA_TYPE_MONO | CAMERA_MEDIA_TYPE_OCCUPY16BIT | 0x0007) 676 | 677 | /*Bayer */ 678 | #define CAMERA_MEDIA_TYPE_BAYGR8 (CAMERA_MEDIA_TYPE_MONO | CAMERA_MEDIA_TYPE_OCCUPY8BIT | 0x0008) 679 | #define CAMERA_MEDIA_TYPE_BAYRG8 (CAMERA_MEDIA_TYPE_MONO | CAMERA_MEDIA_TYPE_OCCUPY8BIT | 0x0009) 680 | #define CAMERA_MEDIA_TYPE_BAYGB8 (CAMERA_MEDIA_TYPE_MONO | CAMERA_MEDIA_TYPE_OCCUPY8BIT | 0x000A) 681 | #define CAMERA_MEDIA_TYPE_BAYBG8 (CAMERA_MEDIA_TYPE_MONO | CAMERA_MEDIA_TYPE_OCCUPY8BIT | 0x000B) 682 | 683 | #define CAMERA_MEDIA_TYPE_BAYGR10_MIPI (CAMERA_MEDIA_TYPE_MONO | CAMERA_MEDIA_TYPE_OCCUPY10BIT | 0x0026) 684 | #define CAMERA_MEDIA_TYPE_BAYRG10_MIPI (CAMERA_MEDIA_TYPE_MONO | CAMERA_MEDIA_TYPE_OCCUPY10BIT | 0x0027) 685 | #define CAMERA_MEDIA_TYPE_BAYGB10_MIPI (CAMERA_MEDIA_TYPE_MONO | CAMERA_MEDIA_TYPE_OCCUPY10BIT | 0x0028) 686 | #define CAMERA_MEDIA_TYPE_BAYBG10_MIPI (CAMERA_MEDIA_TYPE_MONO | CAMERA_MEDIA_TYPE_OCCUPY10BIT | 0x0029) 687 | 688 | 689 | #define CAMERA_MEDIA_TYPE_BAYGR10 (CAMERA_MEDIA_TYPE_MONO | CAMERA_MEDIA_TYPE_OCCUPY16BIT | 0x000C) 690 | #define CAMERA_MEDIA_TYPE_BAYRG10 (CAMERA_MEDIA_TYPE_MONO | CAMERA_MEDIA_TYPE_OCCUPY16BIT | 0x000D) 691 | #define CAMERA_MEDIA_TYPE_BAYGB10 (CAMERA_MEDIA_TYPE_MONO | CAMERA_MEDIA_TYPE_OCCUPY16BIT | 0x000E) 692 | #define CAMERA_MEDIA_TYPE_BAYBG10 (CAMERA_MEDIA_TYPE_MONO | CAMERA_MEDIA_TYPE_OCCUPY16BIT | 0x000F) 693 | 694 | #define CAMERA_MEDIA_TYPE_BAYGR12 (CAMERA_MEDIA_TYPE_MONO | CAMERA_MEDIA_TYPE_OCCUPY16BIT | 0x0010) 695 | #define CAMERA_MEDIA_TYPE_BAYRG12 (CAMERA_MEDIA_TYPE_MONO | CAMERA_MEDIA_TYPE_OCCUPY16BIT | 0x0011) 696 | #define CAMERA_MEDIA_TYPE_BAYGB12 (CAMERA_MEDIA_TYPE_MONO | CAMERA_MEDIA_TYPE_OCCUPY16BIT | 0x0012) 697 | #define CAMERA_MEDIA_TYPE_BAYBG12 (CAMERA_MEDIA_TYPE_MONO | CAMERA_MEDIA_TYPE_OCCUPY16BIT | 0x0013) 698 | 699 | 700 | #define CAMERA_MEDIA_TYPE_BAYGR10_PACKED (CAMERA_MEDIA_TYPE_MONO | CAMERA_MEDIA_TYPE_OCCUPY12BIT | 0x0026) 701 | #define CAMERA_MEDIA_TYPE_BAYRG10_PACKED (CAMERA_MEDIA_TYPE_MONO | CAMERA_MEDIA_TYPE_OCCUPY12BIT | 0x0027) 702 | #define CAMERA_MEDIA_TYPE_BAYGB10_PACKED (CAMERA_MEDIA_TYPE_MONO | CAMERA_MEDIA_TYPE_OCCUPY12BIT | 0x0028) 703 | #define CAMERA_MEDIA_TYPE_BAYBG10_PACKED (CAMERA_MEDIA_TYPE_MONO | CAMERA_MEDIA_TYPE_OCCUPY12BIT | 0x0029) 704 | 705 | #define CAMERA_MEDIA_TYPE_BAYGR12_PACKED (CAMERA_MEDIA_TYPE_MONO | CAMERA_MEDIA_TYPE_OCCUPY12BIT | 0x002A) 706 | #define CAMERA_MEDIA_TYPE_BAYRG12_PACKED (CAMERA_MEDIA_TYPE_MONO | CAMERA_MEDIA_TYPE_OCCUPY12BIT | 0x002B) 707 | #define CAMERA_MEDIA_TYPE_BAYGB12_PACKED (CAMERA_MEDIA_TYPE_MONO | CAMERA_MEDIA_TYPE_OCCUPY12BIT | 0x002C) 708 | #define CAMERA_MEDIA_TYPE_BAYBG12_PACKED (CAMERA_MEDIA_TYPE_MONO | CAMERA_MEDIA_TYPE_OCCUPY12BIT | 0x002D) 709 | 710 | #define CAMERA_MEDIA_TYPE_BAYGR16 (CAMERA_MEDIA_TYPE_MONO | CAMERA_MEDIA_TYPE_OCCUPY16BIT | 0x002E) 711 | #define CAMERA_MEDIA_TYPE_BAYRG16 (CAMERA_MEDIA_TYPE_MONO | CAMERA_MEDIA_TYPE_OCCUPY16BIT | 0x002F) 712 | #define CAMERA_MEDIA_TYPE_BAYGB16 (CAMERA_MEDIA_TYPE_MONO | CAMERA_MEDIA_TYPE_OCCUPY16BIT | 0x0030) 713 | #define CAMERA_MEDIA_TYPE_BAYBG16 (CAMERA_MEDIA_TYPE_MONO | CAMERA_MEDIA_TYPE_OCCUPY16BIT | 0x0031) 714 | 715 | /*RGB */ 716 | #define CAMERA_MEDIA_TYPE_RGB8 (CAMERA_MEDIA_TYPE_COLOR | CAMERA_MEDIA_TYPE_OCCUPY24BIT | 0x0014) 717 | #define CAMERA_MEDIA_TYPE_BGR8 (CAMERA_MEDIA_TYPE_COLOR | CAMERA_MEDIA_TYPE_OCCUPY24BIT | 0x0015) 718 | #define CAMERA_MEDIA_TYPE_RGBA8 (CAMERA_MEDIA_TYPE_COLOR | CAMERA_MEDIA_TYPE_OCCUPY32BIT | 0x0016) 719 | #define CAMERA_MEDIA_TYPE_BGRA8 (CAMERA_MEDIA_TYPE_COLOR | CAMERA_MEDIA_TYPE_OCCUPY32BIT | 0x0017) 720 | #define CAMERA_MEDIA_TYPE_RGB10 (CAMERA_MEDIA_TYPE_COLOR | CAMERA_MEDIA_TYPE_OCCUPY48BIT | 0x0018) 721 | #define CAMERA_MEDIA_TYPE_BGR10 (CAMERA_MEDIA_TYPE_COLOR | CAMERA_MEDIA_TYPE_OCCUPY48BIT | 0x0019) 722 | #define CAMERA_MEDIA_TYPE_RGB12 (CAMERA_MEDIA_TYPE_COLOR | CAMERA_MEDIA_TYPE_OCCUPY48BIT | 0x001A) 723 | #define CAMERA_MEDIA_TYPE_BGR12 (CAMERA_MEDIA_TYPE_COLOR | CAMERA_MEDIA_TYPE_OCCUPY48BIT | 0x001B) 724 | #define CAMERA_MEDIA_TYPE_RGB16 (CAMERA_MEDIA_TYPE_COLOR | CAMERA_MEDIA_TYPE_OCCUPY48BIT | 0x0033) 725 | #define CAMERA_MEDIA_TYPE_BGR16 (CAMERA_MEDIA_TYPE_COLOR | CAMERA_MEDIA_TYPE_OCCUPY48BIT | 0x004B) 726 | #define CAMERA_MEDIA_TYPE_RGBA16 (CAMERA_MEDIA_TYPE_COLOR | CAMERA_MEDIA_TYPE_OCCUPY64BIT | 0x0064) 727 | #define CAMERA_MEDIA_TYPE_BGRA16 (CAMERA_MEDIA_TYPE_COLOR | CAMERA_MEDIA_TYPE_OCCUPY64BIT | 0x0051) 728 | #define CAMERA_MEDIA_TYPE_RGB10V1_PACKED (CAMERA_MEDIA_TYPE_COLOR | CAMERA_MEDIA_TYPE_OCCUPY32BIT | 0x001C) 729 | #define CAMERA_MEDIA_TYPE_RGB10P32 (CAMERA_MEDIA_TYPE_COLOR | CAMERA_MEDIA_TYPE_OCCUPY32BIT | 0x001D) 730 | #define CAMERA_MEDIA_TYPE_RGB12V1_PACKED (CAMERA_MEDIA_TYPE_COLOR | CAMERA_MEDIA_TYPE_OCCUPY36BIT | 0X0034) 731 | #define CAMERA_MEDIA_TYPE_RGB565P (CAMERA_MEDIA_TYPE_COLOR | CAMERA_MEDIA_TYPE_OCCUPY16BIT | 0x0035) 732 | #define CAMERA_MEDIA_TYPE_BGR565P (CAMERA_MEDIA_TYPE_COLOR | CAMERA_MEDIA_TYPE_OCCUPY16BIT | 0X0036) 733 | 734 | /*YUV and YCbCr*/ 735 | #define CAMERA_MEDIA_TYPE_YUV411_8_UYYVYY (CAMERA_MEDIA_TYPE_COLOR | CAMERA_MEDIA_TYPE_OCCUPY12BIT | 0x001E) 736 | #define CAMERA_MEDIA_TYPE_YUV422_8_UYVY (CAMERA_MEDIA_TYPE_COLOR | CAMERA_MEDIA_TYPE_OCCUPY16BIT | 0x001F) 737 | #define CAMERA_MEDIA_TYPE_YUV422_8 (CAMERA_MEDIA_TYPE_COLOR | CAMERA_MEDIA_TYPE_OCCUPY16BIT | 0x0032) 738 | #define CAMERA_MEDIA_TYPE_YUV8_UYV (CAMERA_MEDIA_TYPE_COLOR | CAMERA_MEDIA_TYPE_OCCUPY24BIT | 0x0020) 739 | #define CAMERA_MEDIA_TYPE_YCBCR8_CBYCR (CAMERA_MEDIA_TYPE_COLOR | CAMERA_MEDIA_TYPE_OCCUPY24BIT | 0x003A) 740 | //CAMERA_MEDIA_TYPE_YCBCR422_8 : YYYYCbCrCbCr 741 | #define CAMERA_MEDIA_TYPE_YCBCR422_8 (CAMERA_MEDIA_TYPE_COLOR | CAMERA_MEDIA_TYPE_OCCUPY16BIT | 0x003B) 742 | #define CAMERA_MEDIA_TYPE_YCBCR422_8_CBYCRY (CAMERA_MEDIA_TYPE_COLOR | CAMERA_MEDIA_TYPE_OCCUPY16BIT | 0x0043) 743 | #define CAMERA_MEDIA_TYPE_YCBCR411_8_CBYYCRYY (CAMERA_MEDIA_TYPE_COLOR | CAMERA_MEDIA_TYPE_OCCUPY12BIT | 0x003C) 744 | #define CAMERA_MEDIA_TYPE_YCBCR601_8_CBYCR (CAMERA_MEDIA_TYPE_COLOR | CAMERA_MEDIA_TYPE_OCCUPY24BIT | 0x003D) 745 | #define CAMERA_MEDIA_TYPE_YCBCR601_422_8 (CAMERA_MEDIA_TYPE_COLOR | CAMERA_MEDIA_TYPE_OCCUPY16BIT | 0x003E) 746 | #define CAMERA_MEDIA_TYPE_YCBCR601_422_8_CBYCRY (CAMERA_MEDIA_TYPE_COLOR | CAMERA_MEDIA_TYPE_OCCUPY16BIT | 0x0044) 747 | #define CAMERA_MEDIA_TYPE_YCBCR601_411_8_CBYYCRYY (CAMERA_MEDIA_TYPE_COLOR | CAMERA_MEDIA_TYPE_OCCUPY12BIT | 0x003F) 748 | #define CAMERA_MEDIA_TYPE_YCBCR709_8_CBYCR (CAMERA_MEDIA_TYPE_COLOR | CAMERA_MEDIA_TYPE_OCCUPY24BIT | 0x0040) 749 | #define CAMERA_MEDIA_TYPE_YCBCR709_422_8 (CAMERA_MEDIA_TYPE_COLOR | CAMERA_MEDIA_TYPE_OCCUPY16BIT | 0x0041) 750 | #define CAMERA_MEDIA_TYPE_YCBCR709_422_8_CBYCRY (CAMERA_MEDIA_TYPE_COLOR | CAMERA_MEDIA_TYPE_OCCUPY16BIT | 0x0045) 751 | #define CAMERA_MEDIA_TYPE_YCBCR709_411_8_CBYYCRYY (CAMERA_MEDIA_TYPE_COLOR | CAMERA_MEDIA_TYPE_OCCUPY12BIT | 0x0042) 752 | 753 | /*RGB Planar */ 754 | #define CAMERA_MEDIA_TYPE_RGB8_PLANAR (CAMERA_MEDIA_TYPE_COLOR | CAMERA_MEDIA_TYPE_OCCUPY24BIT | 0x0021) 755 | #define CAMERA_MEDIA_TYPE_RGB10_PLANAR (CAMERA_MEDIA_TYPE_COLOR | CAMERA_MEDIA_TYPE_OCCUPY48BIT | 0x0022) 756 | #define CAMERA_MEDIA_TYPE_RGB12_PLANAR (CAMERA_MEDIA_TYPE_COLOR | CAMERA_MEDIA_TYPE_OCCUPY48BIT | 0x0023) 757 | #define CAMERA_MEDIA_TYPE_RGB16_PLANAR (CAMERA_MEDIA_TYPE_COLOR | CAMERA_MEDIA_TYPE_OCCUPY48BIT | 0x0024) 758 | 759 | /*MindVision 12bit packed bayer*/ 760 | #define CAMERA_MEDIA_TYPE_BAYGR12_PACKED_MV (CAMERA_MEDIA_TYPE_MONO | CAMERA_MEDIA_TYPE_OCCUPY12BIT | 0x0060) 761 | #define CAMERA_MEDIA_TYPE_BAYRG12_PACKED_MV (CAMERA_MEDIA_TYPE_MONO | CAMERA_MEDIA_TYPE_OCCUPY12BIT | 0x0061) 762 | #define CAMERA_MEDIA_TYPE_BAYGB12_PACKED_MV (CAMERA_MEDIA_TYPE_MONO | CAMERA_MEDIA_TYPE_OCCUPY12BIT | 0x0062) 763 | #define CAMERA_MEDIA_TYPE_BAYBG12_PACKED_MV (CAMERA_MEDIA_TYPE_MONO | CAMERA_MEDIA_TYPE_OCCUPY12BIT | 0x0063) 764 | 765 | /*MindVision 12bit packed monochome*/ 766 | #define CAMERA_MEDIA_TYPE_MONO12_PACKED_MV (CAMERA_MEDIA_TYPE_MONO | CAMERA_MEDIA_TYPE_OCCUPY12BIT | 0x0064) 767 | 768 | 769 | #endif 770 | --------------------------------------------------------------------------------