@@ -17,7 +17,7 @@ vtkStandardNewMacro(vtkPlusAndorVideoSource);
1717
1818// put these here so there is no public dependence on OpenCV
1919cv::Mat cvCameraIntrinsics;
20- cv::Mat cvDistanceCoefficients ;
20+ cv::Mat cvDistortionCoefficients ;
2121cv::Mat cvBadPixelImage;
2222cv::Mat cvFlatCorrection;
2323cv::Mat cvBiasDarkCorrection;
@@ -45,7 +45,7 @@ void vtkPlusAndorVideoSource::PrintSelf(ostream& os, vtkIndent indent)
4545 os << indent << " SafeTemperature: " << SafeTemperature << std::endl;
4646 os << indent << " CurrentTemperature: " << CurrentTemperature << std::endl;
4747 os << indent << " CameraIntrinsics: " << cvCameraIntrinsics << std::endl;
48- os << indent << " DistanceCoefficients : " << cvDistanceCoefficients << std::endl;
48+ os << indent << " DistortionCoefficients : " << cvDistortionCoefficients << std::endl;
4949 os << indent << " UseFrameCorrections: " << UseFrameCorrections << std::endl;
5050 os << indent << " UseCosmicRayCorrection: " << UseCosmicRayCorrection << std::endl;
5151 os << indent << " FlatCorrection: " << flatCorrection << std::endl;
@@ -134,13 +134,13 @@ PlusStatus vtkPlusAndorVideoSource::ReadConfiguration(vtkXMLDataElement* rootCon
134134 deviceConfig->GetVectorAttribute (" HSSpeed" , 2 , HSSpeed);
135135 deviceConfig->GetVectorAttribute (" OutputSpacing" , 3 , OutputSpacing);
136136 deviceConfig->GetVectorAttribute (" CameraIntrinsics" , 9 , cameraIntrinsics);
137- deviceConfig->GetVectorAttribute (" DistanceCoefficients " , 4 , distanceCoefficients );
137+ deviceConfig->GetVectorAttribute (" DistortionCoefficients " , 4 , distortionCoefficients );
138138 badPixelCorrection = deviceConfig->GetAttribute (" BadPixelCorrection" );
139139 flatCorrection = deviceConfig->GetAttribute (" FlatCorrection" );
140140 biasDarkCorrection = deviceConfig->GetAttribute (" BiasDarkCorrection" );
141141
142142 cvCameraIntrinsics = cv::Mat (3 , 3 , CV_64FC1, cameraIntrinsics);
143- cvDistanceCoefficients = cv::Mat (1 , 4 , CV_64FC1, distanceCoefficients );
143+ cvDistortionCoefficients = cv::Mat (1 , 4 , CV_64FC1, distortionCoefficients );
144144 this ->SetBadPixelCorrectionImage (badPixelCorrection); // load the image
145145 this ->SetFlatCorrectionImage (flatCorrection); // load and normalize if needed
146146 this ->SetBiasDarkCorrectionImage (biasDarkCorrection); // load the image
@@ -169,7 +169,7 @@ PlusStatus vtkPlusAndorVideoSource::WriteConfiguration(vtkXMLDataElement* rootCo
169169 deviceConfig->SetVectorAttribute (" HSSpeed" , 2 , HSSpeed);
170170 deviceConfig->SetVectorAttribute (" OutputSpacing" , 3 , OutputSpacing);
171171 deviceConfig->SetVectorAttribute (" CameraIntrinsics" , 9 , cameraIntrinsics);
172- deviceConfig->SetVectorAttribute (" DistanceCoefficients " , 4 , distanceCoefficients );
172+ deviceConfig->SetVectorAttribute (" DistortionCoefficients " , 4 , distortionCoefficients );
173173 deviceConfig->SetAttribute (" FlatCorrection" , flatCorrection.c_str ());
174174 deviceConfig->SetAttribute (" BiasDarkCorrection" , biasDarkCorrection.c_str ());
175175 deviceConfig->SetAttribute (" BadPixelCorrection" , badPixelCorrection.c_str ());
@@ -367,6 +367,9 @@ PlusStatus vtkPlusAndorVideoSource::InternalDisconnect()
367367 // WaitForWarmup();
368368 // }
369369
370+ // in case we quit before an acquisition is complete, close the acquisition thread
371+ AbortAcquisition ();
372+
370373 checkStatus (FreeInternalMemory (), " FreeInternalMemory" );
371374
372375 unsigned result = checkStatus (ShutDown (), " ShutDown" );
@@ -487,32 +490,26 @@ void vtkPlusAndorVideoSource::WaitForWarmup()
487490}
488491
489492// ----------------------------------------------------------------------------
490- PlusStatus vtkPlusAndorVideoSource::AcquireFrame (float exposure, ShutterMode shutterMode, int binning, int vsSpeed, int hsSpeed )
493+ PlusStatus vtkPlusAndorVideoSource::AcquireFrame ()
491494{
492- checkStatus (::SetExposureTime (exposure), " SetExposureTime" );
493- checkStatus (::SetShutter (1 , shutterMode, 0 , 0 ), " SetShutter" );
494-
495- int hbin = binning > 0 ? binning : this ->HorizontalBins ;
496- int vbin = binning > 0 ? binning : this ->VerticalBins ;
497- checkStatus (::SetImage (hbin, vbin, 1 , 1024 , 1 , 1024 ), " Binning" );
498- AdjustBuffers (hbin, vbin);
499-
500- AdjustSpacing (hbin, vbin);
501-
502- int vsInd = vsSpeed >= 0 ? vsSpeed : this ->VSSpeed ;
503- checkStatus (::SetVSSpeed (vsInd), " SetVSSpeed" );
495+ checkStatus (::SetExposureTime (this ->effectiveExpTime ), " SetExposureTime" );
496+ checkStatus (::SetShutter (1 , this ->effectiveShutter , 0 , 0 ), " SetShutter" );
497+ checkStatus (::SetImage (this ->effectiveHBins , this ->effectiveVBins , 1 , 1024 , 1 , 1024 ), " Binning" );
498+ checkStatus (::SetVSSpeed (this ->effectiveVSInd ), " SetVSSpeed" );
499+ checkStatus (::SetHSSpeed (this ->HSSpeed [0 ], this ->effectiveHSInd ), " SetHSSpeed" );
504500
505- int hsInd = hsSpeed >= 0 ? hsSpeed : this ->HSSpeed [ 1 ] ;
506- checkStatus (:: SetHSSpeed ( this ->HSSpeed [ 0 ], hsInd), " SetHSSpeed " );
501+ AdjustBuffers ( this -> effectiveHBins , this ->effectiveVBins ) ;
502+ AdjustSpacing ( this ->effectiveHBins , this -> effectiveVBins );
507503
508504 unsigned rawFrameSize = frameSize[0 ] * frameSize[1 ];
509505 rawFrame.resize (rawFrameSize, 0 );
510506
511507 checkStatus (StartAcquisition (), " StartAcquisition" );
512508 unsigned result = checkStatus (WaitForAcquisition (), " WaitForAcquisition" );
513- if (result == DRV_NO_NEW_DATA) // Log a more specific log message for WaitForAcquisition
509+ if (result != DRV_SUCCESS)
514510 {
515- LOG_ERROR (" Non-Acquisition Event occurred.(e.g. CancelWait() called)" );
511+ LOG_ERROR (" Acquisition failed or cancelled." );
512+ return PLUS_FAIL;
516513 }
517514 this ->currentTime = vtkIGSIOAccurateTimer::GetSystemTime ();
518515
@@ -690,7 +687,7 @@ void vtkPlusAndorVideoSource::ApplyFrameCorrections(int binning, float exposureT
690687 }
691688
692689 // OpenCV's lens distortion correction
693- cv::undistort (floatImage, result, cvCameraIntrinsics, cvDistanceCoefficients );
690+ cv::undistort (floatImage, result, cvCameraIntrinsics, cvDistortionCoefficients );
694691 LOG_INFO (" Applied lens distortion correction" );
695692
696693 // Divide the image by the 32-bit floating point correction image
@@ -703,53 +700,149 @@ void vtkPlusAndorVideoSource::ApplyFrameCorrections(int binning, float exposureT
703700}
704701
705702// ----------------------------------------------------------------------------
706- PlusStatus vtkPlusAndorVideoSource::AcquireBLIFrame (int binning, int vsSpeed, int hsSpeed, float exposureTime)
703+ PlusStatus vtkPlusAndorVideoSource::StartBLIFrameAcquisition (int binning, int vsSpeed, int hsSpeed, float exposureTime)
704+ {
705+ if (this ->threadID > -1 )
706+ {
707+ LOG_ERROR (" An acquisition thread is already running!" );
708+ return PLUS_FAIL;
709+ }
710+
711+ this ->effectiveHBins = binning > 0 ? binning : this ->HorizontalBins ;
712+ this ->effectiveVBins = binning > 0 ? binning : this ->VerticalBins ;
713+ this ->effectiveVSInd = vsSpeed > -1 ? vsSpeed : this ->VSSpeed ;
714+ this ->effectiveHSInd = hsSpeed > -1 ? hsSpeed : this ->HSSpeed [1 ];
715+ this ->effectiveExpTime = exposureTime > -1 ? exposureTime : this ->ExposureTime ;
716+ this ->effectiveShutter = ShutterMode::FullyAuto;
717+
718+ this ->threadID = this ->Threader ->SpawnThread ((vtkThreadFunctionType)&vtkPlusAndorVideoSource::AcquireBLIFrameThread, this );
719+ return PLUS_SUCCESS;
720+ }
721+
722+ // ----------------------------------------------------------------------------
723+ void * vtkPlusAndorVideoSource::AcquireBLIFrameThread (vtkMultiThreader::ThreadInfo* info)
707724{
708- WaitForCooldown ();
709- AcquireFrame (exposureTime, ShutterMode::FullyAuto, binning, vsSpeed, hsSpeed);
710- ++this ->FrameNumber ;
711- AddFrameToDataSource (BLIRaw);
725+ vtkPlusAndorVideoSource* device = static_cast <vtkPlusAndorVideoSource*>(info->UserData );
712726
713- if (this ->UseFrameCorrections )
727+ device->WaitForCooldown ();
728+ if (device->AcquireFrame () == PLUS_FAIL)
714729 {
715- ApplyFrameCorrections (binning, exposureTime) ;
716- AddFrameToDataSource (BLICorrected) ;
730+ device-> threadID = - 1 ;
731+ return NULL ;
717732 }
733+ ++device->FrameNumber ;
734+ device->AddFrameToDataSource (device->BLIRaw );
718735
736+ if (device->UseFrameCorrections )
737+ {
738+ device->ApplyFrameCorrections (device->effectiveHBins , device->effectiveExpTime );
739+ device->AddFrameToDataSource (device->BLICorrected );
740+ }
741+
742+ device->threadID = -1 ;
743+ return NULL ;
744+ }
745+
746+ // ----------------------------------------------------------------------------
747+ PlusStatus vtkPlusAndorVideoSource::StartGrayscaleFrameAcquisition (int binning, int vsSpeed, int hsSpeed, float exposureTime)
748+ {
749+ if (this ->threadID > -1 )
750+ {
751+ LOG_ERROR (" An acquisition thread is already running!" );
752+ return PLUS_FAIL;
753+ }
754+
755+ this ->effectiveHBins = binning > 0 ? binning : this ->HorizontalBins ;
756+ this ->effectiveVBins = binning > 0 ? binning : this ->VerticalBins ;
757+ this ->effectiveVSInd = vsSpeed > -1 ? vsSpeed : this ->VSSpeed ;
758+ this ->effectiveHSInd = hsSpeed > -1 ? hsSpeed : this ->HSSpeed [1 ];
759+ this ->effectiveExpTime = exposureTime > -1 ? exposureTime : this ->ExposureTime ;
760+ this ->effectiveShutter = ShutterMode::FullyAuto;
761+
762+ this ->threadID = this ->Threader ->SpawnThread ((vtkThreadFunctionType)&vtkPlusAndorVideoSource::AcquireGrayscaleFrameThread, this );
719763 return PLUS_SUCCESS;
764+
720765}
721766
722767// ----------------------------------------------------------------------------
723- PlusStatus vtkPlusAndorVideoSource::AcquireGrayscaleFrame ( int binning, int vsSpeed, int hsSpeed, float exposureTime )
768+ void * vtkPlusAndorVideoSource::AcquireGrayscaleFrameThread (vtkMultiThreader::ThreadInfo* info )
724769{
725- WaitForCooldown ();
726- AcquireFrame (exposureTime, ShutterMode::FullyAuto, binning, vsSpeed, hsSpeed);
727- ++this ->FrameNumber ;
728- AddFrameToDataSource (GrayRaw);
770+ vtkPlusAndorVideoSource* device = static_cast <vtkPlusAndorVideoSource*>(info->UserData );
771+
772+ device->WaitForCooldown ();
773+ if (device->AcquireFrame () == PLUS_FAIL)
774+ {
775+ device->threadID = -1 ;
776+ return NULL ;
777+ }
778+ ++device->FrameNumber ;
779+ device->AddFrameToDataSource (device->GrayRaw );
729780
730- if (this ->UseFrameCorrections )
781+ if (device ->UseFrameCorrections )
731782 {
732- ApplyFrameCorrections (binning, exposureTime );
733- AddFrameToDataSource (GrayCorrected);
783+ device-> ApplyFrameCorrections (device-> effectiveHBins , device-> effectiveExpTime );
784+ device-> AddFrameToDataSource (device-> GrayCorrected );
734785 }
735786
787+ device->threadID = -1 ;
788+ return NULL ;
789+ }
790+
791+ // ----------------------------------------------------------------------------
792+ PlusStatus vtkPlusAndorVideoSource::StartCorrectionFrameAcquisition (const std::string correctionFilePath, ShutterMode shutter, int binning, int vsSpeed, int hsSpeed, float exposureTime)
793+ {
794+ if (this ->threadID > -1 )
795+ {
796+ LOG_ERROR (" An acquisition thread is already running!" );
797+ return PLUS_FAIL;
798+ }
799+
800+ this ->effectiveHBins = binning > 0 ? binning : this ->HorizontalBins ;
801+ this ->effectiveVBins = binning > 0 ? binning : this ->VerticalBins ;
802+ this ->effectiveVSInd = vsSpeed > -1 ? vsSpeed : this ->VSSpeed ;
803+ this ->effectiveHSInd = hsSpeed > -1 ? hsSpeed : this ->HSSpeed [1 ];
804+ this ->effectiveExpTime = exposureTime > -1 ? exposureTime : this ->ExposureTime ;
805+ this ->effectiveShutter = ShutterMode::FullyAuto;
806+ this ->saveCorrectionPath = correctionFilePath;
807+
808+ this ->threadID = this ->Threader ->SpawnThread ((vtkThreadFunctionType)&vtkPlusAndorVideoSource::AcquireCorrectionFrameThread, this );
736809 return PLUS_SUCCESS;
737810}
738811
739812// ----------------------------------------------------------------------------
740- PlusStatus vtkPlusAndorVideoSource::AcquireCorrectionFrame ( const std::string correctionFilePath, ShutterMode shutter, int binning, int vsSpeed, int hsSpeed, float exposureTime )
813+ void * vtkPlusAndorVideoSource::AcquireCorrectionFrameThread (vtkMultiThreader::ThreadInfo* info )
741814{
742- AcquireFrame (exposureTime, shutter, binning, vsSpeed, hsSpeed);
743- ++this ->FrameNumber ;
815+ vtkPlusAndorVideoSource* device = static_cast <vtkPlusAndorVideoSource*>(info->UserData );
744816
745- cv::Mat cvIMG (frameSize[0 ], frameSize[1 ], CV_16UC1, &rawFrame[0 ]); // uses rawFrame as buffer
746- if (this ->UseFrameCorrections )
817+ if (device->AcquireFrame () == PLUS_FAIL)
747818 {
748- CorrectBadPixels (binning, cvIMG);
819+ device->threadID = -1 ;
820+ return NULL ;
821+ }
822+ ++device->FrameNumber ;
823+
824+ cv::Mat cvIMG (device->frameSize [0 ], device->frameSize [1 ], CV_16UC1, &(device->rawFrame [0 ])); // uses rawFrame as buffer
825+ if (device->UseFrameCorrections )
826+ {
827+ device->CorrectBadPixels (device->effectiveHBins , cvIMG);
749828 LOG_INFO (" Applied bad pixel correction" );
750829 }
751830
752- cv::imwrite (correctionFilePath, cvIMG);
831+ cv::imwrite (device->saveCorrectionPath , cvIMG);
832+ device->threadID = -1 ;
833+ return NULL ;
834+ }
835+
836+ // -----------------------------------------------------------------------------
837+ PlusStatus vtkPlusAndorVideoSource::AbortAcquisition ()
838+ {
839+ checkStatus (::CancelWait (), " CancelWait" );
840+ unsigned result = checkStatus (::AbortAcquisition (), " AbortAcquisition" );
841+ if ((result != DRV_SUCCESS) && (result != DRV_IDLE))
842+ {
843+ LOG_ERROR (" Unable to abort acquisition." );
844+ return PLUS_FAIL;
845+ }
753846 return PLUS_SUCCESS;
754847}
755848
@@ -1012,17 +1105,17 @@ std::array<double, 9> vtkPlusAndorVideoSource::GetCameraIntrinsics()
10121105}
10131106
10141107// ----------------------------------------------------------------------------
1015- PlusStatus vtkPlusAndorVideoSource::SetDistanceCoefficients (std::array<double , 4 > coefficients)
1108+ PlusStatus vtkPlusAndorVideoSource::SetDistortionCoefficients (std::array<double , 4 > coefficients)
10161109{
1017- std::copy (std::begin (coefficients), std::end (coefficients), this ->distanceCoefficients );
1110+ std::copy (std::begin (coefficients), std::end (coefficients), this ->distortionCoefficients );
10181111 return PLUS_SUCCESS;
10191112}
10201113
10211114// ----------------------------------------------------------------------------
1022- std::array<double , 4 > vtkPlusAndorVideoSource::GetDistanceCoefficients ()
1115+ std::array<double , 4 > vtkPlusAndorVideoSource::GetDistortionCoefficients ()
10231116{
10241117 std::array<double , 4 > returnCoefficients;
1025- std::copy (this ->distanceCoefficients , this ->distanceCoefficients + 4 , std::begin (returnCoefficients));
1118+ std::copy (this ->distortionCoefficients , this ->distortionCoefficients + 4 , std::begin (returnCoefficients));
10261119 return returnCoefficients;
10271120}
10281121
@@ -1153,6 +1246,22 @@ int vtkPlusAndorVideoSource::GetSafeTemperature()
11531246 return this ->SafeTemperature ;
11541247}
11551248
1249+ // ----------------------------------------------------------------------------
1250+ unsigned int vtkPlusAndorVideoSource::GetCCDStatus ()
1251+ {
1252+ int status;
1253+ GetStatus (&status);
1254+
1255+ return status;
1256+ }
1257+
1258+ // ----------------------------------------------------------------------------
1259+ bool vtkPlusAndorVideoSource::IsCCDAcquiring ()
1260+ {
1261+ int status = GetCCDStatus ();
1262+ return status == DRV_ACQUIRING;
1263+ }
1264+
11561265// ----------------------------------------------------------------------------
11571266unsigned int vtkPlusAndorVideoSource::checkStatus (unsigned int returnStatus, std::string functionName)
11581267{
0 commit comments