GrabBag/SDK/Galaxy/test/GalaxyCamera.cpp

683 lines
19 KiB
C++
Raw Normal View History

2025-12-10 00:01:32 +08:00
#include "GalaxyCamera.h"
#include <cstring>
#include <algorithm>
#ifdef _WIN32
#include <windows.h>
#endif
// 静态成员初始化
bool GalaxyCamera::s_sdkInitialized = false;
int GalaxyCamera::s_instanceCount = 0;
std::mutex GalaxyCamera::s_sdkMutex;
GalaxyCamera::GalaxyCamera()
: m_pCaptureEventHandler(nullptr)
, m_bIsOpen(false)
, m_bIsStreaming(false)
, m_bHasNewFrame(false) {
std::lock_guard<std::mutex> lock(s_sdkMutex);
s_instanceCount++;
}
GalaxyCamera::~GalaxyCamera() {
try {
StopStreaming();
Close();
}
catch (...) {
// 忽略清理异常
}
std::lock_guard<std::mutex> lock(s_sdkMutex);
s_instanceCount--;
// 注意不在析构函数中反初始化SDK
// SDK应该在程序退出时统一清理或者由最后一个实际使用的相机来清理
// 因为DetectAvailableBrands会频繁创建/销毁临时实例
}
// 检查大恒SDK DLL是否可用
static bool IsGalaxySDKAvailable() {
#ifdef _WIN32
// 尝试加载大恒SDK主DLL
// 使用 LOAD_LIBRARY_AS_DATAFILE 避免触发DLL的依赖加载
HMODULE hModule = LoadLibraryExA("GxIAPI.dll", nullptr, LOAD_LIBRARY_AS_DATAFILE);
if (hModule == nullptr) {
// DLL不在PATH中或不存在
return false;
}
FreeLibrary(hModule);
// 进一步检查尝试真正加载DLL会检查依赖
hModule = LoadLibraryA("GxIAPI.dll");
if (hModule == nullptr) {
// DLL存在但依赖项缺失如缺少MSVCP140D.dll
return false;
}
FreeLibrary(hModule);
return true;
#else
return true; // 非Windows平台假设可用
#endif
}
bool GalaxyCamera::Init(const std::string& sdkPath) {
(void)sdkPath;
std::lock_guard<std::mutex> lock(s_sdkMutex);
// 如果SDK已经初始化直接返回成功
if (s_sdkInitialized) {
return true;
}
// 首先检查SDK DLL是否可用
if (!IsGalaxySDKAvailable()) {
return false;
}
try {
// 尝试获取工厂实例并初始化
IGXFactory& factory = IGXFactory::GetInstance();
factory.Init();
s_sdkInitialized = true;
return true;
}
catch (CGalaxyException& e) {
(void)e;
s_sdkInitialized = false;
return false;
}
catch (std::exception& e) {
(void)e;
s_sdkInitialized = false;
return false;
}
catch (...) {
// 捕获所有其他异常
s_sdkInitialized = false;
return false;
}
}
std::vector<DeviceInfo> GalaxyCamera::Discover() {
std::vector<DeviceInfo> devices;
m_vectorDeviceInfo.clear();
if (!s_sdkInitialized) {
return devices;
}
try {
// 枚举设备超时1000ms
IGXFactory::GetInstance().UpdateDeviceList(1000, m_vectorDeviceInfo);
for (uint32_t i = 0; i < m_vectorDeviceInfo.size(); i++) {
DeviceInfo appDevInfo;
// 获取设备序列号作为ID
appDevInfo.id = m_vectorDeviceInfo[i].GetSN().c_str();
// 获取设备显示名称
appDevInfo.name = m_vectorDeviceInfo[i].GetDisplayName().c_str();
// 标记品牌
appDevInfo.brand = "Galaxy";
devices.push_back(appDevInfo);
}
}
catch (CGalaxyException& e) {
(void)e;
}
catch (std::exception& e) {
(void)e;
}
return devices;
}
bool GalaxyCamera::Open(const std::string& deviceID) {
if (m_bIsOpen) {
Close();
}
if (!s_sdkInitialized) {
return false;
}
bool bIsDeviceOpen = false;
bool bIsStreamOpen = false;
try {
// 通过序列号打开设备
m_objDevicePtr = IGXFactory::GetInstance().OpenDeviceBySN(
deviceID.c_str(), GX_ACCESS_EXCLUSIVE);
bIsDeviceOpen = true;
// 获取远程属性控制器
m_objFeatureControlPtr = m_objDevicePtr->GetRemoteFeatureControl();
// 设置采集模式为连续采集
m_objFeatureControlPtr->GetEnumFeature("AcquisitionMode")->SetValue("Continuous");
// 设置触发模式为关(软件触发时先关闭,后续按需开启)
m_objFeatureControlPtr->GetEnumFeature("TriggerMode")->SetValue("Off");
// 获取设备流个数
int nStreamCount = m_objDevicePtr->GetStreamCount();
if (nStreamCount > 0) {
m_objStreamPtr = m_objDevicePtr->OpenStream(0);
m_objStreamFeatureControlPtr = m_objStreamPtr->GetFeatureControl();
bIsStreamOpen = true;
}
else {
throw std::exception("未发现设备流!");
}
// 对于GigE相机设置最优包长
GX_DEVICE_CLASS_LIST objDeviceClass = m_objDevicePtr->GetDeviceInfo().GetDeviceClass();
if (GX_DEVICE_CLASS_GEV == objDeviceClass) {
if (m_objFeatureControlPtr->IsImplemented("GevSCPSPacketSize")) {
int nPacketSize = m_objStreamPtr->GetOptimalPacketSize();
m_objFeatureControlPtr->GetIntFeature("GevSCPSPacketSize")->SetValue(nPacketSize);
}
}
// 创建采集回调处理器
m_pCaptureEventHandler = new CaptureEventHandler(this);
m_bIsOpen = true;
return true;
}
catch (CGalaxyException& e) {
(void)e;
if (bIsStreamOpen && !m_objStreamPtr.IsNull()) {
m_objStreamPtr->Close();
}
if (bIsDeviceOpen && !m_objDevicePtr.IsNull()) {
m_objDevicePtr->Close();
}
m_bIsOpen = false;
return false;
}
catch (std::exception& e) {
(void)e;
if (bIsStreamOpen && !m_objStreamPtr.IsNull()) {
m_objStreamPtr->Close();
}
if (bIsDeviceOpen && !m_objDevicePtr.IsNull()) {
m_objDevicePtr->Close();
}
m_bIsOpen = false;
return false;
}
}
void GalaxyCamera::Close() {
if (!m_bIsOpen) {
return;
}
try {
// 停止采集
StopStreaming();
// 关闭流对象
if (!m_objStreamPtr.IsNull()) {
m_objStreamPtr->Close();
}
// 关闭设备
if (!m_objDevicePtr.IsNull()) {
m_objDevicePtr->Close();
}
}
catch (CGalaxyException&) {
// 忽略关闭异常
}
catch (std::exception&) {
// 忽略关闭异常
}
// 释放回调处理器
if (m_pCaptureEventHandler != nullptr) {
delete m_pCaptureEventHandler;
m_pCaptureEventHandler = nullptr;
}
m_bIsOpen = false;
}
bool GalaxyCamera::SetROI(int x, int y, int w, int h) {
if (!m_bIsOpen || m_objFeatureControlPtr.IsNull()) {
return false;
}
try {
// 获取最大宽高
int64_t widthMax = m_objFeatureControlPtr->GetIntFeature("WidthMax")->GetValue();
int64_t heightMax = m_objFeatureControlPtr->GetIntFeature("HeightMax")->GetValue();
// 基本验证
if (w <= 0 || h <= 0 || x < 0 || y < 0 ||
(x + w) > widthMax || (y + h) > heightMax) {
return false;
}
// 大恒相机ROI通常需要是4的倍数
w = (w / 4) * 4;
h = (h / 4) * 4;
x = (x / 4) * 4;
y = (y / 4) * 4;
if (w <= 0) w = 4;
if (h <= 0) h = 4;
// 设置ROI
m_objFeatureControlPtr->GetIntFeature("Width")->SetValue(w);
m_objFeatureControlPtr->GetIntFeature("Height")->SetValue(h);
m_objFeatureControlPtr->GetIntFeature("OffsetX")->SetValue(x);
m_objFeatureControlPtr->GetIntFeature("OffsetY")->SetValue(y);
return true;
}
catch (CGalaxyException& e) {
(void)e;
return false;
}
catch (std::exception& e) {
(void)e;
return false;
}
}
bool GalaxyCamera::StartStreaming(FrameCallback callback) {
if (!m_bIsOpen || m_bIsStreaming) {
return false;
}
try {
// 保存回调函数
m_frameCallback = callback;
// 设置Buffer处理模式
try {
m_objStreamFeatureControlPtr->GetEnumFeature("StreamBufferHandlingMode")->SetValue("OldestFirst");
}
catch (...) {
// 部分相机可能不支持此特性,忽略
}
// 注册采集回调
m_objStreamPtr->RegisterCaptureCallback(m_pCaptureEventHandler, this);
// 开启流层采集
m_objStreamPtr->StartGrab();
// 发送开采命令
m_objFeatureControlPtr->GetCommandFeature("AcquisitionStart")->Execute();
m_bIsStreaming = true;
return true;
}
catch (CGalaxyException& e) {
(void)e;
// 清理
try {
m_objStreamPtr->StopGrab();
m_objStreamPtr->UnregisterCaptureCallback();
}
catch (...) {}
m_bIsStreaming = false;
return false;
}
catch (std::exception& e) {
(void)e;
try {
m_objStreamPtr->StopGrab();
m_objStreamPtr->UnregisterCaptureCallback();
}
catch (...) {}
m_bIsStreaming = false;
return false;
}
}
void GalaxyCamera::StopStreaming() {
if (!m_bIsOpen || !m_bIsStreaming) {
return;
}
try {
// 发送停采命令
m_objFeatureControlPtr->GetCommandFeature("AcquisitionStop")->Execute();
// 关闭流层采集
m_objStreamPtr->StopGrab();
// 注销回调函数
m_objStreamPtr->UnregisterCaptureCallback();
}
catch (CGalaxyException&) {
// 忽略异常
}
catch (std::exception&) {
// 忽略异常
}
m_bIsStreaming = false;
m_bHasNewFrame = false;
}
bool GalaxyCamera::IsStreaming() const {
return m_bIsStreaming;
}
bool GalaxyCamera::GrabCurrentFrame(ImageBuffer& out) {
if (!m_bIsStreaming) {
return false;
}
std::lock_guard<std::mutex> lock(m_frameMutex);
if (!m_latestFramePtr || m_latestFramePtr->data.empty()) {
return false;
}
// 复制最新帧数据
out = *m_latestFramePtr;
m_bHasNewFrame = false;
return true;
}
bool GalaxyCamera::Capture(ImageBuffer& out) {
if (!m_bIsOpen) {
return false;
}
// 如果正在流模式使用GrabCurrentFrame
if (m_bIsStreaming) {
return GrabCurrentFrame(out);
}
try {
// 单帧采集模式
// 开启流层采集
m_objStreamPtr->StartGrab();
// 发送开采命令
m_objFeatureControlPtr->GetCommandFeature("AcquisitionStart")->Execute();
// 获取一帧图像超时5000ms
CImageDataPointer objImageDataPointer = m_objStreamPtr->GetImage(5000);
if (objImageDataPointer.IsNull()) {
m_objFeatureControlPtr->GetCommandFeature("AcquisitionStop")->Execute();
m_objStreamPtr->StopGrab();
return false;
}
// 检查图像状态
if (objImageDataPointer->GetStatus() != GX_FRAME_STATUS_SUCCESS) {
m_objFeatureControlPtr->GetCommandFeature("AcquisitionStop")->Execute();
m_objStreamPtr->StopGrab();
return false;
}
// 转换图像数据
out.width = static_cast<int>(objImageDataPointer->GetWidth());
out.height = static_cast<int>(objImageDataPointer->GetHeight());
out.pixelFormat = convertPixelFormat(objImageDataPointer->GetPixelFormat());
// 计算数据大小
size_t dataSize = objImageDataPointer->GetPayloadSize();
out.data.resize(dataSize);
// 复制图像数据
void* pBuffer = objImageDataPointer->GetBuffer();
if (pBuffer) {
std::memcpy(out.data.data(), pBuffer, dataSize);
}
// 停止采集
m_objFeatureControlPtr->GetCommandFeature("AcquisitionStop")->Execute();
m_objStreamPtr->StopGrab();
return true;
}
catch (CGalaxyException& e) {
(void)e;
try {
m_objFeatureControlPtr->GetCommandFeature("AcquisitionStop")->Execute();
m_objStreamPtr->StopGrab();
}
catch (...) {}
return false;
}
catch (std::exception& e) {
(void)e;
try {
m_objFeatureControlPtr->GetCommandFeature("AcquisitionStop")->Execute();
m_objStreamPtr->StopGrab();
}
catch (...) {}
return false;
}
}
bool GalaxyCamera::GetIntValue(const std::string& name, int& value) {
if (!m_bIsOpen || m_objFeatureControlPtr.IsNull()) {
return false;
}
try {
// 映射参数名称
std::string gxName = name;
if (name == "Width" || name == "Height" ||
name == "OffsetX" || name == "OffsetY") {
// 直接使用
}
value = static_cast<int>(m_objFeatureControlPtr->GetIntFeature(gxName.c_str())->GetValue());
return true;
}
catch (CGalaxyException&) {
return false;
}
catch (std::exception&) {
return false;
}
}
bool GalaxyCamera::SetIntValue(const std::string& name, int value) {
if (!m_bIsOpen || m_objFeatureControlPtr.IsNull()) {
return false;
}
try {
m_objFeatureControlPtr->GetIntFeature(name.c_str())->SetValue(value);
return true;
}
catch (CGalaxyException&) {
return false;
}
catch (std::exception&) {
return false;
}
}
bool GalaxyCamera::GetFloatValue(const std::string& name, float& value) {
if (!m_bIsOpen || m_objFeatureControlPtr.IsNull()) {
return false;
}
try {
// 映射参数名称到大恒SDK参数名
std::string gxName = name;
if (name == "ExposureTime") {
gxName = "ExposureTime";
}
else if (name == "Gain") {
gxName = "Gain";
}
value = static_cast<float>(m_objFeatureControlPtr->GetFloatFeature(gxName.c_str())->GetValue());
return true;
}
catch (CGalaxyException&) {
return false;
}
catch (std::exception&) {
return false;
}
}
bool GalaxyCamera::SetFloatValue(const std::string& name, float value) {
if (!m_bIsOpen || m_objFeatureControlPtr.IsNull()) {
return false;
}
try {
// 映射参数名称
std::string gxName = name;
if (name == "ExposureTime") {
gxName = "ExposureTime";
}
else if (name == "Gain") {
gxName = "Gain";
}
m_objFeatureControlPtr->GetFloatFeature(gxName.c_str())->SetValue(value);
return true;
}
catch (CGalaxyException&) {
return false;
}
catch (std::exception&) {
return false;
}
}
bool GalaxyCamera::IsConnected() {
return m_bIsOpen && !m_objDevicePtr.IsNull();
}
void GalaxyCamera::Cleanup() {
Close();
}
void GalaxyCamera::UninitSDK() {
std::lock_guard<std::mutex> lock(s_sdkMutex);
if (s_sdkInitialized) {
try {
IGXFactory::GetInstance().Uninit();
s_sdkInitialized = false;
}
catch (...) {
// 忽略清理异常
}
}
}
// 采集回调处理
void GalaxyCamera::CaptureEventHandler::DoOnImageCaptured(
CImageDataPointer& objImageDataPointer, void* pUserParam) {
try {
GalaxyCamera* pCamera = static_cast<GalaxyCamera*>(pUserParam);
if (pCamera) {
pCamera->processFrame(objImageDataPointer);
}
}
catch (CGalaxyException&) {
// 忽略异常
}
catch (std::exception&) {
// 忽略异常
}
}
void GalaxyCamera::processFrame(CImageDataPointer& objImageDataPointer) {
if (objImageDataPointer.IsNull()) {
return;
}
// 检查图像状态
if (objImageDataPointer->GetStatus() != GX_FRAME_STATUS_SUCCESS) {
return;
}
try {
// 创建新的图像缓冲区
auto newFrame = std::make_shared<ImageBuffer>();
newFrame->width = static_cast<int>(objImageDataPointer->GetWidth());
newFrame->height = static_cast<int>(objImageDataPointer->GetHeight());
newFrame->pixelFormat = convertPixelFormat(objImageDataPointer->GetPixelFormat());
// 获取图像数据大小
size_t dataSize = objImageDataPointer->GetPayloadSize();
newFrame->data.resize(dataSize);
// 复制图像数据
void* pBuffer = objImageDataPointer->GetBuffer();
if (pBuffer) {
std::memcpy(newFrame->data.data(), pBuffer, dataSize);
}
// 更新最新帧
{
std::lock_guard<std::mutex> lock(m_frameMutex);
m_latestFramePtr = newFrame;
m_bHasNewFrame = true;
}
// 调用用户回调
if (m_frameCallback) {
m_frameCallback(newFrame);
}
}
catch (std::exception&) {
// 忽略异常
}
}
PixelFormat GalaxyCamera::convertPixelFormat(GX_PIXEL_FORMAT_ENTRY gxFormat) {
switch (gxFormat) {
case GX_PIXEL_FORMAT_MONO8:
return PixelFormat::Mono8;
case GX_PIXEL_FORMAT_MONO10:
return PixelFormat::Mono10;
case GX_PIXEL_FORMAT_MONO12:
return PixelFormat::Mono12;
case GX_PIXEL_FORMAT_MONO16:
return PixelFormat::Mono16;
case GX_PIXEL_FORMAT_BAYER_RG8:
return PixelFormat::BayerRG8;
case GX_PIXEL_FORMAT_BAYER_GB8:
return PixelFormat::BayerGB8;
case GX_PIXEL_FORMAT_BAYER_GR8:
return PixelFormat::BayerGR8;
case GX_PIXEL_FORMAT_BAYER_BG8:
return PixelFormat::BayerBG8;
default:
// 对于未知格式默认返回Mono8
return PixelFormat::Mono8;
}
}