37 #include <visp3/core/vpConfig.h>
40 #include <visp3/core/vpIoTools.h>
41 #include <visp3/core/vpMatrix.h>
42 #include <visp3/gui/vpDisplayD3D.h>
43 #include <visp3/gui/vpDisplayGDI.h>
44 #include <visp3/gui/vpDisplayGTK.h>
45 #include <visp3/gui/vpDisplayOpenCV.h>
46 #include <visp3/gui/vpDisplayX.h>
47 #include <visp3/gui/vpPlot.h>
48 #include <visp3/io/vpImageIo.h>
49 #include <visp3/io/vpParseArgv.h>
52 #include <visp3/ustk_core/us.h>
53 #include <visp3/ustk_core/usSequenceReader.h>
54 #include <visp3/ustk_needle_detection/usNeedleTrackerSIR2D.h>
63 #define GETOPTARGS "cdo:h"
65 void usage(
const char *name,
const char *badparam,
const std::string &opath,
const std::string &user);
66 bool getOptions(
int argc,
const char **argv, std::string &opath,
const std::string &user);
78 void usage(
const char *name,
const char *badparam,
const std::string &opath,
const std::string &user)
81 Write and read ultrasound sequences in 2d image files, and the associated xml settings file.\n\
84 %s [-o <output image path>] [-h]\n",
89 -o <output data path> %s\n\
90 Set data output path.\n\
91 From this directory, creates the \"%s\"\n\
92 subdirectory depending on the username, where \n\
93 sequenceRF2D.xml file is written.\n\
97 opath.c_str(), user.c_str());
100 fprintf(stderr,
"ERROR: \n");
101 fprintf(stderr,
"\nBad parameter [%s]\n", badparam);
114 bool getOptions(
int argc,
const char **argv, std::string &opath,
const std::string &user)
118 while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
125 usage(argv[0], NULL, opath, user);
134 usage(argv[0], optarg_, opath, user);
140 if ((c == 1) || (c == -1)) {
142 usage(argv[0], NULL, opath, user);
143 std::cerr <<
"ERROR: " << std::endl;
144 std::cerr <<
" Bad argument " << optarg_ << std::endl << std::endl;
151 int main(
int argc,
const char *argv[])
153 std::string opt_opath;
154 std::string username;
156 std::string logFilename;
158 std::string windowTitle;
161 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)))
163 #elif defined(_WIN32)
164 opt_opath =
"C:\\temp";
168 vpIoTools::getUserName(username);
171 if (getOptions(argc, argv, opt_opath, username) ==
false) {
176 if (!opt_opath.empty())
180 std::string dirname = vpIoTools::createFilePath(opath.c_str(), username);
183 if (vpIoTools::checkDirectory(dirname) ==
false) {
186 vpIoTools::makeDirectory(dirname);
189 usage(argv[0], NULL, opath, username);
190 std::cerr << std::endl <<
"ERROR:" << std::endl;
191 std::cerr <<
" Cannot create " << dirname << std::endl;
192 std::cerr <<
" Check your -o " << opath.c_str() <<
" option " << std::endl;
197 std::string xml_filename;
199 for (
int i = 0; i < argc; i++) {
200 if (std::string(argv[i]) ==
"--input")
201 xml_filename = std::string(argv[i + 1]);
202 else if (std::string(argv[i]) ==
"--help") {
203 std::cout <<
"\nUsage: " << argv[0] <<
" [--input <needleSequence.xml>] [--help]\n" << std::endl;
209 if (xml_filename.empty()) {
211 if (!env_ipath.empty())
212 xml_filename = env_ipath +
"/needle/water_bath_minimal_noise_png/sequence.xml";
214 std::cout <<
"You should set USTK_DATASET_PATH environment var to access to ustk dataset" << std::endl;
234 #if defined VISP_HAVE_X11
235 vpDisplay *
display =
new vpDisplayX(I);
236 #elif defined VISP_HAVE_GTK
237 vpDisplay *
display =
new vpDisplayGTK(I);
238 #elif defined VISP_HAVE_GDI
239 vpDisplay *
display =
new vpDisplayGDI(I);
240 #elif defined VISP_HAVE_D3D9
241 vpDisplay *
display =
new vpDisplayD3D(I);
242 #elif defined VISP_HAVE_OPENCV
243 vpDisplay *
display =
new vpDisplayOpenCV(I);
245 #error "No display available."
248 vpDisplay::display(I);
253 vpMatrix controlPoints(2, 2);
256 std::cout <<
"Click on the entry point." << std::endl;
257 vpDisplay::getClick(I, P);
259 controlPoints[0][0] = P.get_i();
260 controlPoints[1][0] = P.get_j();
262 std::cout <<
"Click on the tip." << std::endl;
263 vpDisplay::getClick(I, P);
265 controlPoints[0][1] = P.get_i();
266 controlPoints[1][1] = P.get_j();
268 needle.setControlPoints(controlPoints.t());
269 std::cout <<
"Needle model initialized." << std::endl;
274 unsigned int nControlPoints = 2;
275 unsigned int nParticles = 200;
280 needleDetector.
init(I, nControlPoints, nParticles, needle);
281 std::cout <<
"Needle detector initialized." << std::endl;
284 logFilename = dirname + std::string(
"/needle.dat");
285 std::ofstream ofile(logFilename.c_str());
286 std::cout <<
"Results will be saved in " << logFilename.c_str() << std::endl;
291 for (
unsigned int i = 0; i < nPoints; ++i)
292 ofile <<
" " << controlPoints[0][i] <<
" " << controlPoints[1][i];
295 vpColVector tipPose, entryPose;
306 vpMatrix tipStd(2, 2);
308 vpColVector evalue, evector;
311 while (!reader.
end()) {
313 needleDetector.
run(I, 0.0);
317 cout <<
"Tip position: (" << tipMean[0] <<
"," << tipMean[1] <<
")" << endl;
319 cout <<
"Number of control points: " << needleDetector.
getNeedle()->
getOrder() << endl;
325 for (
unsigned int i = 0; i < nPoints; ++i)
326 ofile <<
" " << controlPoints[0][i] <<
" " << controlPoints[1][i];
330 int size =
static_cast<int>(ceil(log10(n0 + 1))) + 1
331 char *noChar =
new char[size];
332 snprintf(noChar, size,
"%d", n0);
333 windowTitle = std::string(
"Frame ") + std::string(noChar);
335 vpDisplay::setTitle(I, windowTitle);
336 vpDisplay::display(I);
339 unsigned int n = rendering.getCols();
341 for (
unsigned int j = 0; j < n - 1; ++j)
342 vpDisplay::displayLine(I, (
int)rendering[0][j], (
int)rendering[1][j], (
int)rendering[0][j + 1],
343 (
int)rendering[1][j + 1], vpColor::red, 2);
347 for (
unsigned int i = 0; i < nParticles; ++i) {
349 tipStd += needleDetector.
getWeight(i) * (tipPose - tipMean) * (tipPose - tipMean).t();
352 vpDisplay::displayCross(I, (
int)tipPose[0], (int)tipPose[1], 3, vpColor::blue);
364 #if defined VISP_HAVE_DISPLAY
372 int main() { std::cout <<
"You should install xml2 to use this example" << std::endl; }
Needle detection in 2D images based on particle filtering.
double getWeight(unsigned int i)
usPolynomialCurve2D * getNeedle()
void init(unsigned int dims[2], unsigned int nPoints, unsigned int nParticles, const usPolynomialCurve2D &needle)
usPolynomialCurve2D * getParticle(unsigned int i)
void run(vpImage< unsigned char > &I, double v)
double getLength(int nbCountSeg=50) const
vpMatrix getControlPoints() const
vpColVector getPoint(double parameter) const
vpMatrix getRenderingPoints() 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()