您的位置:首页 > 理论基础

【计算机视觉】结构光——格雷码模式捕获教程1 (代码)

2017-07-03 16:14 3167 查看

 格雷码模式捕获

教程 

1  格雷码图案







 视觉格雷码模式,珊条纹,条纹光







2  格雷码图案 应用-通信和测量

二进制格雷码(也被称为二进制循环码)是一种无权码,其特点是任何相邻的两个码字中仅有一位代码不同,其他代码是一样的,所以二进制格雷码又叫单位距离码。仔细观察格雷码的编码方式:如果按顺序将格雷码每四个分为一组,对于格雷码的最后一位,具有折叠反射特性,即:最后一位的顺序为
01 10,01 10,.....如果按顺序将格雷码每8个分为一组,则其倒数第2为的顺序为0011,1100,0011,1100.....同样,倒数第3为的顺序为0001111,1111000.这种特性称为反射特性。
格雷码是一种具有反射特性和循环特性的单步自补码,其循环和单步特性消除了随机取数时出现重大错误的可能,其反射和自补特性使得对其进行求反操作也非常方便,所以,格雷码属于一种可靠性编码,是一种错误最小化的编码方式,因此格雷码在通信和测量技术中得到广泛应用。


https://wenku.baidu.com/view/747b0a83ec3a87c24028c478.html

摘要提出一种基于格雷码-相移的组合光编码技术, 以格雷码技术自身的误差不累加性优点保证了光编解码的稳健性, 针对格雷码对视场解析的有限性缺陷,
提出将格雷码部分作为编码的整数部分, 综合使用相移编码作为小数部分, 实现了视场空间的无级细分, 提高了编码的分辨率, 对编码技术中常见的两种错误, 使用提出的编码校正算法有效的减少了编码错误及重建误差的产生。试验结果表明这种光信号编码方法在三维测量中的有很高的稳健性。


  西交大三维光学测量系统技术水平

 



西交大三维光学测量系统技术水平

 


转载▼

标签: 


三维测量

 


反求

 


逆向设计

 


格雷码

 


外差式多频

 


1.1    国内外的三维光学测量系统现状

目前国内有几家单位生产三维光学测量系统,主要有以下两类:

1.只能用于人体扫描的单相机测量技术

这些系统主要用于人体测量,采用类似加拿大Inspeck公司的单相机测量技术,采用简单的单幅光栅相移技术,测量精度低,只能用于人体测量和人像雕刻使用,无法满足工业的测量精度。

2.采用格雷码加相移的三维测量技术

多数的国产三维光学测量系统,基本上采用格雷码加相移的三维测量技术,国外该技术在二十世纪90年代初已经成熟。采用该技术的典型产品为德国GOM公司在1995年推出的ATOS Standard, 1999年GOM公司采用该技术推出了ATOS HR。因此国内目前的三维光学测量系统的技术水平处于国际上二十世纪90年代的水平。

格雷码加相移的三维测量技术的优点为算法实现简单,易于实现产品化,但是缺点非常明显:一是格雷码只是用于对测量幅面的分级,无法提高测量精度;二是格雷码的使用造成测量系统对测量工件的表面明暗比较敏感,一般要喷显影剂才能测量,无法测量较暗的工件,无法测量表面剧烈变化的工件;三是单次测量幅面较小,一般小于400mm。


1.2    最新的外差式多频相移三维光学测量技术

对于格雷码加相移的三维测量技术的缺点,国外一直在研究新的替代方法,提出了很多测量技术,其中外差式多频相移技术是发展较快的方法。XJTUOM测量系统就是采用国际目前最新的外差式多频相移三维光学测量技术,由西安交通大学机械工程学院信息机电研究所和模具与塑性加工研究所研制,该技术与传统的格雷码加相移相比,优点突出:

(1)对测量工件的明暗不受影响。该技术放弃了格雷码,采用多频相移技术,因此该技术就没有了格雷码带来的问题,对测量工件的明暗基本不受影响,不用喷显影剂就可测量大多数的工件。

(2)测量幅面可以更大,而测量时间较短。如果采用格雷码,测量幅面增大后,必须增加格雷码的编码位数,必须投射更多幅的格雷码,增大了测量时间。外差式多频相移技术更适于测量更大幅面的工件,精度更高。

