UsTK : Ultrasound ToolKit  version 2.0.1 under development (2025-03-14)
testUsNeedleTracking2D.cpp
1 /****************************************************************************
2  *
3  * This file is part of the UsNeedleDetection software.
4  * Copyright (C) 2013 - 2016 by Inria. All rights reserved.
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License ("GPL") as
8  * published by the Free Software Foundation, either version 3 of the
9  * License, or (at your option) any later version.
10  * See the file COPYING at the root directory of this source
11  * distribution for additional information about the GNU GPL.
12  *
13  * This software was developed at:
14  * INRIA Rennes - Bretagne Atlantique
15  * Campus Universitaire de Beaulieu
16  * 35042 Rennes Cedex
17  * France
18  * http://www.irisa.fr/lagadic
19  *
20  * If you have questions regarding the use of this file, please contact the
21  * authors at Alexandre.Krupa@inria.fr
22  *
23  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
24  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
25  *
26  * Authors:
27  * Marc Pouliquen
28  *
29  *****************************************************************************/
30 
31 #include <iostream>
32 #include <sstream>
33 #include <string>
34 
35 // visp
36 #include <visp3/core/vpConfig.h>
37 
38 #ifdef VISP_HAVE_XML2
39 #include <visp3/core/vpIoTools.h>
40 #include <visp3/core/vpMatrix.h>
41 #include <visp3/io/vpImageIo.h>
42 #include <visp3/io/vpParseArgv.h>
43 
44 // ustk
45 #include <visp3/ustk_core/us.h>
46 #include <visp3/ustk_core/usSequenceReader.h>
47 #include <visp3/ustk_needle_detection/usNeedleTrackerSIR2D.h>
48 
49 int main()
50 {
51  std::string xml_filename;
52  double error_max = 4.;
53 
54  // Get the ustk-dataset package path or USTK_DATASET_PATH environment variable value
55  if (xml_filename.empty()) {
56  std::string env_ipath = us::getDataSetPath();
57  if (!env_ipath.empty())
58  xml_filename = env_ipath + "/needle/water_bath_minimal_noise_png/sequence.xml";
59  else {
60  std::cout << "You should set USTK_DATASET_PATH environment var to access to ustk dataset" << std::endl;
61  return 0;
62  }
63  }
64 
66  //
67  // Initializations.
68  //
70 
72  reader.setSequenceFileName(xml_filename);
73 
74  // Read the first image
76  reader.acquire(I);
77 
78  // Initialize the needle model
79  usPolynomialCurve2D needle(1);
80  vpMatrix controlPoints(2, 2);
81 
82  // initial needle position for needle insertion sequence of ustk-dataset repo
83  controlPoints[0][0] = 197;
84  controlPoints[1][0] = 218;
85  controlPoints[0][1] = 211;
86  controlPoints[1][1] = 236;
87  needle.setControlPoints(controlPoints);
88 
89  // Initialization of the needle detector
90  usNeedleTrackerSIR2D needleDetector;
91 
92  unsigned int nControlPoints = 2;
93  unsigned int nParticles = 200;
94 
95  needleDetector.setSigma(1.0);
96  needleDetector.setSigma1(10.0);
97  needleDetector.setSigma2(1.0);
98  needleDetector.init(I, nControlPoints, nParticles, needle);
99  std::cout << "Needle detector initialized." << std::endl;
100 
101  controlPoints = needleDetector.getNeedle()->getControlPoints();
102 
103  vpColVector entryPose;
104 
106  //
107  // Start needle detection.
108  //
110 
111  vpColVector tipMean;
112 
113  // ground truth values
114  std::vector<vpColVector> tipGroundTruth;
115  vpColVector vec(2);
116  vec[0] = 210;
117  vec[1] = 235;
118  tipGroundTruth.push_back(vec);
119  vec[1] = 234;
120  tipGroundTruth.push_back(vec);
121  vec[0] = 218;
122  vec[1] = 242;
123  tipGroundTruth.push_back(vec);
124  vec[0] = 224;
125  vec[1] = 248;
126  tipGroundTruth.push_back(vec);
127  vec[0] = 229;
128  vec[1] = 252;
129  tipGroundTruth.push_back(vec);
130  vec[0] = 232;
131  vec[1] = 254;
132  tipGroundTruth.push_back(vec);
133  vec[0] = 234;
134  vec[1] = 255;
135  tipGroundTruth.push_back(vec);
136  vec[0] = 237;
137  vec[1] = 256;
138  tipGroundTruth.push_back(vec);
139  vec[0] = 243;
140  vec[1] = 259;
141  tipGroundTruth.push_back(vec);
142 
143  for (int i = 0; i < 9; i++) {
144  reader.acquire(I);
145  needleDetector.run(I, 0.0);
146 
147  tipMean = needleDetector.getNeedle()->getPoint(1.0);
148  entryPose = needleDetector.getNeedle()->getPoint(0.0);
149  std::cout << "Tip position: (" << tipMean[0] << "," << tipMean[1] << ")" << std::endl;
150  std::cout << "Needle length: " << needleDetector.getNeedle()->getLength() << std::endl;
151  std::cout << "Number of control points: " << needleDetector.getNeedle()->getOrder() + 1 << std::endl;
152 
153  // Output
154  double error = sqrt(vpMath::sqr(tipMean[0] - tipGroundTruth.at(i)[0]) + vpMath::sqr(tipMean[1] - tipGroundTruth.at(i)[1]));
155  if (error > error_max) {
156  std::cout << "Error " << error << " exeeds " << error_max << " with i error=" << std::abs(tipMean[0] - tipGroundTruth.at(i)[0])
157  << ", j error= " << std::abs(tipMean[1] - tipGroundTruth.at(i)[1]) << std::endl;
158 
159  return EXIT_FAILURE;
160  }
161  }
162  tipGroundTruth.clear();
163 
164  std::cout << "Test succeed" << std::endl;
165  return EXIT_SUCCESS;
166 }
167 
168 #else
169 int main() { std::cout << "You should install xml2 to use this example" << std::endl; }
170 #endif
Needle detection in 2D images based on particle filtering.
usPolynomialCurve2D * getNeedle()
void init(unsigned int dims[2], unsigned int nPoints, unsigned int nParticles, const usPolynomialCurve2D &needle)
void run(vpImage< unsigned char > &I, double v)
double getLength(int nbCountSeg=50) const
vpMatrix getControlPoints() const
vpColVector getPoint(double parameter) const
unsigned int getOrder() const
Reading of sequences of ultrasound images.
void acquire(ImageType &image)
void setSequenceFileName(const std::string &sequenceFileName)
VISP_EXPORT std::string getDataSetPath()
Definition: us.cpp:54