8 #include "PlusConfigure.h" 9 #include "igsioTrackedFrame.h" 10 #include "vtkIGSIOTrackedFrameList.h" 13 #include <PlaneParametersEstimator.h> 17 #include <itkBinaryThresholdImageFilter.h> 18 #include <itkImageDuplicator.h> 19 #include <itkImageFileWriter.h> 20 #include <itkImageRegionIterator.h> 21 #include <itkLineIterator.h> 22 #include <itkOtsuThresholdImageFilter.h> 23 #include <itkRGBPixel.h> 24 #include <itkResampleImageFilter.h> 25 #include <itkRescaleIntensityImageFilter.h> 28 #include <vtkChartXY.h> 29 #include <vtkContextScene.h> 30 #ifdef PLUS_RENDERING_ENABLED 31 #include <vtkContextView.h> 33 #include <vtkDoubleArray.h> 34 #include <vtkIntArray.h> 35 #include <vtkObjectFactory.h> 39 #include <vtkRenderWindow.h> 40 #include <vtkRenderWindowInteractor.h> 41 #include <vtkRenderer.h> 65 this->Superclass::PrintSelf(os, indent);
70 : m_TrackedFrameList(vtkSmartPointer<vtkIGSIOTrackedFrameList>::New())
71 , m_SaveIntermediateImages(false)
72 , IntermediateFilesOutputDirectory(
"")
73 , PlotIntensityProfile(false)
74 , m_SignalTimeRangeMin(0.0)
75 , m_SignalTimeRangeMax(-1.0)
127 LOG_ERROR(
"vtkPlusLineSegmentationAlgo video input data verification failed: no frames");
134 LOG_ERROR(
"vtkPlusLineSegmentationAlgo video input data verification failed: video data orientation or type is not supported (MF orientation, BRIGHTNESS type is expected)");
139 int totalNumberOfInvalidVideoFrames = 0;
140 int greatestNumberOfConsecutiveInvalidVideoFrames = 0;
141 int currentNumberOfConsecutiveInvalidVideoFrames = 0;
151 if (!trackedFrame->GetImageData()->IsImageValid())
153 ++totalNumberOfInvalidVideoFrames;
154 ++currentNumberOfConsecutiveInvalidVideoFrames;
158 if (currentNumberOfConsecutiveInvalidVideoFrames > greatestNumberOfConsecutiveInvalidVideoFrames)
160 greatestNumberOfConsecutiveInvalidVideoFrames = currentNumberOfConsecutiveInvalidVideoFrames ;
162 currentNumberOfConsecutiveInvalidVideoFrames = 0;
166 double percentageOfInvalidVideoFrames = totalNumberOfInvalidVideoFrames / static_cast<double>(
m_TrackedFrameList->GetNumberOfTrackedFrames());
169 LOG_WARNING(
"In vtkPlusLineSegmentationAlgo " << 100 * percentageOfInvalidVideoFrames <<
"% of the video frames were invalid. This warning " <<
171 "accuracy of the computed time offset may be marginalised");
176 LOG_WARNING(
"In vtkPlusLineSegmentationAlgo there were " << greatestNumberOfConsecutiveInvalidVideoFrames <<
" invalid video frames in a row. This warning " <<
178 "accuracy of the computed time offset may be marginalised");
199 int numberOfSuccessfulLineSegmentations = 0;
201 for (
unsigned int frameNumber = 0; frameNumber <
m_TrackedFrameList->GetNumberOfTrackedFrames(); ++frameNumber)
203 LOG_TRACE(
"Calculating video position metric for frame " << frameNumber);
208 LOG_TRACE(
"Skip frame, it is out of the valid signal range");
213 if (trackedFrame->GetImageData()->GetVTKScalarPixelType() != VTK_UNSIGNED_CHAR)
215 LOG_ERROR(
"vtkPlusLineSegmentationAlgo::ComputeVideoPositionMetric only supports 8-bit images");
218 auto localImage = CharImageType::New();
219 PlusCommon::DeepCopyVtkVolumeToItkImage<CharPixelType>(trackedFrame->GetImageData()->GetImage(), localImage);
220 if (localImage.IsNull())
223 LOG_ERROR(
"vtkPlusLineSegmentationAlgo::ComputeVideoPositionMetric failed to retrieve image data from frame");
228 typedef itk::ImageDuplicator<CharImageType> DuplicatorType;
229 auto duplicator = DuplicatorType::New();
230 CharImageType::Pointer scanlineImage;
233 duplicator->SetInputImage(localImage);
234 duplicator->Update();
237 scanlineImage = duplicator->GetOutput();
240 std::vector<itk::Point<double, 2> > intensityPeakPositions;
241 CharImageType::RegionType region = localImage->GetLargestPossibleRegion();
244 int numOfValidScanlines = 0;
249 CharImageType::IndexType startPixel;
250 double scanlineSpacingPix = static_cast<double>(region.GetSize()[0] - 1) / (
NUMBER_OF_SCANLINES - 1);
251 startPixel[0] = region.GetIndex()[0] + scanlineSpacingPix * (currScanlineNum);
252 startPixel[1] = region.GetIndex()[1];
255 CharImageType::IndexType endPixel;
256 endPixel[0] = startPixel[0];
257 endPixel[1] = startPixel[1] + region.GetSize()[1] - 1;
259 std::deque<int> intensityProfile;
260 itk::LineIterator<CharImageType> it(localImage, startPixel, endPixel);
263 itk::LineIterator<CharImageType>* itScanlineImage = NULL;
268 itScanlineImage =
new itk::LineIterator<CharImageType>(scanlineImage, startPixel, endPixel);
269 itScanlineImage->GoToBegin();
272 while (!it.IsAtEnd())
274 intensityProfile.push_back((
int)it.Get());
278 itScanlineImage->Set(255);
279 ++(*itScanlineImage);
285 if (itScanlineImage != NULL)
287 delete itScanlineImage;
288 itScanlineImage = NULL;
298 int maxFromLargestArea = -1;
299 int maxFromLargestAreaIndex = -1;
300 int startOfMaxArea = -1;
303 double currPeakPos_y = -1;
328 itk::Point<double, 2> currPeakPos;
329 currPeakPos[0] = static_cast<double>(startPixel[0]);
330 currPeakPos[1] = startPixel[1] + currPeakPos_y;
331 intensityPeakPositions.push_back(currPeakPos);
332 ++numOfValidScanlines;
341 LOG_DEBUG(
"Only " << numOfValidScanlines <<
" valid scanlines; this is less than the required " <<
MINIMUM_NUMBER_OF_VALID_SCANLINES <<
". Skipping frame" << frameNumber);
348 LOG_DEBUG(
"Unable to compute line parameters for frame " << frameNumber);
355 LOG_TRACE(
"Line on frame " << frameNumber <<
" is too close to vertical, skip the frame");
359 ++numberOfSuccessfulLineSegmentations;
373 numOfValidScanlines, intensityPeakPositions);
378 double segmentationSuccessRate = double(numberOfSuccessfulLineSegmentations) /
m_TrackedFrameList->GetNumberOfTrackedFrames();
381 LOG_WARNING(
"Line segmentation success rate is very low (" << segmentationSuccessRate * 100 <<
"%): a line could only be detected on " << numberOfSuccessfulLineSegmentations <<
" frames out of " <<
m_TrackedFrameList->GetNumberOfTrackedFrames());
398 double startPeakValue = maxFromLargestArea * 0.5;
400 int pixelIndex = startOfMaxArea;
402 while (intensityProfile.at(pixelIndex) <= startPeakValue)
407 startOfPeak = --pixelIndex;
415 int currentLargestArea = 0;
417 int currentMaxFromLargestArea = 0;
418 int currentMaxFromLargestAreaIndex = 0;
420 int currentMaxIndex = 0;
421 bool underPeak =
false;
422 int currentStartOfMaxArea = 0;
423 int currentStart = 0;
425 if (intensityProfile.size() == 0)
427 LOG_ERROR(
"Intensity contains no elements");
431 double intensityMax = intensityProfile.at(0);
432 for (
unsigned int pixelLoc = 1; pixelLoc < intensityProfile.size(); ++pixelLoc)
434 if (intensityProfile.at(pixelLoc) > intensityMax)
436 intensityMax = intensityProfile.at(pixelLoc);
442 for (
unsigned int pixelLoc = 0; pixelLoc < intensityProfile.size(); ++pixelLoc)
444 if (intensityProfile.at(pixelLoc) > peakIntensityThreshold && !underPeak)
448 currentMax = intensityProfile.at(pixelLoc);
449 currentMaxIndex = pixelLoc;
450 currentArea = intensityProfile.at(pixelLoc);
451 currentStart = pixelLoc;
453 else if (intensityProfile.at(pixelLoc) > peakIntensityThreshold && underPeak)
456 currentArea += intensityProfile.at(pixelLoc);
458 if (intensityProfile.at(pixelLoc) > currentMax)
460 currentMax = intensityProfile.at(pixelLoc);
461 currentMaxIndex = pixelLoc;
464 else if (intensityProfile.at(pixelLoc) < peakIntensityThreshold && underPeak)
468 if (currentArea > currentLargestArea)
470 currentLargestArea = currentArea;
471 currentMaxFromLargestArea = currentMax;
472 currentMaxFromLargestAreaIndex = currentMaxIndex;
473 currentStartOfMaxArea = currentStart;
478 maxFromLargestArea = currentMaxFromLargestArea;
479 maxFromLargestAreaIndex = currentMaxFromLargestAreaIndex;
480 startOfMaxArea = currentStartOfMaxArea;
482 if (currentLargestArea == 0)
494 if (intensityProfile.size() == 0)
499 double intensityMax = intensityProfile.at(0);
500 for (
unsigned int pixelLoc = 1; pixelLoc < intensityProfile.size(); ++pixelLoc)
502 if (intensityProfile.at(pixelLoc) > intensityMax)
504 intensityMax = intensityProfile.at(pixelLoc);
510 int pixelLoc = startOfMaxArea;
511 int pointsInPeak = 0;
512 double intensitySum = 0;
513 while (intensityProfile.at(pixelLoc) > peakIntensityThreshold)
515 intensitySum += pixelLoc * intensityProfile.at(pixelLoc);
516 pointsInPeak += intensityProfile.at(pixelLoc);
520 if (pointsInPeak == 0)
525 centerOfGravity = intensitySum / pointsInPeak;
535 std::vector<double> ransacParameterResult;
536 typedef itk::PlaneParametersEstimator<DIMENSION> PlaneEstimatorType;
537 typedef itk::RANSAC<itk::Point<double, DIMENSION>,
double> RANSACType;
540 double maximalDistanceFromPlane = 0.5;
541 auto planeEstimator = PlaneEstimatorType::New();
542 planeEstimator->SetDelta(maximalDistanceFromPlane);
543 planeEstimator->LeastSquaresEstimate(
data, ransacParameterResult);
544 if (ransacParameterResult.empty())
546 LOG_DEBUG(
"Unable to fit line through points with least squares estimation");
550 LOG_TRACE(
"Least squares line parameters (n, a):");
553 LOG_TRACE(
" LS parameter: " << ransacParameterResult[
i]);
558 double desiredProbabilityForNoOutliers = 0.999;
559 auto ransacEstimator = RANSACType::New();
563 ransacEstimator->SetData(
data);
565 catch (std::exception& e)
573 ransacEstimator->SetParametersEstimator(planeEstimator.GetPointer());
575 catch (std::exception& e)
584 ransacEstimator->Compute(ransacParameterResult, desiredProbabilityForNoOutliers);
586 catch (std::exception& e)
592 if (ransacParameterResult.empty())
594 LOG_DEBUG(
"Unable to fit line through points with RANSAC, line segmentation failed");
598 LOG_TRACE(
"RANSAC line fitting parameters (n, a):");
602 LOG_TRACE(
" RANSAC parameter: " << ransacParameterResult[
i]);
617 typedef itk::RGBPixel<unsigned char> rgbPixelType;
618 typedef itk::Image<rgbPixelType, 2> rgbImageType;
619 auto rgbImageCopy = rgbImageType::New();
621 CharImageType::RegionType fullImageRegion = scanlineImage->GetLargestPossibleRegion();
623 rgbImageType::IndexType
start;
624 start[0] = fullImageRegion.GetIndex()[0];
625 start[1] = fullImageRegion.GetIndex()[0];
626 rgbImageType::SizeType size;
627 size[0] = fullImageRegion.GetSize()[0];
628 size[1] = fullImageRegion.GetSize()[1];
629 rgbImageType::RegionType region;
630 region.SetIndex(
start);
631 region.SetSize(size);
632 rgbImageCopy->SetRegions(region);
633 rgbImageCopy->Allocate();
636 for (
unsigned int x_coord = region.GetIndex()[0]; x_coord < region.GetSize()[0]; ++x_coord)
638 for (
unsigned int y_coord = region.GetIndex()[1]; y_coord < region.GetSize()[1]; ++y_coord)
640 rgbImageType::IndexType currRgbImageIndex;
641 currRgbImageIndex[0] = x_coord;
642 currRgbImageIndex[1] = y_coord;
644 CharImageType::IndexType currLocalImageIndex;
645 currLocalImageIndex[0] = x_coord;
646 currLocalImageIndex[1] = y_coord;
648 CharPixelType currLocalImagePixelVal = scanlineImage->GetPixel(currLocalImageIndex);
649 rgbPixelType currRgbImagePixelVal;
650 currRgbImagePixelVal.Set(currLocalImagePixelVal, currLocalImagePixelVal, currLocalImagePixelVal);
651 rgbImageCopy->SetPixel(currRgbImageIndex, currRgbImagePixelVal);
655 float diag = sqrtf((
float)(size[0] * size[0] + size[1] * size[1]));
658 for (
int i = static_cast<int>(-diag); i < static_cast<int>(diag); ++
i)
660 rgbImageType::IndexType currIndex;
661 currIndex[0] = static_cast<int>(x_0 +
i * r_x);
662 currIndex[1] = static_cast<int>(y_0 +
i * r_y);
664 if (fullImageRegion.IsInside(currIndex))
666 rgbPixelType currRgbImagePixelVal;
667 currRgbImagePixelVal.Set(0, 0, 255);
668 rgbImageCopy->SetPixel(currIndex, currRgbImagePixelVal);
673 for (
int scanLineIndex = 0; scanLineIndex < numOfValidScanlines; ++scanLineIndex)
675 unsigned int sqareCenterCoordX = static_cast<unsigned int>(intensityPeakPositions.at(scanLineIndex).GetElement(0));
676 unsigned int sqareCenterCoordY = static_cast<unsigned int>(intensityPeakPositions.at(scanLineIndex).GetElement(1));
678 for (
unsigned int x = sqareCenterCoordX - 3;
x < sqareCenterCoordX + 3; ++
x)
680 for (
unsigned int y = sqareCenterCoordY - 3;
y < sqareCenterCoordY + 3; ++
y)
682 rgbImageType::IndexType currIndex;
686 rgbPixelType currRgbImagePixelVal;
687 currRgbImagePixelVal.Set(0, 0, 255);
689 rgbImageCopy->SetPixel(currIndex, currRgbImagePixelVal);
694 std::ostringstream rgbImageFilename;
699 rgbImageFilename <<
"LineSegmentationResult_" << std::setw(3) << std::setfill(
'0') << frameNumber <<
".png" << std::ends;
701 typedef itk::ImageFileWriter<rgbImageType> rgbImageWriterType;
702 auto rgbImageWriter = rgbImageWriterType::New();
704 rgbImageWriter->SetFileName(rgbImageFilename.str());
705 rgbImageWriter->SetInput(rgbImageCopy);
708 rgbImageWriter->Update();
710 catch (itk::ExceptionObject& e)
712 LOG_ERROR(
"Failed to write intermediate image in line segmentation algorithm, check if the destination directory exists: " << rgbImageFilename.str() <<
"\n" << e);
716 LOG_DEBUG(
"Line segmentation intermediate image is saved to: " << rgbImageFilename.str());
736 #ifdef PLUS_RENDERING_ENABLED 738 vtkSmartPointer<vtkTable> table = vtkSmartPointer<vtkTable>::New();
741 vtkSmartPointer<vtkIntArray> arrPixelPositions = vtkSmartPointer<vtkIntArray>::New();
742 arrPixelPositions->SetName(
"Pixel Positions");
743 table->AddColumn(arrPixelPositions);
746 vtkSmartPointer<vtkIntArray> arrIntensityProfile = vtkSmartPointer<vtkIntArray>::New();
747 arrIntensityProfile->SetName(
"Intensity Profile");
748 table->AddColumn(arrIntensityProfile);
751 table->SetNumberOfRows(intensityValues.size());
752 for (
unsigned int i = 0;
i < intensityValues.size(); ++
i)
754 table->SetValue(
i, 0,
i);
755 table->SetValue(
i, 1, (intensityValues.at(
i)));
759 vtkSmartPointer<vtkContextView> view = vtkSmartPointer<vtkContextView>::New();
760 view->GetRenderer()->SetBackground(1.0, 1.0, 1.0);
763 vtkSmartPointer<vtkChartXY> chart = vtkSmartPointer<vtkChartXY>::New();
764 view->GetScene()->AddItem(chart);
765 vtkPlot*
line = chart->AddPlot(vtkChart::LINE);
767 line->SetInputData(table, 0, 1);
769 line->SetColor(0, 255, 0, 255);
771 line = chart->AddPlot(vtkChart::LINE);
774 view->GetInteractor()->Initialize();
775 view->GetInteractor()->Start();
777 LOG_ERROR(
"Function not available when VTK_RENDERING_BACKEND is None!");
784 #ifdef PLUS_RENDERING_ENABLED 786 vtkSmartPointer<vtkTable> table = vtkSmartPointer<vtkTable>::New();
789 vtkSmartPointer<vtkDoubleArray> arrPixelPositions = vtkSmartPointer<vtkDoubleArray>::New();
790 arrPixelPositions->SetName(
"Pixel Positions");
791 table->AddColumn(arrPixelPositions);
794 vtkSmartPointer<vtkDoubleArray> arrIntensityProfile = vtkSmartPointer<vtkDoubleArray>::New();
795 arrIntensityProfile->SetName(
"Intensity Profile");
796 table->AddColumn(arrIntensityProfile);
799 table->SetNumberOfRows(intensityValues.size());
800 for (
unsigned int i = 0;
i < intensityValues.size(); ++
i)
802 table->SetValue(
i, 0,
i);
803 table->SetValue(
i, 1, (intensityValues.at(
i)));
807 vtkSmartPointer<vtkContextView> view = vtkSmartPointer<vtkContextView>::New();
808 view->GetRenderer()->SetBackground(1.0, 1.0, 1.0);
811 vtkSmartPointer<vtkChartXY> chart = vtkSmartPointer<vtkChartXY>::New();
812 view->GetScene()->AddItem(chart);
813 vtkPlot*
line = chart->AddPlot(vtkChart::LINE);
815 line->SetInputData(table, 0, 1);
817 line->SetColor(0, 255, 0, 255);
819 line = chart->AddPlot(vtkChart::LINE);
822 view->GetInteractor()->Initialize();
823 view->GetInteractor()->Start();
825 LOG_ERROR(
"Function not available when VTK_RENDERING_BACKEND is None!");
866 CharImageType::IndexValueType clipRectangleOrigin[2] =
871 CharImageType::SizeValueType clipRectangleSize[2] =
878 CharImageType::IndexType imageOrigin = region.GetIndex();
879 CharImageType::SizeType imageSize = region.GetSize();
880 if (clipRectangleOrigin[0] < imageOrigin[0]
881 || clipRectangleOrigin[1] < imageOrigin[1]
882 || clipRectangleOrigin[0] >= imageOrigin[0] + static_cast<CharImageType::OffsetValueType>(imageSize[0])
883 || clipRectangleOrigin[1] >= imageOrigin[1] + static_cast<CharImageType::OffsetValueType>(imageSize[1]))
885 LOG_WARNING(
"ClipRectangleOrigin is invalid (" << clipRectangleOrigin[0] <<
", " << clipRectangleOrigin[1] <<
886 "). The frame size is " 887 << imageSize[0] <<
"x" << imageSize[1] <<
889 << imageOrigin[0] <<
"," << imageOrigin[1] <<
890 ") as ClipRectangleOrigin.");
891 clipRectangleOrigin[0] = 0;
892 clipRectangleOrigin[1] = 0;
894 if (clipRectangleOrigin[0] + clipRectangleSize[0] >= imageOrigin[0] + imageSize[0])
897 clipRectangleSize[0] = imageOrigin[0] + imageSize[0] - clipRectangleOrigin[0];
898 LOG_WARNING(
"Adjusting ClipRectangleSize x to " << clipRectangleSize[0]);
900 if (clipRectangleOrigin[1] + clipRectangleSize[1] > imageSize[1])
903 clipRectangleSize[1] = imageOrigin[1] + imageSize[1] - clipRectangleOrigin[1];
904 LOG_WARNING(
"Adjusting ClipRectangleSize y to " << clipRectangleSize[1]);
907 if ((clipRectangleSize[0] <= 0) || (clipRectangleSize[1] <= 0))
914 imageOrigin[0] = clipRectangleOrigin[0];
915 imageOrigin[1] = clipRectangleOrigin[1];
916 imageSize[0] = clipRectangleSize[0];
917 imageSize[1] = clipRectangleSize[1];
918 region.SetIndex(imageOrigin);
919 region.SetSize(imageSize);
925 XML_FIND_NESTED_ELEMENT_REQUIRED(lineSegmentationElement, aConfig,
"vtkPlusLineSegmentationAlgo");
927 XML_READ_BOOL_ATTRIBUTE_OPTIONAL(SaveIntermediateImages, lineSegmentationElement);
933 int clipRectangleOrigin[2];
934 int clipRectangleSize[2];
935 if (!lineSegmentationElement->GetVectorAttribute(
"ClipRectangleOrigin", 2, clipRectangleOrigin) ||
936 !lineSegmentationElement->GetVectorAttribute(
"ClipRectangleSize", 2, clipRectangleSize))
938 LOG_WARNING(
"Cannot find ClipRectangleOrigin or ClipRectangleSize attribute in the vtkPlusLineSegmentationAlgo configuration file; Using the largest ROI possible.");
946 if (clipRectangleOrigin[0] < 0)
948 clipRectangleOrigin[0] = 0;
950 if (clipRectangleOrigin[1] < 0)
952 clipRectangleOrigin[1] = 0;
954 if (clipRectangleSize[0] < 0)
956 clipRectangleSize[0] = -1;
958 if (clipRectangleSize[1] < 0)
960 clipRectangleSize[1] = -1;
969 double signalTimeRange[2] = {0};
970 if (lineSegmentationElement->GetVectorAttribute(
"SignalTimeRange", 2, signalTimeRange))
double m_SignalTimeRangeMin
CharImageType::SizeValueType m_ClipRectangleSize[2]
void SetClipRectangle(int clipRectangleOriginPix[2], int clipRectangleSizePix[2])
PlusStatus FindPeakStart(std::deque< int > &intensityProfile, int maxFromLargestArea, int startOfMaxArea, double &startOfPeak)
void SaveIntermediateImage(int frameNumber, CharImageType::Pointer scanlineImage, double x_0, double y_0, double r_x, double r_y, int numOfValidScanlines, const std::vector< itk::Point< double, 2 > > &intensityPeakPositions)
vtkStandardNewMacro(vtkPlusLineSegmentationAlgo)
virtual void PrintSelf(ostream &os, vtkIndent indent) VTK_OVERRIDE
bool PlotIntensityProfile
double lineOriginPoint_Image[2]
void SetIntermediateFilesOutputDirectory(const std::string &outputDirectory)
PlusStatus ComputeCenterOfGravity(std::deque< int > &intensityProfile, int startOfMaxArea, double ¢erOfGravity)
vtkPlusLineSegmentationAlgo()
PlusStatus VerifyVideoInput()
std::vector< LineParameters > m_LineParameters
static const double MAX_CONSECUTIVE_INVALID_VIDEO_FRAMES
static vtkPlusConfig * GetInstance()
void GetDetectedPositions(std::deque< double > &positions)
std::deque< double > m_SignalTimestamps
virtual ~vtkPlusLineSegmentationAlgo()
unsigned char CharPixelType
double lineDirectionVector_Image[2]
static const double MIN_X_SLOPE_COMPONENT_FOR_DETECTED_LINE
void SetTrackedFrameList(vtkIGSIOTrackedFrameList &aTrackedFrameList)
static const double MAX_PERCENTAGE_OF_INVALID_VIDEO_FRAMES
static const unsigned int DIMENSION
std::string GetOutputDirectory()
double m_SignalTimeRangeMax
static const double EXPECTED_LINE_SEGMENTATION_SUCCESS_RATE
PlusStatus ReadConfiguration(vtkXMLDataElement *aConfig)
bool m_SaveIntermediateImages
vtkSmartPointer< vtkIGSIOTrackedFrameList > m_TrackedFrameList
const PEAK_POS_METRIC_TYPE PEAK_POS_METRIC
PlusStatus FindLargestPeak(std::deque< int > &intensityProfile, int &maxFromLargestArea, int &maxFromLargestAreaIndex, int &startOfMaxArea)
static const int NUMBER_OF_SCANLINES
CharImageType::IndexValueType m_ClipRectangleOrigin[2]
PlusStatus ComputeVideoPositionMetric()
void SetSignalTimeRange(double rangeMin, double rangeMax)
void GetDetectedLineParameters(std::vector< LineParameters > ¶meters)
static vtkIGSIOLogger * Instance()
std::string IntermediateFilesOutputDirectory
void LimitToClipRegion(CharImageType::RegionType ®ion)
static const int MINIMUM_NUMBER_OF_VALID_SCANLINES
void ComputeLineParameters(std::vector< itk::Point< double, 2 > > &data, LineParameters &outputParameters)
void SetSaveIntermediateImages(bool saveIntermediateImages)
Direction vectors of rods y
void PlotDoubleArray(const std::deque< double > &intensityValues)
static const double INTESNITY_THRESHOLD_PERCENTAGE_OF_PEAK
std::deque< double > m_SignalValues
void GetDetectedTimestamps(std::deque< double > ×tamps)
void PlotIntArray(const std::deque< int > &intensityValues)
void SetTrackedFrame(igsioTrackedFrame &aTrackedFrame)
Detect the position of a line (image of a plane) in an US image sequence.