(3)测量精度更高。采用格雷码加相移的三维测量技术,其测量精度主要由一幅光栅四次相移决定,格雷码的使用没有提高测量精度。而外差式多频相移三维光学测量技术,采用多个频率的光栅相移,比只投射1种频率的光栅精度更高,抗干扰能力强,而且能够测量剧烈变化的曲面。

(4)可以测量表面剧烈变化的工件。可以测量非连续、剧烈变化的表面。

国外最新的三维光学测量系统,已经逐步采用外差式多频相移三维光学测量技术。例如,GOM公司在2001年推出了第一代的采用多频相移的ATOS II型测量系统,2003年推出了的ATOS IIe型和ATOS III型测量系统。2003年GOM公司推出的外差式多频相移三维光学测量技术还不成熟,测量速度较慢。2006年GOM公司推出了采用轮式光栅的外差式多频相移技术,测量速度得到较大提高。

XJTUOM型三维光学密集点云测量系统采用外差式多频相移三维光学测量技术,技术水平达到了国际水平,技术指标达到了世界最先进的德国GOM公司的2007年最新ATOS产品。外差式多频相移三维光学测量技术的优点很多,但是技术含量较高,要达到实用水平需要解决许多问题。XJTUOM型三维光学密集点云测量系统采用外差式多频相移三维光学测量技术,重点解决了以下关键技术问题,使系统的技术水平达到的国际水平。

(1)外差式多频相移测量算法。该算法综合了外差算法、多频测量、小波变化、傅立叶技术、贝叶斯估计法等方法,实现了快速、高效的测量。

(2)光栅投射器,研制了高精度快速的光栅投射器,根据情况更换不同镜头。

(3)新的自动拼接算法,使自动拼接准确、自动化程度更高,自动删除重叠面,提高工件扫描效率80%以上,并可与西安交通大学XJTUDP型工业数字近景三维摄影测量系统配合使用提高拼接精度。


1.2.1            三维光学密集点云测量原理

目前,国内外三维光学密集点云测量实用系统主要有两类[1]:一是采用简单的单幅光栅相移技术,以加拿大Inspeck公司为代表的单相机测量技术,主要用于人体测量和人像雕刻使用,其精度无法满足工业的测量精度;二是采用格雷码加相移的三维测量技术,用多幅格雷码光栅对测量区域分级标识,再用单幅光栅相移测量,该技术国外在二十世纪90年代初已经成熟,德国GOM公司采用该技术在1995年就推出了ATOS Standard产品,目前国内外的三维光学扫描测量系统多采用该方法。

ATOS三维形状测量的基本原理是基于相位光栅投影的结构光法,如图 1所示,采用非接触式几何光学法测量工件的形貌轮廓,运用条纹结构光经由投射器将条纹光栅投射至待测物表面, 相机拍摄工件图像,通过格雷编码与相位移法计算得到其绝对相位,配合三角测量原理便可得到待测物三维形貌轮廓。

图 1  ATOS结构图


1.2.2            格雷码加相移技术

对于三维光学密集点云测量方法[2],位相测量轮廓法(PMP)为目前主流的测量技术。变形的条纹光强可用下式表示,这种变形可理解为相位和振幅均被调制的空间载波信号。

I(x,y)=R(x,y){A(x,y)+B(x,y)cos[2πx/p+Δφ(x,y)]}

上式中R(x,y)为与物体表面反射率有关的参数,A(x,y)为背景光强,B(x,y)为调制因子,P为条纹周期,Δφ(x,y)则是与物体表面轮廓相关联的相位因子,为了从I(x,y)中解调出反映物体形面信息的Δφ(x,y),在这里采用四步相移法。当引入相移量0,π/2,π,3π/2后,则有:      

Δφ(x,y)=arctg[(I1-I3)/( I2-I4)]   其中Ii ( i = 1 ,2 ,3 ,4) 为光强。

位相测量轮廓法(PMP)的难点在于解包裹方法。目前常用解包裹方法为格雷Gray码法(如图 2所示),国外商用的三维光学测量系统几乎都采用该方法。格雷码方法己经比较成熟[3],其优点是条纹定级非常方便,直接根据黑白分布求得格雷码,再解码便获成功,算法实现简单,易于实现产品化。但是缺点非常明显:一是格雷码只是用于对测量幅面的分级,对计算物体的相位没有帮助,无法提高测量精度,无宜是种浪费;二是格雷码的使用造成测量系统对测量工件的表面明暗比较敏感,黑白交界处容易受到噪声的干扰,一般要喷显影剂才能测量,无法测量较暗的工件,无法测量表面剧烈变化的工件;三是单次测量幅面较小,一般小于400mm。

