682 lines
17 KiB
C++
682 lines
17 KiB
C++
|
|
#include "IKapDevice.h"
|
|||
|
|
#include <cstring>
|
|||
|
|
#include <iostream>
|
|||
|
|
|
|||
|
|
// 静态工厂方法实现
|
|||
|
|
int IIKapDevice::CreateObject(IIKapDevice** ppDevice)
|
|||
|
|
{
|
|||
|
|
if (ppDevice == nullptr)
|
|||
|
|
return -1;
|
|||
|
|
|
|||
|
|
*ppDevice = new CIKapDevice();
|
|||
|
|
return (*ppDevice) ? 0 : -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
CIKapDevice::CIKapDevice()
|
|||
|
|
: m_hDevice(nullptr)
|
|||
|
|
, m_hStream(nullptr)
|
|||
|
|
, m_bIsGrabbing(false)
|
|||
|
|
, m_bLibInitialized(false)
|
|||
|
|
, m_imageCallback(nullptr)
|
|||
|
|
, m_pUserData(nullptr)
|
|||
|
|
, m_nDeviceIndex(0)
|
|||
|
|
, m_bDeviceOpened(false)
|
|||
|
|
{
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
CIKapDevice::~CIKapDevice()
|
|||
|
|
{
|
|||
|
|
// 确保资源被释放
|
|||
|
|
if (m_bIsGrabbing.load())
|
|||
|
|
{
|
|||
|
|
StopGrabbing();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (m_bDeviceOpened)
|
|||
|
|
{
|
|||
|
|
CloseDevice();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (m_bLibInitialized.load())
|
|||
|
|
{
|
|||
|
|
TerminateLibrary();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int CIKapDevice::InitLibrary()
|
|||
|
|
{
|
|||
|
|
if (m_bLibInitialized.load())
|
|||
|
|
return 0;
|
|||
|
|
|
|||
|
|
ITKSTATUS status = ItkManInitialize();
|
|||
|
|
if (status != ITKSTATUS_OK)
|
|||
|
|
{
|
|||
|
|
std::cerr << "ItkManInitialize failed, status: " << status << std::endl;
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
m_bLibInitialized.store(true);
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int CIKapDevice::TerminateLibrary()
|
|||
|
|
{
|
|||
|
|
if (!m_bLibInitialized.load())
|
|||
|
|
return 0;
|
|||
|
|
|
|||
|
|
ITKSTATUS status = ItkManTerminate();
|
|||
|
|
if (status != ITKSTATUS_OK)
|
|||
|
|
{
|
|||
|
|
std::cerr << "ItkManTerminate failed, status: " << status << std::endl;
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
m_bLibInitialized.store(false);
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int CIKapDevice::EnumerateDevices(unsigned int& nCount)
|
|||
|
|
{
|
|||
|
|
if (!m_bLibInitialized.load())
|
|||
|
|
{
|
|||
|
|
std::cerr << "Library not initialized" << std::endl;
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
ITKSTATUS status = ItkManGetDeviceCount(&nCount);
|
|||
|
|
if (status != ITKSTATUS_OK)
|
|||
|
|
{
|
|||
|
|
std::cerr << "ItkManGetDeviceCount failed, status: " << status << std::endl;
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int CIKapDevice::GetDeviceInfo(unsigned int nIndex, IKapDeviceInfo& deviceInfo)
|
|||
|
|
{
|
|||
|
|
if (!m_bLibInitialized.load())
|
|||
|
|
{
|
|||
|
|
std::cerr << "Library not initialized" << std::endl;
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
ITKDEV_INFO devInfo;
|
|||
|
|
memset(&devInfo, 0, sizeof(devInfo));
|
|||
|
|
|
|||
|
|
ITKSTATUS status = ItkManGetDeviceInfo(nIndex, &devInfo);
|
|||
|
|
if (status != ITKSTATUS_OK)
|
|||
|
|
{
|
|||
|
|
std::cerr << "ItkManGetDeviceInfo failed, status: " << status << std::endl;
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 复制设备信息
|
|||
|
|
strncpy(deviceInfo.vendorName, devInfo.VendorName, sizeof(deviceInfo.vendorName) - 1);
|
|||
|
|
deviceInfo.vendorName[sizeof(deviceInfo.vendorName) - 1] = '\0';
|
|||
|
|
strncpy(deviceInfo.modelName, devInfo.ModelName, sizeof(deviceInfo.modelName) - 1);
|
|||
|
|
deviceInfo.modelName[sizeof(deviceInfo.modelName) - 1] = '\0';
|
|||
|
|
strncpy(deviceInfo.serialNumber, devInfo.SerialNumber, sizeof(deviceInfo.serialNumber) - 1);
|
|||
|
|
deviceInfo.serialNumber[sizeof(deviceInfo.serialNumber) - 1] = '\0';
|
|||
|
|
strncpy(deviceInfo.userDefinedName, devInfo.UserDefinedName, sizeof(deviceInfo.userDefinedName) - 1);
|
|||
|
|
deviceInfo.userDefinedName[sizeof(deviceInfo.userDefinedName) - 1] = '\0';
|
|||
|
|
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int CIKapDevice::OpenDevice(unsigned int nIndex, int accessMode)
|
|||
|
|
{
|
|||
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
|||
|
|
|
|||
|
|
if (m_bDeviceOpened)
|
|||
|
|
{
|
|||
|
|
std::cerr << "Device already opened" << std::endl;
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!m_bLibInitialized.load())
|
|||
|
|
{
|
|||
|
|
std::cerr << "Library not initialized" << std::endl;
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 打开设备
|
|||
|
|
ITKSTATUS status = ItkDevOpen(nIndex, accessMode, &m_hDevice);
|
|||
|
|
if (status != ITKSTATUS_OK || m_hDevice == nullptr)
|
|||
|
|
{
|
|||
|
|
std::cerr << "ItkDevOpen failed, status: " << status << std::endl;
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
m_nDeviceIndex = nIndex;
|
|||
|
|
m_bDeviceOpened = true;
|
|||
|
|
|
|||
|
|
// 创建数据流和Buffer
|
|||
|
|
if (CreateStreamAndBuffer() != 0)
|
|||
|
|
{
|
|||
|
|
CloseDevice();
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int CIKapDevice::CloseDevice()
|
|||
|
|
{
|
|||
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
|||
|
|
|
|||
|
|
if (!m_bDeviceOpened)
|
|||
|
|
return 0;
|
|||
|
|
|
|||
|
|
// 释放数据流和Buffer
|
|||
|
|
ReleaseStreamAndBuffer();
|
|||
|
|
|
|||
|
|
// 关闭设备
|
|||
|
|
if (m_hDevice != nullptr)
|
|||
|
|
{
|
|||
|
|
ITKSTATUS status = ItkDevClose(m_hDevice);
|
|||
|
|
if (status != ITKSTATUS_OK)
|
|||
|
|
{
|
|||
|
|
std::cerr << "ItkDevClose failed, status: " << status << std::endl;
|
|||
|
|
}
|
|||
|
|
m_hDevice = nullptr;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
m_bDeviceOpened = false;
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int CIKapDevice::IsConnected(bool& bConnected)
|
|||
|
|
{
|
|||
|
|
if (!m_bDeviceOpened || m_hDevice == nullptr)
|
|||
|
|
{
|
|||
|
|
bConnected = false;
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#ifdef _WIN32
|
|||
|
|
// Windows 平台:使用新版 API
|
|||
|
|
bool connected = false;
|
|||
|
|
ITKSTATUS status = ItkDevIsConnected(m_hDevice, &connected);
|
|||
|
|
if (status != ITKSTATUS_OK)
|
|||
|
|
{
|
|||
|
|
std::cerr << "ItkDevIsConnected failed, status: " << status << std::endl;
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
bConnected = connected;
|
|||
|
|
#else
|
|||
|
|
// Linux/ARM 平台:旧版 SDK 没有 IsConnected 接口,简化实现
|
|||
|
|
// 假设设备打开后就是连接状态
|
|||
|
|
bConnected = (m_hDevice != nullptr);
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int CIKapDevice::CreateStreamAndBuffer()
|
|||
|
|
{
|
|||
|
|
if (m_hDevice == nullptr)
|
|||
|
|
return -1;
|
|||
|
|
|
|||
|
|
// 获取数据流数量
|
|||
|
|
uint32_t streamCount = 0;
|
|||
|
|
ITKSTATUS status = ItkDevGetStreamCount(m_hDevice, &streamCount);
|
|||
|
|
if (status != ITKSTATUS_OK || streamCount == 0)
|
|||
|
|
{
|
|||
|
|
std::cerr << "ItkDevGetStreamCount failed or no stream available" << std::endl;
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#ifdef _WIN32
|
|||
|
|
// Windows 平台:使用新版 API ItkDevAllocStreamEx(自动分配buffer)
|
|||
|
|
status = ItkDevAllocStreamEx(m_hDevice, 0, m_nBufferCount, &m_hStream);
|
|||
|
|
if (status != ITKSTATUS_OK || m_hStream == nullptr)
|
|||
|
|
{
|
|||
|
|
std::cerr << "ItkDevAllocStreamEx failed, status: " << status << std::endl;
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 获取所有 Buffer
|
|||
|
|
m_vecBuffers.resize(m_nBufferCount);
|
|||
|
|
for (unsigned int i = 0; i < m_nBufferCount; ++i)
|
|||
|
|
{
|
|||
|
|
status = ItkStreamGetBuffer(m_hStream, i, &m_vecBuffers[i]);
|
|||
|
|
if (status != ITKSTATUS_OK)
|
|||
|
|
{
|
|||
|
|
std::cerr << "ItkStreamGetBuffer failed for index " << i << std::endl;
|
|||
|
|
ReleaseStreamAndBuffer();
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
#else
|
|||
|
|
// Linux/ARM 平台:使用旧版 API ItkDevAllocStream(需要手动创建buffer)
|
|||
|
|
// 旧版 API 需要传入单个 buffer,简化实现:使用 nullptr 让SDK自动分配
|
|||
|
|
status = ItkDevAllocStream(m_hDevice, 0, nullptr, &m_hStream);
|
|||
|
|
if (status != ITKSTATUS_OK || m_hStream == nullptr)
|
|||
|
|
{
|
|||
|
|
std::cerr << "ItkDevAllocStream failed, status: " << status << std::endl;
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// ARM 版本不支持 GetBuffer,buffer 由 SDK 内部管理
|
|||
|
|
m_vecBuffers.clear();
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int CIKapDevice::ReleaseStreamAndBuffer()
|
|||
|
|
{
|
|||
|
|
// 清空 Buffer 列表
|
|||
|
|
m_vecBuffers.clear();
|
|||
|
|
|
|||
|
|
// 释放数据流
|
|||
|
|
if (m_hStream != nullptr)
|
|||
|
|
{
|
|||
|
|
ItkDevFreeStream(m_hStream);
|
|||
|
|
m_hStream = nullptr;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int CIKapDevice::GrabSingleFrame(ImageData& imageData, unsigned int nTimeout)
|
|||
|
|
{
|
|||
|
|
if (!m_bDeviceOpened || m_hDevice == nullptr || m_hStream == nullptr)
|
|||
|
|
{
|
|||
|
|
std::cerr << "Device not opened" << std::endl;
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#ifdef _WIN32
|
|||
|
|
// Windows 平台:使用主动取图 API
|
|||
|
|
// 开始采集单帧
|
|||
|
|
ITKSTATUS status = ItkStreamStart(m_hStream, 1);
|
|||
|
|
if (status != ITKSTATUS_OK)
|
|||
|
|
{
|
|||
|
|
std::cerr << "ItkStreamStart failed, status: " << status << std::endl;
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 等待单帧图像
|
|||
|
|
ITKBUFFER hReadyBuffer = nullptr;
|
|||
|
|
status = ItkStreamWaitOneFrameReady(m_hStream, &hReadyBuffer, (long long)nTimeout);
|
|||
|
|
if (status != ITKSTATUS_OK || hReadyBuffer == nullptr)
|
|||
|
|
{
|
|||
|
|
std::cerr << "ItkStreamWaitOneFrameReady failed or timeout, status: " << status << std::endl;
|
|||
|
|
ItkStreamStop(m_hStream);
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 复制图像数据
|
|||
|
|
int ret = CopyImageData(hReadyBuffer, imageData);
|
|||
|
|
|
|||
|
|
// 清除buffer(返还给stream)
|
|||
|
|
ItkStreamClearBuffer(m_hStream, hReadyBuffer);
|
|||
|
|
|
|||
|
|
// 停止采集
|
|||
|
|
ItkStreamStop(m_hStream);
|
|||
|
|
|
|||
|
|
return ret;
|
|||
|
|
#else
|
|||
|
|
// Linux/ARM 平台:旧版 SDK 不支持 WaitOneFrameReady
|
|||
|
|
// 简化实现:返回不支持错误
|
|||
|
|
std::cerr << "GrabSingleFrame not supported on ARM platform (old SDK)" << std::endl;
|
|||
|
|
return -1;
|
|||
|
|
#endif
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int CIKapDevice::CopyImageData(ITKBUFFER hBuffer, ImageData& imageData)
|
|||
|
|
{
|
|||
|
|
if (hBuffer == nullptr)
|
|||
|
|
return -1;
|
|||
|
|
|
|||
|
|
// 获取 Buffer 信息
|
|||
|
|
ITK_BUFFER_INFO bufferInfo;
|
|||
|
|
memset(&bufferInfo, 0, sizeof(bufferInfo));
|
|||
|
|
|
|||
|
|
ITKSTATUS status = ItkBufferGetInfo(hBuffer, &bufferInfo);
|
|||
|
|
if (status != ITKSTATUS_OK)
|
|||
|
|
{
|
|||
|
|
std::cerr << "ItkBufferGetInfo failed, status: " << status << std::endl;
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 填充图像数据结构
|
|||
|
|
imageData.width = static_cast<unsigned int>(bufferInfo.ImageWidth);
|
|||
|
|
imageData.height = static_cast<unsigned int>(bufferInfo.ImageHeight);
|
|||
|
|
imageData.pixelFormat = static_cast<unsigned int>(bufferInfo.PixelFormat);
|
|||
|
|
imageData.imageSize = static_cast<unsigned int>(bufferInfo.ImageSize);
|
|||
|
|
imageData.timestamp = bufferInfo.TimestampNs;
|
|||
|
|
imageData.frameID = bufferInfo.BlockID;
|
|||
|
|
|
|||
|
|
// 分配内存并复制图像数据
|
|||
|
|
if (imageData.pData != nullptr)
|
|||
|
|
{
|
|||
|
|
delete[] imageData.pData;
|
|||
|
|
}
|
|||
|
|
imageData.pData = new unsigned char[imageData.imageSize];
|
|||
|
|
|
|||
|
|
// 使用ItkBufferRead读取数据
|
|||
|
|
status = ItkBufferRead(hBuffer, 0, imageData.pData, (uint32_t)imageData.imageSize);
|
|||
|
|
if (status != ITKSTATUS_OK)
|
|||
|
|
{
|
|||
|
|
std::cerr << "ItkBufferRead failed, status: " << status << std::endl;
|
|||
|
|
delete[] imageData.pData;
|
|||
|
|
imageData.pData = nullptr;
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int CIKapDevice::StartGrabbing(ImageCallback callback, void* pUser)
|
|||
|
|
{
|
|||
|
|
if (m_bIsGrabbing.load())
|
|||
|
|
{
|
|||
|
|
std::cerr << "Already grabbing" << std::endl;
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!m_bDeviceOpened || m_hDevice == nullptr || m_hStream == nullptr)
|
|||
|
|
{
|
|||
|
|
std::cerr << "Device not opened" << std::endl;
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (callback == nullptr)
|
|||
|
|
{
|
|||
|
|
std::cerr << "Callback is null" << std::endl;
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
m_imageCallback = callback;
|
|||
|
|
m_pUserData = pUser;
|
|||
|
|
m_bIsGrabbing.store(true);
|
|||
|
|
|
|||
|
|
// 启动采集线程
|
|||
|
|
m_grabbingThread = std::thread(&CIKapDevice::GrabbingThread, this);
|
|||
|
|
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int CIKapDevice::StopGrabbing()
|
|||
|
|
{
|
|||
|
|
if (!m_bIsGrabbing.load())
|
|||
|
|
return 0;
|
|||
|
|
|
|||
|
|
// 设置停止标志
|
|||
|
|
m_bIsGrabbing.store(false);
|
|||
|
|
|
|||
|
|
// 等待线程结束
|
|||
|
|
if (m_grabbingThread.joinable())
|
|||
|
|
{
|
|||
|
|
m_grabbingThread.join();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
m_imageCallback = nullptr;
|
|||
|
|
m_pUserData = nullptr;
|
|||
|
|
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool CIKapDevice::IsGrabbing()
|
|||
|
|
{
|
|||
|
|
return m_bIsGrabbing.load();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CIKapDevice::GrabbingThread()
|
|||
|
|
{
|
|||
|
|
// 开始连续采集
|
|||
|
|
ITKSTATUS status = ItkStreamStart(m_hStream, 0); // 0表示连续采集
|
|||
|
|
if (status != ITKSTATUS_OK)
|
|||
|
|
{
|
|||
|
|
std::cerr << "ItkStreamStart failed in thread" << std::endl;
|
|||
|
|
m_bIsGrabbing.store(false);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
while (m_bIsGrabbing.load())
|
|||
|
|
{
|
|||
|
|
// 等待图像
|
|||
|
|
ITKBUFFER hReadyBuffer = nullptr;
|
|||
|
|
status = ItkStreamWaitOneFrameReady(m_hStream, &hReadyBuffer, 1000);
|
|||
|
|
|
|||
|
|
if (status == ITKSTATUS_OK && hReadyBuffer != nullptr)
|
|||
|
|
{
|
|||
|
|
// 复制图像数据
|
|||
|
|
ImageData imageData;
|
|||
|
|
imageData.pData = nullptr;
|
|||
|
|
|
|||
|
|
if (CopyImageData(hReadyBuffer, imageData) == 0)
|
|||
|
|
{
|
|||
|
|
// 调用回调函数
|
|||
|
|
if (m_imageCallback)
|
|||
|
|
{
|
|||
|
|
m_imageCallback(imageData, m_pUserData);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 释放图像数据内存
|
|||
|
|
if (imageData.pData != nullptr)
|
|||
|
|
{
|
|||
|
|
delete[] imageData.pData;
|
|||
|
|
imageData.pData = nullptr;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 清除buffer(返还给stream继续使用)
|
|||
|
|
ItkStreamClearBuffer(m_hStream, hReadyBuffer);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 停止采集
|
|||
|
|
ItkStreamStop(m_hStream);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int CIKapDevice::SetExposureTime(double exposureTime)
|
|||
|
|
{
|
|||
|
|
if (!m_bDeviceOpened || m_hDevice == nullptr)
|
|||
|
|
{
|
|||
|
|
std::cerr << "Device not opened" << std::endl;
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
ITKSTATUS status = ItkDevSetDouble(m_hDevice, "ExposureTime", exposureTime);
|
|||
|
|
if (status != ITKSTATUS_OK)
|
|||
|
|
{
|
|||
|
|
std::cerr << "SetExposureTime failed, status: " << status << std::endl;
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int CIKapDevice::GetExposureTime(double& exposureTime)
|
|||
|
|
{
|
|||
|
|
if (!m_bDeviceOpened || m_hDevice == nullptr)
|
|||
|
|
{
|
|||
|
|
std::cerr << "Device not opened" << std::endl;
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
ITKSTATUS status = ItkDevGetDouble(m_hDevice, "ExposureTime", &exposureTime);
|
|||
|
|
if (status != ITKSTATUS_OK)
|
|||
|
|
{
|
|||
|
|
std::cerr << "GetExposureTime failed, status: " << status << std::endl;
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int CIKapDevice::SetGain(double gain)
|
|||
|
|
{
|
|||
|
|
if (!m_bDeviceOpened || m_hDevice == nullptr)
|
|||
|
|
{
|
|||
|
|
std::cerr << "Device not opened" << std::endl;
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
ITKSTATUS status = ItkDevSetDouble(m_hDevice, "Gain", gain);
|
|||
|
|
if (status != ITKSTATUS_OK)
|
|||
|
|
{
|
|||
|
|
std::cerr << "SetGain failed, status: " << status << std::endl;
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int CIKapDevice::GetGain(double& gain)
|
|||
|
|
{
|
|||
|
|
if (!m_bDeviceOpened || m_hDevice == nullptr)
|
|||
|
|
{
|
|||
|
|
std::cerr << "Device not opened" << std::endl;
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
ITKSTATUS status = ItkDevGetDouble(m_hDevice, "Gain", &gain);
|
|||
|
|
if (status != ITKSTATUS_OK)
|
|||
|
|
{
|
|||
|
|
std::cerr << "GetGain failed, status: " << status << std::endl;
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int CIKapDevice::SetTriggerMode(bool bEnable)
|
|||
|
|
{
|
|||
|
|
if (!m_bDeviceOpened || m_hDevice == nullptr)
|
|||
|
|
{
|
|||
|
|
std::cerr << "Device not opened" << std::endl;
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const char* triggerMode = bEnable ? "On" : "Off";
|
|||
|
|
ITKSTATUS status = ItkDevFromString(m_hDevice, "TriggerMode", triggerMode);
|
|||
|
|
if (status != ITKSTATUS_OK)
|
|||
|
|
{
|
|||
|
|
std::cerr << "SetTriggerMode failed, status: " << status << std::endl;
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int CIKapDevice::ExecuteSoftwareTrigger()
|
|||
|
|
{
|
|||
|
|
if (!m_bDeviceOpened || m_hDevice == nullptr)
|
|||
|
|
{
|
|||
|
|
std::cerr << "Device not opened" << std::endl;
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
ITKSTATUS status = ItkDevExecuteCommand(m_hDevice, "TriggerSoftware");
|
|||
|
|
if (status != ITKSTATUS_OK)
|
|||
|
|
{
|
|||
|
|
std::cerr << "ExecuteSoftwareTrigger failed, status: " << status << std::endl;
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int CIKapDevice::GetWidth(unsigned int& width)
|
|||
|
|
{
|
|||
|
|
if (!m_bDeviceOpened || m_hDevice == nullptr)
|
|||
|
|
{
|
|||
|
|
std::cerr << "Device not opened" << std::endl;
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int64_t value = 0;
|
|||
|
|
ITKSTATUS status = ItkDevGetInt64(m_hDevice, "Width", &value);
|
|||
|
|
if (status != ITKSTATUS_OK)
|
|||
|
|
{
|
|||
|
|
std::cerr << "GetWidth failed, status: " << status << std::endl;
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
width = static_cast<unsigned int>(value);
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int CIKapDevice::GetHeight(unsigned int& height)
|
|||
|
|
{
|
|||
|
|
if (!m_bDeviceOpened || m_hDevice == nullptr)
|
|||
|
|
{
|
|||
|
|
std::cerr << "Device not opened" << std::endl;
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int64_t value = 0;
|
|||
|
|
ITKSTATUS status = ItkDevGetInt64(m_hDevice, "Height", &value);
|
|||
|
|
if (status != ITKSTATUS_OK)
|
|||
|
|
{
|
|||
|
|
std::cerr << "GetHeight failed, status: " << status << std::endl;
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
height = static_cast<unsigned int>(value);
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int CIKapDevice::SetROI(unsigned int offsetX, unsigned int offsetY,
|
|||
|
|
unsigned int width, unsigned int height)
|
|||
|
|
{
|
|||
|
|
if (!m_bDeviceOpened || m_hDevice == nullptr)
|
|||
|
|
{
|
|||
|
|
std::cerr << "Device not opened" << std::endl;
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
ITKSTATUS status;
|
|||
|
|
|
|||
|
|
// 设置 OffsetX
|
|||
|
|
status = ItkDevSetInt64(m_hDevice, "OffsetX", offsetX);
|
|||
|
|
if (status != ITKSTATUS_OK)
|
|||
|
|
{
|
|||
|
|
std::cerr << "Set OffsetX failed" << std::endl;
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 设置 OffsetY
|
|||
|
|
status = ItkDevSetInt64(m_hDevice, "OffsetY", offsetY);
|
|||
|
|
if (status != ITKSTATUS_OK)
|
|||
|
|
{
|
|||
|
|
std::cerr << "Set OffsetY failed" << std::endl;
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 设置 Width
|
|||
|
|
status = ItkDevSetInt64(m_hDevice, "Width", width);
|
|||
|
|
if (status != ITKSTATUS_OK)
|
|||
|
|
{
|
|||
|
|
std::cerr << "Set Width failed" << std::endl;
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 设置 Height
|
|||
|
|
status = ItkDevSetInt64(m_hDevice, "Height", height);
|
|||
|
|
if (status != ITKSTATUS_OK)
|
|||
|
|
{
|
|||
|
|
std::cerr << "Set Height failed" << std::endl;
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int CIKapDevice::GetLibraryVersion(unsigned int& version)
|
|||
|
|
{
|
|||
|
|
ITKSTATUS status = ItkManGetVersion(&version);
|
|||
|
|
if (status != ITKSTATUS_OK)
|
|||
|
|
{
|
|||
|
|
std::cerr << "ItkManGetVersion failed, status: " << status << std::endl;
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return 0;
|
|||
|
|
}
|