8 #include "PlusConfigure.h" 10 #include "igsioMath.h" 15 #include <vtkTriangle.h> 22 : m_ApproximateSpacingMmPerPixel(-1.0)
23 , m_MaxAngleDiff(-1.0)
24 , m_MinLinePairDistMm(-1.0)
25 , m_MaxLinePairDistMm(-1.0)
26 , m_MinLinePairAngleRad(-1.0)
27 , m_MaxLinePairAngleRad(-1.0)
28 , m_MaxLineShiftMm(10.0)
29 , m_MaxLinePairDistanceErrorPercent(-1.0)
33 , m_AngleToleranceRad(-1.0)
34 , m_InclinedLineAngleRad(-1.0)
35 , m_PatternIntensity(-1.0)
50 LOG_TRACE(
"FidLabeling::UpdateParameters");
53 std::vector<PlusFidPattern*>::size_type numOfPatterns =
m_Patterns.size();
54 double epsilon = 0.001;
57 std::vector<vtkSmartPointer<vtkPlane>> planes;
58 for (std::vector<PlusFidPattern*>::size_type
i = 0;
i < numOfPatterns; ++
i)
60 double normal[3] = {0, 0, 0};
61 double v1[3], v2[3], v3[3];
62 memcpy(v1,
m_Patterns[
i]->GetWires()[0].EndPointFront,
sizeof(
double) * 3);
63 memcpy(v2,
m_Patterns[
i]->GetWires()[0].EndPointBack,
sizeof(
double) * 3);
64 memcpy(v3,
m_Patterns[
i]->GetWires()[2].EndPointFront,
sizeof(
double) * 3);
65 vtkTriangle::ComputeNormal(v1, v2, v3, normal);
67 vtkSmartPointer<vtkPlane> plane = vtkSmartPointer<vtkPlane>::New();
68 plane->SetNormal(normal);
70 planes.push_back(plane);
72 std::array<double, 3> point1 = {
m_Patterns[
i]->GetWires()[1].EndPointFront[0],
m_Patterns[
i]->GetWires()[1].EndPointFront[1],
m_Patterns[
i]->GetWires()[1].EndPointFront[2] };
73 double distance1F = plane->DistanceToPlane(point1.data());
74 std::array<double, 3> point2 = {
m_Patterns[
i]->GetWires()[1].EndPointBack[0],
m_Patterns[
i]->GetWires()[1].EndPointBack[1],
m_Patterns[
i]->GetWires()[1].EndPointBack[2] };
75 double distance1B = plane->DistanceToPlane(point2.data());
76 std::array<double, 3> point3 = {
m_Patterns[
i]->GetWires()[2].EndPointBack[0],
m_Patterns[
i]->GetWires()[2].EndPointBack[1],
m_Patterns[
i]->GetWires()[2].EndPointBack[2] };
77 double distance2B = plane->DistanceToPlane(point3.data());
79 if (distance1F > epsilon || distance1B > epsilon || distance2B > epsilon)
81 LOG_ERROR(
"Pattern number " <<
i <<
" is invalid: the endpoints are not on the same plane");
86 double maxNPlaneDistance = -1.0;
87 double minNPlaneDistance = std::numeric_limits<double>::max();
90 for (std::vector<PlusFidPattern*>::size_type
i = numOfPatterns - 1;
i > 0; --
i)
92 for (
int j = static_cast<int>(
i) - 1; j >= 0; --j)
94 double distance = planes.at(
i)->DistanceToPlane(planes.at(j)->GetOrigin());
103 double angle = acos(vtkMath::Dot(planes.at(
i)->GetNormal(), planes.at(j)->GetNormal())
104 / vtkMath::Norm(planes.at(
i)->GetNormal())
105 / vtkMath::Norm(planes.at(j)->GetNormal()));
107 if (angle > vtkMath::Pi() / 2)
109 angle -= vtkMath::Pi();
111 else if (angle < -vtkMath::Pi() / 2)
113 angle += vtkMath::Pi();
136 LOG_TRACE(
"FidLabeling::ReadConfiguration");
138 XML_FIND_NESTED_ELEMENT_OPTIONAL(segmentationParameters, configData,
"Segmentation");
139 if (!segmentationParameters)
141 segmentationParameters = igsioXmlUtils::GetNestedElementWithName(configData,
"Segmentation");
145 XML_READ_SCALAR_ATTRIBUTE_WARNING(
double, ApproximateSpacingMmPerPixel, segmentationParameters);
149 int computeSegmentationParametersFromPhantomDefinition(0);
150 if (segmentationParameters->GetScalarAttribute(
"ComputeSegmentationParametersFromPhantomDefinition", computeSegmentationParametersFromPhantomDefinition)
151 && computeSegmentationParametersFromPhantomDefinition != 0)
153 LOG_WARNING(
"Automatic computation of the MaxLinePairDistanceErrorPercent and MaxAngleDifferenceDegrees parameters are not yet supported, use the values that are in the config file");
156 XML_READ_SCALAR_ATTRIBUTE_WARNING(
double, MaxLinePairDistanceErrorPercent, segmentationParameters);
157 XML_READ_SCALAR_ATTRIBUTE_WARNING(
double, MaxAngleDifferenceDegrees, segmentationParameters);
158 XML_READ_SCALAR_ATTRIBUTE_WARNING(
double, AngleToleranceDegrees, segmentationParameters);
159 XML_READ_SCALAR_ATTRIBUTE_WARNING(
double, MaxLineShiftMm, segmentationParameters);
161 XML_READ_SCALAR_ATTRIBUTE_OPTIONAL(
double, InclinedLineAngleDegrees, segmentationParameters);
181 std::vector<PlusFidLine> emptyLine;
189 LOG_TRACE(
"FidLineFinder::SetFrameSize(" << frameSize[0] <<
", " << frameSize[1] <<
")");
202 LOG_ERROR(
"Dimensions of the frame size are not positive!");
217 return temporaryLine1[1] < temporaryLine2[1];
223 std::vector<std::vector<double>> temporaryLine;
228 std::vector<double> temp;
231 temp.push_back(sqrt((startPointIndex.
GetX() - point.
GetX()) * (startPointIndex.
GetX() - point.
GetX()) + (startPointIndex.
GetY() - point.
GetY()) * (startPointIndex.
GetY() - point.
GetY())));
232 temporaryLine.push_back(temp);
267 double y = (
y2 -
y1);
268 double x = (
x2 -
x1);
271 if (fabs(
x) > fabs(
y))
273 t = vtkMath::Pi() / 2 + atan(
y /
x);
277 double tanTheta =
x /
y;
280 t = vtkMath::Pi() - atan(tanTheta);
288 assert(
t >= 0 &&
t <= vtkMath::Pi());
295 double x[3],
y[3], z[3];
309 return igsioMath::ComputeDistanceLinePoint(
x,
y, z);
328 double midLine1_to_midLine2[3] =
330 midLine2[0] - midLine1[0],
331 midLine2[1] - midLine1[1],
335 double line1vector[3] =
341 vtkMath::Normalize(line1vector);
343 double midLine1_to_midLine2_projectionToLine1_length = vtkMath::Dot(line1vector, midLine1_to_midLine2);
345 return midLine1_to_midLine2_projectionToLine1_length;
352 double intensity = 0;
353 std::vector<double> dotCoords;
356 for (
int i = 0;
i < numberOfLines; ++
i)
363 for (
unsigned int i = 0 ;
i < resultLines[
line]->GetNumberOfPoints() ;
i++)
367 dotCoords.push_back(result.
x);
369 dotCoords.push_back(result.
y);
373 foundDotsCoordinateValues.push_back(dotCoords);
377 intensity += resultLines[
line]->GetIntensity();
391 double intensity = 0;
392 std::vector<double> dotCoords;
399 dotCoords.push_back(result.
x);
401 dotCoords.push_back(result.
y);
405 foundDotsCoordinateValues.push_back(dotCoords);
414 dotCoords.push_back(result.
x);
416 dotCoords.push_back(result.
y);
420 foundDotsCoordinateValues.push_back(dotCoords);
429 dotCoords.push_back(result.
x);
431 dotCoords.push_back(result.
y);
435 foundDotsCoordinateValues.push_back(dotCoords);
456 int numberOfCandidateLines = maxPointsLines.size();
457 std::vector<int> lineIndices(numberOfLines);
458 std::vector<PlusLabelingResults> results;
463 for (
unsigned int i = 0 ;
i < lineIndices.size() ;
i++)
465 lineIndices[
i] = lineIndices.size() - 1 -
i;
469 bool foundPattern =
false;
472 for (
int i = 0;
i < numberOfLines;
i++)
476 if (lineIndices[
i] < numberOfCandidateLines -
i)
480 int nextIndex = lineIndices[
i] + 1;
481 for (
int j =
i - 1; j >= 0; j--)
483 lineIndices[j] = nextIndex;
490 if (
i == numberOfLines - 1)
501 for (
int i = 0 ;
i < numberOfLines - 1 && foundPattern;
i++)
503 PlusFidLine currentLine1 = maxPointsLines[lineIndices[
i]];
504 for (
int j =
i + 1 ; j < numberOfLines && foundPattern; j++)
506 PlusFidLine currentLine2 = maxPointsLines[lineIndices[j]];
520 foundPattern =
false;
525 double shift =
ComputeShift(currentLine1, currentLine2);
528 if (fabs(shift) > maxLineShiftDistPx)
531 foundPattern =
false;
540 if ((angleBetweenLinesRad > maxAngle) || (angleBetweenLinesRad < minAngle))
543 foundPattern =
false;
549 int commonPointIndex = -1;
558 if (commonPointIndex != -1)
563 if ((angleBetweenLinesRad > maxAngle) || (angleBetweenLinesRad < minAngle))
566 foundPattern =
false;
574 while ((lineIndices[numberOfLines - 1] != numberOfCandidateLines - numberOfLines + 2) && (!foundPattern));
581 if (nWire !=
nullptr)
583 std::vector<PlusFidLine*> resultLines(numberOfLines);
584 std::vector<double> resultLineMiddlePointYs;
586 for (std::vector<int>::iterator it = lineIndices.begin(); it != lineIndices.end(); ++it)
588 resultLineMiddlePointYs.push_back((
m_DotsVector[maxPointsLines[*it].GetStartPointIndex()].GetY() +
m_DotsVector[maxPointsLines[*it].GetEndPointIndex()].GetY()) / 2);
593 std::vector<double>::iterator middlePointYsBeginIt = resultLineMiddlePointYs.begin();
594 for (
int i = 0;
i < numberOfLines; ++
i)
596 std::vector<double>::iterator middlePointYsMinIt = std::min_element(middlePointYsBeginIt, resultLineMiddlePointYs.end());
597 int minIndex = (
int)
std::distance(middlePointYsBeginIt, middlePointYsMinIt);
598 resultLines[
i] = &maxPointsLines[lineIndices[minIndex]];
599 (*middlePointYsMinIt) = DBL_MAX;
604 else if (coplanarParallelWire)
606 PlusFidLine resultLine1 = maxPointsLines[lineIndices[0]];
607 PlusFidLine resultLine2 = maxPointsLines[lineIndices[1]];
608 PlusFidLine resultLine3 = maxPointsLines[lineIndices[2]];
615 if (!test1 && !test2)
626 else if (!test1 && !test3)
657 std::vector<std::vector<PlusFidDot>::iterator> pointsIterator(
line.GetNumberOfPoints());
659 for (
unsigned int i = 0;
i <
line.GetNumberOfPoints() ;
i++)
666 for (
unsigned int i = 0;
i <
line.GetNumberOfPoints();
i++)
void SortRightToLeft(PlusFidLine &line)
std::vector< PlusFidLine > m_FoundLines
std::vector< PlusFidPattern * > & GetPatterns()
unsigned int GetNumberOfPoints() const
PlusFidLine SortPointsByDistanceFromStartPoint(PlusFidLine &fiducials)
double m_MaxLinePairDistMm
void SetMaxLineShiftMm(double aValue)
void SetAngleToleranceDegrees(double angleToleranceDegrees)
void UpdateCirsResults(const PlusFidLine &resultLine1, const PlusFidLine &resultLine2, const PlusFidLine &resultLine3)
double ComputeDistancePointLine(PlusFidDot &dot, PlusFidLine &line)
virtual ~PlusFidLabeling()
int GetEndPointIndex() const
double m_ApproximateSpacingMmPerPixel
std::vector< std::vector< PlusFidLine > > m_LinesVector
int GetStartPointIndex() const
void SetFrameSize(const FrameSizeType &frameSize)
double m_MinLinePairAngleRad
void SetPoint(int aIndex, int aValue)
std::vector< PlusFidDot > m_DotsVector
double ComputeShift(PlusFidLine &line1, PlusFidLine &line2)
double ComputeSlope(PlusFidLine &line)
std::vector< PlusLabelingResults > m_Results
std::vector< PlusFidPattern * > m_Patterns
double m_InclinedLineAngleRad
double m_PatternIntensity
void SetMinThetaDeg(double value)
double GetMaxLineShiftMm()
const char const char * value
std::array< unsigned int, 3 > m_FrameSize
PlusStatus ReadConfiguration(vtkXMLDataElement *rootConfigElement, double minThetaRad, double maxThetaRad)
double m_MaxLinePairAngleRad
double m_MaxLinePairDistanceErrorPercent
void SetInclinedLineAngleDegrees(double inclinedLineAngleDegrees)
static void SetDefaultSegmentationParameters(vtkXMLDataElement *segmentationElement)
int GetPoint(int aIndex) const
void SetMaxThetaDeg(double value)
static double ComputeAngleRad(const PlusFidLine &line1)
std::vector< std::vector< double > > m_FoundDotsCoordinateValue
double m_MinLinePairDistMm
Direction vectors of rods y
void UpdateNWiresResults(std::vector< PlusFidLine * > &resultLines)
static bool SortCompare(const std::vector< double > &temporaryLine1, const std::vector< double > &temporaryLine2)
void SetAngleToleranceDeg(double value)
static bool PositionLessThan(std::vector< PlusFidDot >::iterator b1, std::vector< PlusFidDot >::iterator b2)
double m_AngleToleranceRad
double GetIntensity() const