图 2格雷码加相移技术示意图

 

图 3 ATOS工作原理

图 3所示ATOS系统采用格雷码加相移获取三维点云的过程:首先由光源卤素灯产生编码光栅,这些光栅投影到被测样件表面产生一系列图象,这些图象被CCD相机摄取到,然后通过图象处理方法分析这些图象,计算被测样件表面点的空间位置。光源投影一系列的黑白条纹到被测样件表面,图像每个像素都依据其对应的被测表面点是被白色条纹还是黑色条纹投影到呈现亮或暗。比如通过投影五种条纹可以得到一个五位的二进制代码用以估算每个像素,这个代码与被测表面形状是直接相关的。使用这个代码可以得到被测表面点的粗略空间位置。


1.2.3   外差式多频相移技术

对于格雷码加相移的三维测量技术的缺点[4],国外一直在研究新的替代方法,提出了很多测量技术,其中外差式多频相移技术是发展较快的方法。国内外研究者以前提出过双频相移技术,虽然摆脱了格雷码,提出了采用查找表法的双频相移技术、贝叶斯估计法的双频相移技术等,进行了大量研究,但是实际测量效果都不理想,大量试验和理论证明采用双频相移技术无法满足实际测量需要,外差式多频相移技术是在双频相移技术的基础上发展而来的,其光栅数目大于两个,一般为3至6个,而且种频率光栅需要进行多次相移,因此其技术难度大大增加。该技术与传统的格雷码加相移相比,具有以突出下优点:

(1)对测量工件的明暗不受影响。该技术放弃了格雷码,采用多频相移技术,因此该技术就没有了格雷码带来的问题,对测量工件的明暗基本不受影响,不用喷显影剂就可测量大多数的工件。

(2)测量幅面可以更大,而测量时间较短。如果采用格雷码,测量幅面增大后,必须增加格雷码的编码位数,必须投射更多幅的格雷码,增大了测量时间。外差式多频相移技术更适于测量更大幅面的工件,精度更高。

(3)测量精度更高。采用格雷码加相移的三维测量技术,其测量精度主要由一幅光栅四次相移决定,格雷码的使用没有提高测量精度。而外差式多频相移三维光学测量技术,采用多个频率的光栅相移,比只投射1种频率的光栅精度更高,抗干扰能力强,而且能够测量剧烈变化的曲面。

(4)可以测量表面剧烈变化的工件。可以测量非连续、剧烈变化的表面。

外差式多频相移技术的具体实现方法很多,投射的每个条纹一个周期的明暗变化可以正弦、三角形等,根据精度要求不同,投射的多种频率光栅可以多个(3至6种)。可以采用彩色相机一次拍摄3种不同颜色不同频率光栅图像,也可以采用黑白相机多次拍摄多种频率光栅。该技术既可以测量静止工件三维点云,也可以测量移动物体的三维点云。

要实现外差式多频相移技术,其难点很多,一是光栅投射机构,由于需要多个光栅,每个光栅需要多次相移,造成光栅投射机构复杂;二是光栅和算法设计要巧妙,既要测量准确,又要保证不增加太多的计算量;三是实现大幅面测量,需要更强的投射光,一次3米幅面测量需要比400mm幅面大30倍的光强和对比度,大幅面测量的光路设计也比较特殊,需要在较近距离投射和拍摄3米幅面,投射光路和相机光路必须采用短焦广角镜头。

图 4为2006年11月GOM公司申请的一种多频光栅投射装置结构专利,图 4-a为不同图案的光栅,有正弦、三角形、菱形、圆形等,图 4-a为圆盘光栅,一个圆盘周边刻画出多种频率和多种相移的光栅图案,当圆盘告诉旋转后,经过强光照射后,图 4-c为投射到物体的光栅图案。图 4的光栅投射装置采用圆盘旋转机构巧妙地解决了多种频率光栅和多种相移的复杂机械结构。

a) 不同图案光栅                b)圆盘光栅         c)投射到物体的合成光栅

图 4 圆盘旋转产生多频光栅相移结构

