#include "Hd_CameraModule_Basler_soft.h" #include "qfuture.h" #include QQueue queuepic; Pylon::DeviceInfoList_t m_devices; static int FrameID = 0; static const size_t c_maxCamerasToUse = 2; // Smart pointer to camera features Pylon::CIntegerParameter m_exposureTime; //曝光 Pylon::CIntegerParameter m_gain; //增益 // The grab result retrieved from the camera. Pylon::CGrabResultPtr m_ptrGrabResult; bool m_invertImage=true; // The grab result as a windows DIB to be displayed on the screen. Pylon::CPylonBitmapImage m_bitmapImage; bool ifGetImage = false; bool ifmoduleRun = true; //判断是否为彩色相机 bool IsColor(EPixelType enType) { switch (enType) { case PixelType_RGB8packed: case PixelType_BayerGR8: case PixelType_BayerRG8: case PixelType_BayerGB8: case PixelType_BayerBG8: case PixelType_BayerGR10: case PixelType_BayerRG10: case PixelType_BayerGB10: case PixelType_BayerBG10: case PixelType_BayerGR12: case PixelType_BayerRG12: case PixelType_BayerGB12: case PixelType_BayerBG12: case PixelType_RGB10packed: case PixelType_BGR10packed: case PixelType_RGB12packed: case PixelType_BGR12packed: case PixelType_YUV422_YUYV_Packed: case PixelType_BayerGR12Packed: case PixelType_BayerRG12Packed: case PixelType_BayerGB12Packed: case PixelType_BayerBG12Packed: return true; default: return false; } } //搜索设备 int Hd_CameraModule_Basler_soft::SearchDevice() { CTlFactory& tlFactory = CTlFactory::GetInstance(); DeviceInfoList_t devices; //找到所有相机 if (tlFactory.EnumerateDevices(devices) == 0) { qDebug() << "No camera present"; } m_devices = devices; // Fill the combo box. int mindex = 0; for (Pylon::DeviceInfoList_t::const_iterator it = m_devices.begin(); it != m_devices.end(); ++it) { // Get the pointer to the current device info. const Pylon::CDeviceInfo* const pDeviceInfo = &(*it); // Add the friendly name to the list. Pylon::String_t friendlyName = pDeviceInfo->GetFriendlyName(); std::string s = friendlyName; //Basler raL4096-24gm (24731776);cam0 (23593460) //std:cout << s << std::endl; if (s == Username) { index = mindex; break; } mindex++; } return (int)devices.size(); } //回调函数 //当有新图像可用时,从CInstantCamera抓取线程调用此函数。 //在此处执行图像处理。 //之后,我们将把图像转换为RGB位图,并通知GUI关于新图像的信息。 // //注意:您不能访问任何UI对象,因为此函数不是从GUI线程调用的。 //为了更新GUI,我们将在该功能结束时向主窗口发布一条消息。 //GUI线程将处理消息并更新GUI。 void Hd_CameraModule_Basler_soft::OnImageGrabbed(Pylon::CInstantCamera& camera, const CGrabResultPtr& grabResult) { // The following line is commented out as this function will be called very often // filling up the debug output. //TRACE(_T("%s\n"), __FUNCTIONW__); // When overwriting the current CGrabResultPtr, the previous result will automatically be // released and reused by CInstantCamera. double time_Start = (double)clock(); //m_ptrGrabResult = grabResult; //CBaslerUniversalGrabResultPtr ptrGrabResult;CGrabResultPtr // First check whether the smart pointer is valid. // Then call GrabSucceeded() on the CGrabResultData to test whether the grab resulut conatains // an sucessfully grabbed image. // In case of i.e. transmission errors the result may be invalid if (grabResult.IsValid() && grabResult->GrabSucceeded()) { // This is where you would do image processing // and do other tasks. // --- Start of sample image processing --- (only works for 8-bit formats) if (m_invertImage && grabResult->GetPixelType() == PixelType_Mono8) { srcImage = cv::Mat(grabResult->GetHeight(), grabResult->GetWidth(), CV_8UC1, grabResult->GetBuffer()); //size_t imageSize = Pylon::ComputeBufferSize(grabResult->GetPixelType(), grabResult->GetWidth(), grabResult->GetHeight(), grabResult->GetPaddingX()); //uint8_t* p = reinterpret_cast(grabResult->GetBuffer()); //uint8_t* const pEnd = p + (imageSize / sizeof(uint8_t)); //for (; p < pEnd; ++p) //{ // *p = 255 - *p; //For demonstration purposes only, invert the image. //} } else if (m_invertImage && grabResult->GetPixelType() == PixelType_BGR8packed) { srcImage = cv::Mat(grabResult->GetHeight(), grabResult->GetWidth(), CV_8UC3, grabResult->GetBuffer()); } else if (IsColor(grabResult->GetPixelType())) { // Create a target image. CPylonImage targetImage; // Create the converter and set parameters. CImageFormatConverter converter; converter.OutputPixelFormat = PixelType_BGR8packed; // Now we can check if conversion is required. if (converter.ImageHasDestinationFormat(grabResult)) { ; } else { converter.Convert(targetImage, grabResult); } srcImage = cv::Mat(targetImage.GetHeight(), targetImage.GetWidth(), CV_8UC3, targetImage.GetBuffer()); } //++m_cntGrabbedImages; ifGetImage = true; } else { // If the grab result is invalid, we also mark the bitmap as invalid. m_bitmapImage.Release(); ifGetImage = false; // The some TLs provide an error code why the grab failed. //TRACE(_T("%s Grab failed. Error code. %x\n"), __FUNCTIONW__, (int)grabResult->GetErrorCode()); //CSingleLock lockErrorCount(&m_MemberLock, TRUE); //++m_cntGrabErrors; //lockErrorCount.Unlock(); } // Tell the main window that there is a new image available so it can update the image window. double time_End = (double)clock(); qDebug() << "[INFO] " " srcImage Exist,Time:" << (time_End - time_Start) / 1.0 << "ms" << "--CameraName:" << QString::fromStdString(Username) << "--FrameID : " << FrameID++; } //断线回调 // This will be called when the camera has been removed/disconnected. // We'll post a message to the GUI about this event and return. // In response to this message, the GUI will be updated and the camera will be closed. void Hd_CameraModule_Basler_soft::OnCameraDeviceRemoved(Pylon::CInstantCamera& camera) { moduleStatus = false; qDebug() << "[Hd_CameraModule_Basler_soft] " << " Camera disconnected! try auto connect"; //运行重连线程 QFuture future2 = QtConcurrent::run(this, &Hd_CameraModule_Basler_soft::reConnctDevice); } //OnImageGrabbed和OnCameraDeviceRemoved函数,相机创建时自动绑定;相机释放时,自动解除绑定。 //重连 bool Hd_CameraModule_Basler_soft::reConnctDevice() { m_camera->StopGrabbing(); m_camera->DestroyDevice(); m_camera->Close(); delete m_camera; m_camera = nullptr; while (1) { if (ifmoduleRun == false) return false; Sleep(100); //m_mutex->lock(); if (ConnctDevice() == true) { qWarning() << "[Hd_CameraModule_Basler_soft] " << " Camera create success again! "; moduleStatus = true; //m_mutex->unlock(); return true; } } } //连接设备 bool Hd_CameraModule_Basler_soft::ConnctDevice() { index = -1; SearchDevice(); if (index < 0) return false; m_camera = new CBaslerUniversalInstantCamera; //因为用的new方式 { // Register this object as an image event handler in order to get notified of new images. // See Pylon::CImageEventHandler for details. m_camera->RegisterImageEventHandler(this, Pylon::RegistrationMode_ReplaceAll, Pylon::Cleanup_None); // Register this object as a configuration event handler in order to get notified of camera state changes. // See Pylon::CConfigurationEventHandler for details. m_camera->RegisterConfiguration(new Pylon::CAcquireContinuousConfiguration(), Pylon::RegistrationMode_ReplaceAll, Pylon::Cleanup_Delete); m_camera->RegisterConfiguration(this, Pylon::RegistrationMode_Append, Pylon::Cleanup_None); } // Get the pointer to Pylon::CDeviceInfo selected. const Pylon::CDeviceInfo* pDeviceInfo = &m_devices[index];// (const Pylon::CDeviceInfo*)m_cameraBox.GetItemData(index); try { // Add the AutoPacketSizeConfiguration and let pylon delete it when not needed anymore. //m_camera->RegisterConfiguration(new CAutoPacketSizeConfiguration(), Pylon::RegistrationMode_Append, Pylon::Cleanup_Delete); // Create the device and attach it to CInstantCamera. // Let CInstantCamera take care of destroying the device. Pylon::IPylonDevice* pDevice = Pylon::CTlFactory::GetInstance().CreateDevice(*pDeviceInfo); m_camera->Attach(pDevice, Pylon::Cleanup_Delete); if (m_camera->IsPylonDeviceAttached() == false) return false; // Open camera. m_camera->Open(); //设置心跳;快速进断线回调函数 CIntegerParameter heartbeat(m_camera->GetTLNodeMap(), "HeartbeatTimeout"); heartbeat.TrySetValue(1000, IntegerValueCorrection_Nearest); // set to 1000 ms timeout if writable ////设置曝光,GigE相机为ExposureTimeRaw;USB相机为ExposureTime;方法可行,断电不保存 //if (m_camera->ExposureTime.IsValid()) //{ // m_camera->ExposureTime.GetAlternativeIntegerRepresentation(m_exposureTime); // int64_t myExposureTimeRaw=m_camera->ExposureTimeRaw.GetValue(); // m_camera->ExposureTimeRaw.SetValue(20); //} //else if (m_camera->ExposureTimeRaw.IsValid()) //{ // m_exposureTime.Attach(m_camera->ExposureTimeRaw.GetNode()); // m_camera->ExposureTimeRaw.SetValue(20); //} //线扫相机,设置增益有问题 ////设置增益,GigE相机为GainRaw;USB相机为Gain //if (m_camera->Gain.IsValid()) //{ // m_camera->Gain.GetAlternativeIntegerRepresentation(m_gain); // m_camera->Gain.SetValue(2); //} //else if (m_camera->GainRaw.IsValid()) //{ // m_gain.Attach(m_camera->GainRaw.GetNode()); // m_camera->GainRaw.SetValue(2); //} //这几行会把相机设置重置 //像素格式 //m_camera->RegisterCameraEventHandler(this, "PixelFormat", 0, Pylon::RegistrationMode_Append, Pylon::Cleanup_None, Pylon::CameraEventAvailability_Optional); //触发模式 //m_camera->RegisterCameraEventHandler(this, "TriggerMode", 0, Pylon::RegistrationMode_Append, Pylon::Cleanup_None, Pylon::CameraEventAvailability_Optional); //触发源 //m_camera->RegisterCameraEventHandler(this, "TriggerSource", 0, Pylon::RegistrationMode_Append, Pylon::Cleanup_None, Pylon::CameraEventAvailability_Optional); //触发模式 m_camera->TriggerSource.SetValue( Basler_UniversalCameraParams::TriggerSource_Software); //触发源 m_camera->TriggerMode.SetValue(Basler_UniversalCameraParams::TriggerMode_On); //m_camera->PixelFormat.SetValue();// //连续采集 // Camera may have been disconnected. if (!m_camera->IsOpen() || m_camera->IsGrabbing()) { return false; } // Try set continuous frame mode if available m_camera->AcquisitionMode.TrySetValue(Basler_UniversalCameraParams::AcquisitionMode_Continuous); // Start grabbing until StopGrabbing() is called. m_camera->StartGrabbing(Pylon::GrabStrategy_OneByOne, Pylon::GrabLoop_ProvidedByInstantCamera); qDebug() << "[StartGrabbing] " << " basler camera StartGrabbing!"; } catch (const Pylon::GenericException& e) { qDebug() << "[error] " << " basler camera disconnects!"; return false; } return true; ////创建相机对象(以最先识别的相机) ////camera = CTlFactory::GetInstance().CreateFirstDevice(); //CInstantCameraArray cameras(min(devices.size(), c_maxCamerasToUse)); //// 打印相机的名称 ////std::cout << "Using device " << camera.GetDeviceInfo().GetModelName() << endl; // ////获取相机节点映射以获得相机参数 //GenApi::INodeMap& nodemap = camera.GetNodeMap(); ////打开相机 //camera.Open(); ////加载用户集,相机设置应当userset1 //camera.UserSetSelector.SetValue(UserSetSelector_UserSet1); //camera.RegisterImageEventHandler(new CSampleImageEventHandler, RegistrationMode_Append, Cleanup_Delete); //camera.RegisterExceptionCallBack(); // 设置相机参数 /*GenApi::cenumerationptr ptracquisitionmode = camera.getparameter("acquisitionmode"); ptracquisitionmode->fromstring("continuous"); genapi::cenumerationptr ptrtriggerselector = camera.getparameter("triggerselector"); ptrtriggerselector->fromstring("framestart"); genapi::cenumerationptr ptrtriggermode = camera.getparameter("triggermode"); ptrtriggermode->fromstring("on"); genapi::cenumerationptr ptrtriggersource = camera.getparameter("triggersource"); ptrtriggersource->fromstring("software"); CIntegerParameter heartbeat( camera.GetTLNodeMap(), "HeartbeatTimeout" ); heartbeat.TrySetValue( 1000, IntegerValueCorrection_Nearest ); */ } //错误 void Hd_CameraModule_Basler_soft::OnGrabError(Pylon::CInstantCamera& camera, const char* errorMessage) { std::cout << "Hd_CameraModule_Basler_soft err:: " << errorMessage << std::endl; moduleStatus = false; } Hd_CameraModule_Basler_soft* create() { qDebug() << "[info] " << "Hd_CameraModule_Basler_soft create success!"; return new Hd_CameraModule_Basler_soft; } void destory(Hd_CameraModule_Basler_soft* ptr) { if (ptr) { delete ptr; ptr = nullptr; } qDebug() << "[info] " << "Hd_CameraModule_Basler_soft destory success!"; } Hd_CameraModule_Basler_soft::Hd_CameraModule_Basler_soft() { PylonInitialize(); m_mutex = new QMutex(); } //关闭设备 void Hd_CameraModule_Basler_soft::CloseDevice() { m_camera->StopGrabbing(); //m_bitmapImage.Release(); //// Free the grab result, if present. //m_ptrGrabResult.Release(); //// Remove the event handlers that will be called when the feature changes. //m_camera->DeregisterCameraEventHandler(this, "TriggerSource"); //m_camera->DeregisterCameraEventHandler(this, "TriggerMode"); //m_camera->DeregisterCameraEventHandler(this, "PixelFormat"); //if (m_gain.IsValid()) //{ // // If we must use the alternative integer representation, we don't know the name of the node as it defined by the camera // m_camera->DeregisterCameraEventHandler(this, m_gain.GetNode()->GetName()); //} //if (m_exposureTime.IsValid()) //{ // // If we must use the alternative integer representation, we don't know the name of the node as it defined by the camera // m_camera->DeregisterCameraEventHandler(this, m_exposureTime.GetNode()->GetName()); //} //// Clear the pointers to the features we set manually in Open(). //m_exposureTime.Release(); //m_gain.Release(); // Close the camera and free all ressources. // This will also unregister all m_camera->DestroyDevice(); m_camera->Close(); delete m_camera; m_camera = nullptr; //m_camera->ClearBufferModeEnable(); /*camera.StopGrabbing(); camera.DestroyDevice(); camera.Close();*/ } Hd_CameraModule_Basler_soft::~Hd_CameraModule_Basler_soft() { ifmoduleRun = false; m_mutex->lock(); CloseDevice(); m_mutex->unlock(); //PylonTerminate(); if (m_mutex) { delete m_mutex; m_mutex = nullptr; } qDebug() << "[info] " << " delete success!"; } //从类中读数据到实例对象 bool Hd_CameraModule_Basler_soft::readData(std::vector& mat, QByteArray& data) { int timeCnt = 0; while (srcImage.empty()) { //qCritical() << "[INFO] " << " srcImage is null!"; QThread::msleep(1); timeCnt++; if(timeCnt>1000) return false; } mat.push_back(srcImage); return true; } //实例对象把数据写入到类 bool Hd_CameraModule_Basler_soft::writeData(std::vector& mat, QByteArray& data) { Q_UNUSED(mat) m_flag = false; Username = data.toStdString(); return true; } bool Hd_CameraModule_Basler_soft::initParas(QByteArray&) { return true; return ConnctDevice(); } bool Hd_CameraModule_Basler_soft::run() { bool result = false; ifGetImage = false; try { m_mutex->lock(); if (!m_camera->IsGrabbing()) { m_mutex->unlock(); return result; } //软触发一次 // Only wait if software trigger is currently turned on. if (m_camera->TriggerSource.GetValue() == Basler_UniversalCameraParams::TriggerSource_Software && m_camera->TriggerMode.GetValue() == Basler_UniversalCameraParams::TriggerMode_On) { // If the camera is currently processing a previous trigger command, // it will silently discard trigger commands. // We wait until the camera is ready to process the next trigger. if (moduleStatus == false) { m_mutex->unlock(); return result; } if (m_camera->WaitForFrameTriggerReady(3000, Pylon::TimeoutHandling_ThrowException) == true) { // Send trigger m_camera->ExecuteSoftwareTrigger(); } else { m_mutex->unlock(); return result; } } else { m_mutex->unlock(); return result; } int timeOut = 0; while (1) { if (ifGetImage == true) { result = true; break; } if (timeOut++ > 3000 || moduleStatus ==false) { result = false; break; } //else //{ // result = true; // break; //} Sleep(1); } } catch (...) { qDebug() << "[error] " << " Hd_CameraModule_Basler_soft:" ; } m_mutex->unlock(); return result; } //相机连接状态:正常连接或断开 bool Hd_CameraModule_Basler_soft::checkStatus() { //m_mutex->lock(); //status = modulestatus; return moduleStatus; //m_mutex->unlock(); }