该示例演示了如何通过 API 接口操作 C 系列相机在 IN_SCAN_HDR 曝光模式下采集图像数据。
包括如何发现相机并连接相机,如何设置 2d 参数,以及如何采集图像、保存图像。
在 IN_SCAN_HDR 曝光模式下采图时,相机并不会真正的再去采集一张新的图像,而是从上一轮扫描中每一个曝光时间对应的打光图像都取出来,做 HDR 融合后返回。
因此,IN_SCAN_HDR 曝光模式必须配合扫描操作一同使用,否则,IN_SCAN_HDR 曝光模式采集到的图像不会更新。
IN_SCAN_HDR 模式适用于图像中不同区域亮度差异较大的场景。
关于参数的具体信息,以及设置后产生的影响,请使用 ALSON Viewer 进行操作验证。
如何在Visual Studio、QT、CLion中使用示例工程请参考示例工程使用说明。
注意:设置参数时请关注各个参数是否可写,以及参数的上下限!
// std
#include <iostream>
// alson
#include <alson/classic_client.h>
int main(int argc, char** argv) {
try {
// 开启客户端日志,需要指定日志配置文件。
ALSON::Client::initLog("../../../LogConfig-Client.yaml");
// 检测所有服务端(即可用的设备),并获取其中第一个服务端的信息。
std::vector<ALSON::ServerInfo> serverInfoList = ALSON::Client::discovery();
if (serverInfoList.empty()) {
std::cerr << "can not find any server or device" << std::endl;
return -1;
}
ALSON::ServerInfo serverInfo = serverInfoList.front();
// 构造客户端并建立通信连接
ALSON::Client client;
client.connect(serverInfo.getServerNetworkCardInfo().getIp(), serverInfo.getServerNetworkCardInfo().getBindPort());
std::cout << "is connected: " << client.isConnected() << std::endl;
// 心跳时间通常设置为 2000ms 至 3000ms。在开发调试过程中,可适当设置大些。
// 如果心跳时间很大,那么当通信意外断开时,客户端和服务端都需要经历很长的时间才能感知到。
// 在此期间,客户端将阻塞您的进程,服务端不能被新的客户端连接。
client.setHeartbeatTimeout(3000);
// 创建设备控制器对象
ALSON::ClassicDeviceController deviceController = client.createDeviceController<ALSON::ClassicDeviceController>();
// 打开设备。注意无论设备是否关闭,在调用 DeviceController 中其他接口之前都必须调用 open 接口。
deviceController.open();
// 获取参数组管理器
ALSON::DeviceParameterManager parameterManager = client.createDeviceParameterManager();
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// 获取默认的 IN_SCAN_HDR 图像
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 重置参数组,所有参数会恢复成默认值。
parameterManager.resetCurrentValue();
// 将曝光模式设置为 IN_SCAN_HDR
parameterManager.updateCurrentEnumerationValue("2dParameters.exposureMode", "IN_SCAN_HDR");
// 设置 3d 曝光时间为 5000、30000。接下来采集的 2d 图像将会是 5000 和 30000 下两张打光图像的融合。
parameterManager.updateCurrentIntegerValue("3dParameters.exposureTimeArray[0]", 5000);
parameterManager.addArrayElementForCurrent("3dParameters.exposureTimeArray");
parameterManager.updateCurrentIntegerValue("3dParameters.exposureTimeArray[1]", 30000);
// 注意:获取 IN_SCAN_HDR 图像之前必须执行扫描。
deviceController.grabPointCloud();
// 采集原始图像并保存到本地,原始图像是左相机图像和右相机图像。
std::vector<ALSON::AlsonMat> sourceImageList = deviceController.grabSourceImages();
sourceImageList[0].save("./GrabImage_C_IN_SCAN_HDR_Default_Left.bmp");
sourceImageList[1].save("./GrabImage_C_IN_SCAN_HDR_Default_Right.bmp");
// 采集纹理图像保存到本地,纹理图像默认是左相机图像。
ALSON::AlsonMat textureImage = deviceController.grabTextureImage();
textureImage.save("./GrabImage_C_IN_SCAN_Default_TextureImage.bmp");
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// 快速获取 IN_SCAN_HDR 图像
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 重置参数组,所有参数会恢复成默认值。
parameterManager.resetCurrentValue();
// 将曝光模式设置为 IN_SCAN_HDR
parameterManager.updateCurrentEnumerationValue("2dParameters.exposureMode", "IN_SCAN_HDR");
// 设置 3d 曝光时间为 5000、30000。接下来采集的 2d 图像将会是 5000 和 30000 下两张打光图像的融合。
parameterManager.updateCurrentIntegerValue("3dParameters.exposureTimeArray[0]", 5000);
parameterManager.addArrayElementForCurrent("3dParameters.exposureTimeArray");
parameterManager.updateCurrentIntegerValue("3dParameters.exposureTimeArray[1]", 30000);
// 开启快速 HDR,开启后,只有左相机会生成融合图像,将进一步缩短节拍。默认情况下,快速 HDR 选项是关闭状态,即左右相机都会生成融合图像。
parameterManager.updateCurrentBooleanValue("2dParameters.fastHdr", true);
// 注意:获取 IN_SCAN_HDR 图像之前必须执行扫描。
deviceController.grabPointCloud();
// 采集原始图像并保存到本地,原始图像列表中只有左相机图像。
sourceImageList = deviceController.grabSourceImages();
sourceImageList[0].save("./GrabImage_C_IN_SCAN_HDR_Fast_Left.bmp");
sourceImageList[1].save("./GrabImage_C_IN_SCAN_HDR_Fast_Right.bmp");
// 采集纹理图像保存到本地,纹理图像默认是左相机图像。
textureImage = deviceController.grabTextureImage();
textureImage.save("./GrabImage_C_IN_SCAN_HDR_Fast_TextureImage.bmp");
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// 获取更亮的 IN_SCAN_HDR 图像
/// IN_SCAN_HDR 图像的亮度主要受 3d 曝光时间和增益的影响。此外,减小 gamma 也能提升图像亮度。
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 重置参数组,所有参数会恢复成默认值。
parameterManager.resetCurrentValue();
// 将曝光模式设置为 IN_SCAN_HDR
parameterManager.updateCurrentEnumerationValue("2dParameters.exposureMode", "IN_SCAN_HDR");
// 设置 3d 曝光时间为 10000、30000。接下来采集的 2d 图像将会是 10000 和 30000 下两张打光图像的融合。
parameterManager.updateCurrentIntegerValue("3dParameters.exposureTimeArray[0]", 10000);
parameterManager.addArrayElementForCurrent("3dParameters.exposureTimeArray");
parameterManager.updateCurrentIntegerValue("3dParameters.exposureTimeArray[1]", 30000);
// 提高增益
parameterManager.updateCurrentIntegerValue("3dParameters.gain", 10);
// 设置 gamma。gamma 小于 1 时,图像会变亮;gamma 大于 1 时,图像会变暗。
parameterManager.updateCurrentFloatValue("2dParameters.gamma", 0.8f);
// 注意:获取 IN_SCAN_HDR 图像之前必须执行扫描。
deviceController.grabPointCloud();
// 采集原始图像并保存到本地,原始图像是左相机图像和右相机图像。
sourceImageList = deviceController.grabSourceImages();
sourceImageList[0].save("./GrabImage_C_IN_SCAN_HDR_Bright_Left.bmp");
sourceImageList[1].save("./GrabImage_C_IN_SCAN_HDR_Bright_Right.bmp");
// 采集纹理图像保存到本地,纹理图像默认是左相机图像。
textureImage = deviceController.grabTextureImage();
textureImage.save("./GrabImage_C_IN_SCAN_HDR_Bright_TextureImage.bmp");
// 关闭设备。注意:close 接口一般情况下不需要调用,如果该接口被调用,下次调用 open 接口的时候就会比较耗时。
deviceController.close();
// 如果不再需要连接服务端,请及时调用 disconnect 断开连接。
client.disconnect();
}
catch (ALSON::CommonException& cause) {
// API 中的所有接口都有可能抛出异常,请按照这种方式进行捕获。否则异常发生时可能会导致程序崩溃。
std::cerr << cause.getStackTrace() << std::endl;
return -1;
}
return 0;
}