西安交通大学模具与塑性加工研究所研制“XJTUOM型三维光学密集点云测量系统”采用一种新的外差式多频相移三维光学测量技术,利用空间频接近的多个投影条纹莫尔特性的解相方法,能够非常简洁可靠地对条纹进行解包裹。分别投影多种不同空间频率的条纹于待测面上,摄像机摄取变形的条纹图,并利用相移法求取多种条纹的相位主值,从而恢复出条纹的真实相位来。此解包裹过程针对各点单独进行,所以不会出现误差传递的现象。通过多个光栅的相移,要比一个光栅(格雷码加相移法)的相移测量精度更高。

3格雷码捕获模式教程

http://docs.opencv.org/master/db/d56/tutorial_capture_graycode_pattern.html



目标

在本教程中,您将学习如何使用 GrayCodePattern 类:
生成一个灰色的代码模式。
项目格雷码的模式。
捕获投射格雷码图案。

重要的是要强调这一点 GrayCodePattern 类实际上实现了3中描述dunderworld算法 [73] 基于立体视觉的方法:我们需要捕捉投影模式同时从两个不同的观点如果我们想重建扫描对象的三维模型。
因此,收购集由每个相机捕捉到的图像中每一个图像序列模式。


代码

/*M///////////////////////////////////////////////////////////////////////////////////////

//

// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.

//

// By downloading, copying, installing or using the software you agree to this license.

// If you do not agree to this license, do not download, install,

// copy or use the software.

//

//

// License Agreement

// For Open Source Computer Vision Library

//

// Copyright (C) 2015, OpenCV Foundation, all rights reserved.

// Third party copyrights are property of their respective owners.

//

// Redistribution and use in source and binary forms, with or without modification,

// are permitted provided that the following conditions are met:

//

// * Redistribution's of source code must retain the above copyright notice,

// this list of conditions and the following disclaimer.

//

// * Redistribution's in binary form must reproduce the above copyright notice,

// this list of conditions and the following disclaimer in the documentation

// and/or other materials provided with the distribution.

//

// * The name of the copyright holders may not be used to endorse or promote products

// derived from this software without specific prior written permission.

//

// This software is provided by the copyright holders and contributors "as is" and

// any express or implied warranties, including, but not limited to, the implied

// warranties of merchantability and fitness for a particular purpose are disclaimed.

// In no event shall the Intel Corporation or contributors be liable for any direct,

// indirect, incidental, special, exemplary, or consequential damages

// (including, but not limited to, procurement of substitute goods or services;

// loss of use, data, or profits; or business interruption) however caused

// and on any theory of liability, whether in contract, strict liability,

// or tort (including negligence or otherwise) arising in any way out of

// the use of this software, even if advised of the possibility of such damage.

//

//M*/

#include <opencv2/imgproc.hpp>

#include <opencv2/highgui.hpp>

#include <opencv2/structured_light.hpp>

#include <iostream>

#include <stdio.h>

using namespace cv;

using namespace std;

static
const char* keys =

{ "{@path | | Path of the folder where the captured pattern images will be save }"

"{@proj_width | | Projector width }"

"{@proj_height | | Projector height }" };

static
void help()

{

cout << "\nThis example shows how to use the \"Structured Light module\" to acquire a graycode pattern"

"\nCall (with the two cams connected):\n"

"./example_structured_light_cap_pattern <path> <proj_width> <proj_height> \n"

<< endl;

}

int main(
int argc, char** argv )

{

structured_light::GrayCodePattern::Params params;

CommandLineParser parser( argc, argv, keys );

String path = parser.get<String>(
0 );

params.width
= parser.get<int>( 1 );

params.height
= parser.get<int>( 2 );

if( path.empty()
|| params.width
< 1 || params.height
< 1 )

{

help();

return -1;

}

// Set up GraycodePattern with params

Ptr<structured_light::GrayCodePattern> graycode =structured_light::GrayCodePattern::create(
params );

// Storage for pattern

vector<Mat> pattern;

graycode->generate(
pattern );

cout << pattern.size() <<
" pattern images + 2 images for shadows mask computation to acquire with both cameras"

<< endl;

// Generate the all-white and all-black images needed for shadows mask computation

Mat white;

Mat black;

graycode->getImagesForShadowMasks(
black, white );

pattern.push_back( white );

pattern.push_back( black );

// Setting pattern window on second monitor (the projector's one)

namedWindow("Pattern
Window",
WINDOW_NORMAL );

resizeWindow("Pattern
Window", params.width,
params.height
);

moveWindow("Pattern
Window", params.width
+ 316, -20 );

setWindowProperty("Pattern
Window",
WND_PROP_FULLSCREEN,
WINDOW_FULLSCREEN );

// Open camera number 1, using libgphoto2

VideoCapture cap1(CAP_GPHOTO2
);

if( !cap1.isOpened() )

{

// check if cam1 opened

cout << "cam1 not opened!" << endl;

help();

return -1;

}

// Open camera number 2

VideoCapture cap2( 1 );

if( !cap2.isOpened() )

{

// check if cam2 opened

cout << "cam2 not opened!" << endl;

help();

return -1;

}

// Turning off autofocus

cap1.set(
CAP_PROP_SETTINGS, 1 );

cap2.set(
CAP_PROP_SETTINGS, 1 );

int i = 0;

while( i < (int) pattern.size() )

{

cout << "Waiting to save image number " << i + 1 << endl <<"Press any key to acquire the photo" << endl;

imshow("Pattern
Window", pattern[i] );

Mat frame1;

Mat frame2;

cap1 >> frame1; // get a new frame from camera 1

cap2 >> frame2; // get a new frame from camera 2

if( ( frame1.data ) && ( frame2.data ) )

{

Mat tmp;

cout << "cam 1 size: " <<Size(
( int ) cap1.get(CAP_PROP_FRAME_WIDTH
), ( int ) cap1.get(
CAP_PROP_FRAME_HEIGHT ) )

<< endl;

cout << "cam 2 size: " <<Size(
( int ) cap2.get(CAP_PROP_FRAME_WIDTH
), ( int ) cap2.get(
CAP_PROP_FRAME_HEIGHT ) )

<< endl;

cout << "zoom cam 1: " << cap1.get(CAP_PROP_ZOOM
) << endl << "zoom cam 2: " << cap2.get(

CAP_PROP_ZOOM )

<< endl;

cout << "focus cam 1: " << cap1.get(CAP_PROP_FOCUS
) << endl << "focus cam 2: " << cap2.get(

CAP_PROP_FOCUS )

<< endl;

cout << "Press enter to save the photo or an other key to re-acquire the photo" << endl;

namedWindow("cam1",

WINDOW_NORMAL );

resizeWindow("cam1",
640, 480 );

namedWindow("cam2",

WINDOW_NORMAL );

resizeWindow("cam2",
640, 480 );

// Moving window of cam2 to see the image at the same time with cam1

moveWindow("cam2",
640 + 75, 0 );

// Resizing images to avoid issues for high resolution images, visualizing them as grayscale

resize( frame1, tmp,Size(
640, 480 ) );

cvtColor( tmp, tmp,COLOR_RGB2GRAY
);

imshow("cam1",
tmp );

resize( frame2, tmp,Size(
640, 480 ) );

cvtColor( tmp, tmp,COLOR_RGB2GRAY
);

imshow("cam2",
tmp );

bool save1 =
false;

bool save2 =
false;

int key =
waitKey( 0 );

// Pressing enter, it saves the output

if( key == 13 )

{

ostringstream name;

name << i + 1;

save1 =
imwrite( path + "pattern_cam1_im" + name.str() +".png", frame1 );

save2 =
imwrite( path + "pattern_cam2_im" + name.str() +".png", frame2 );

if( ( save1 ) && ( save2 ) )

{

cout << "pattern cam1 and cam2 images number " << i + 1 <<" saved" << endl << endl;

i++;

}

else

{

cout << "pattern cam1 and cam2 images number " << i + 1 <<" NOT saved" << endl << endl <<"Retry,
check the path"<< endl << endl;

}

}

// Pressing escape, the program closes

if( key == 27 )

{

cout << "Closing program" << endl;

}

}

else

{

cout << "No frame data, waiting for new frame" << endl;

}

}

// the camera will be deinitialized automatically in VideoCapture destructor

return 0;

}


解释

首先必须生成模式图像项目。 由于图像是一个函数的数量投影仪的分辨率, GrayCodePattern 类参数必须设置与我们的投影仪的宽度和高度。
通过这种方式, 生成 方法可以被称为:它垫的填充矢量计算模式图片:

structured_light::GrayCodePattern::Params params;

....

params.width
= parser.get<int>( 1 );

params.height = parser.get<int>( 2 );

....

// Set up GraycodePattern with params

Ptr<structured_light::GrayCodePattern> graycode = structured_light::GrayCodePattern::create( params );

// Storage for pattern

vector<Mat> pattern;

graycode->generate( pattern );

例如,使用默认的投影仪分辨率(1024 x 768),40图像投影:20正则颜色模式(10图像的列顺序和10行)和20的反色模式,反模式的图像是图像与原始文件相同的结构,但反向的颜色。 这提供了一个有效的方法,轻松地确定每个像素的强度值时点燃(最大值),当它不是点燃在解码步骤(最小值)。

随后,确定阴影区域,该地区的两个图像像素不点燃投影仪的光,因此,没有代码信息,3 dunderworld算法计算两个摄像头的荫罩的观点,从一个白色和一个黑色的图像捕捉到每一个相机。 所以需要两个额外的图像投影和捕获与相机:

/ /生成所需的全白和全黑图像阴影掩码计算

Mat white;

Mat black;

graycode->getImagesForShadowMasks( black, white );

pattern.push_back( white );

pattern.push_back( black );

因此,预计最终投影序列如下:第一列及其反向序列,然后行及其反向序列,最后的黑白图像。

一旦图像生成模式,他们必须使用完整的投影屏幕上选择:必须填满所有的投影的图像区域,否则投影机全分辨率不是剥削,是基于一个条件3 dunderworld实现。

/ /设置模式窗口第二台显示器(投影仪)



// Setting pattern window on second monitor (the projector's one)

namedWindow("Pattern
Window",
WINDOW_NORMAL );

resizeWindow("Pattern
Window", params.width, params.height );

moveWindow("Pattern
Window", params.width + 316, -20 );

setWindowProperty("Pattern
Window",
WND_PROP_FULLSCREEN,
WINDOW_FULLSCREEN )

在这一点上与数码相机捕获的图像可以使用libgphoto2库,最近在OpenCV包括:记住Cmake gPhoto2选项。 当建筑OpenCV。

/ /打开相机1号,使用libgphoto2

VideoCapture cap1(
CAP_GPHOTO2 );

if( !cap1.isOpened() )

{

// check if cam1 opened

cout << "cam1 not opened!" << endl;

help();

return -1;

}

// Open camera number 2

VideoCapture cap2( 1 );

if( !cap2.isOpened() )

{

// check if cam2 opened

cout << "cam2 not opened!" << endl;

help();

return -1;

}

两个摄像头必须工作在同一分辨率和必须禁用自动对焦选项,保持相同的焦点都在收购。 投影仪可以定位在镜头中间。

然而,在推进模式收购之前,相机必须校准。 一旦执行校准,不应该有摄像机的运动,否则将需要一个新的校准。

后摄像头和投影仪连接到电脑,可以启动cap_pattern演示给作为参数保存图片的路径,和投影仪的宽度和高度,照顾使用相同的专注和相机设置的校准。

在这一点上,这两款相机获取的图像,用户可以按任意键。

/ /关闭自动对焦

cap1.set(
CAP_PROP_SETTINGS, 1 );

cap2.set(
CAP_PROP_SETTINGS, 1 );

int i = 0;

while( i < (int) pattern.size() )

{

cout << "Waiting to save image number " << i + 1 << endl <<"Press any key to acquire the photo" << endl;

imshow("Pattern
Window", pattern[i] );

Mat frame1;

Mat frame2;

cap1 >> frame1; // get a new frame from camera 1

cap2 >> frame2; // get a new frame from camera 2

...

}

如果捕获的图像是好的(预期的用户必须照顾模式从两个摄像头),用户可以拯救他们按enter键,否则按其他键他可以再拍摄。

/ /按回车保存输出

// Pressing enter, it saves the output

if( key == 13 )

{

ostringstream name;

name << i + 1;

save1 =
imwrite( path + "pattern_cam1_im" + name.str() +".png", frame1 );

save2 =
imwrite( path + "pattern_cam2_im" + name.str() +".png", frame2 );

if( ( save1 ) && ( save2 ) )

{

cout << "pattern cam1 and cam2 images number " << i + 1 <<" saved" << endl << endl;

i++;

}

else

{

cout << "pattern cam1 and cam2 images number " << i + 1 <<" NOT saved" << endl << endl <<"Retry,
check the path"<< endl << endl;

}

}

采访结束时,所有的模式都救了摄像机的图像。 然后用户可以重建的三维模型捕获现场使用 解码 的方法 GrayCodePattern 类(参见下一个教程)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: