UsTK : Ultrasound ToolKit  version 2.0.1 under development (2024-12-03)
usMHDSequenceReader.cpp
1 #include <visp3/ustk_core/usMHDSequenceReader.h>
2 
7  : m_sequenceDirectory(), m_sequenceImageType(us::NOT_SET), m_sequenceFiles(), m_totalImageNumber(0), m_imageCounter(0)
8 {
9 }
10 
15 
20 void usMHDSequenceReader::setSequenceDirectory(const std::string sequenceDirectory)
21 {
22  m_sequenceFiles = vpIoTools::getDirFiles(sequenceDirectory);
23  m_sequenceDirectory = sequenceDirectory;
24  m_totalImageNumber = (int)m_sequenceFiles.size() / 2; // we have mhd and raw in the directory (2 * m_totalImageNumber)
25  m_imageCounter = 0;
26 }
27 
33 void usMHDSequenceReader::acquire(usImageRF2D<short int> &image, uint64_t &timestamp)
34 {
35 
36  if (m_imageCounter > m_totalImageNumber)
37  throw(vpException(vpException::fatalError, "usMHDSequenceReader : end of sequence reached !"));
38 
39  if (usImageIo::getHeaderFormat(m_sequenceFiles.at(2 * m_imageCounter)) !=
40  usImageIo::FORMAT_MHD) // check file extention
41  throw(vpException(vpException::fatalError, "usMHDSequenceReader trying to open a non-mhd file !"));
42 
43  usMetaHeaderParser mhdParser;
44  mhdParser.read(m_sequenceDirectory + vpIoTools::path("/") +
45  m_sequenceFiles.at(2 * m_imageCounter)); // we skip raw files
46  m_sequenceImageType = mhdParser.getImageType();
47  if (m_sequenceImageType != us::RF_2D && m_sequenceImageType != us::NOT_SET) {
48  throw(vpException(vpException::badValue, "Reading a non rf 2D image!"));
49  }
50  if (mhdParser.getElementType() != usMetaHeaderParser::MET_SHORT) {
51  throw(vpException(vpException::badValue, "Reading a non short image!"));
52  }
53 
54  usMetaHeaderParser::MHDHeader mhdHeader = mhdParser.getMHDHeader();
55  timestamp = mhdHeader.timestamp.at(0);
56 
57  usImagePreScanSettings settings;
58  settings.setTransducerRadius(mhdHeader.transducerRadius);
59  settings.setScanLinePitch(mhdHeader.scanLinePitch);
60  settings.setTransducerConvexity(mhdHeader.isTransducerConvex);
61  settings.setAxialResolution(mhdParser.getAxialResolution());
62  settings.setDepth(settings.getAxialResolution() * mhdHeader.dim[1]);
63  settings.setSamplingFrequency(mhdHeader.samplingFrequency);
64  settings.setTransmitFrequency(mhdHeader.transmitFrequency);
65  image.setImagePreScanSettings(settings);
66 
67  // resizing image in memory
68  image.resize(mhdHeader.dim[1], mhdHeader.dim[0]);
69 
70  // data parsing
71  usRawFileParser rawParser;
72  rawParser.read(image, m_sequenceDirectory + vpIoTools::path("/") + m_sequenceFiles.at(2 * m_imageCounter + 1));
73 
74  m_imageCounter++;
75 }
76 
83 {
84  if (m_imageCounter > m_totalImageNumber)
85  throw(vpException(vpException::fatalError, "usMHDSequenceReader : end of sequence reached !"));
86 
87  if (usImageIo::getHeaderFormat(m_sequenceFiles.at(2 * m_imageCounter)) !=
88  usImageIo::FORMAT_MHD) // check file extention
89  throw(vpException(vpException::fatalError, "usMHDSequenceReader trying to open a non-mhd file !"));
90 
91  usMetaHeaderParser mhdParser;
92  mhdParser.read(m_sequenceDirectory + vpIoTools::path("/") +
93  m_sequenceFiles.at(2 * m_imageCounter)); // we skip raw files
94  m_sequenceImageType = mhdParser.getImageType();
95  if (m_sequenceImageType != us::PRESCAN_2D && m_sequenceImageType != us::NOT_SET) {
96  throw(vpException(vpException::badValue, "Reading a non pre-scan 2D image!"));
97  }
98  if (mhdParser.getElementType() != usMetaHeaderParser::MET_UCHAR) {
99  throw(vpException(vpException::badValue, "Reading a non unsigned char image!"));
100  }
101 
102  usMetaHeaderParser::MHDHeader mhdHeader = mhdParser.getMHDHeader();
103  timestamp = mhdHeader.timestamp.at(0);
104 
105  usImagePreScanSettings settings;
106  settings.setTransducerRadius(mhdHeader.transducerRadius);
107  settings.setScanLinePitch(mhdHeader.scanLinePitch);
108  settings.setTransducerConvexity(mhdHeader.isTransducerConvex);
109  settings.setAxialResolution(mhdParser.getAxialResolution());
110  settings.setDepth(settings.getAxialResolution() * mhdHeader.dim[1]);
111  settings.setSamplingFrequency(mhdHeader.samplingFrequency);
112  settings.setTransmitFrequency(mhdHeader.transmitFrequency);
113  image.setImagePreScanSettings(settings);
114 
115  // resizing image in memory
116  image.resize(mhdHeader.dim[1], mhdHeader.dim[0]);
117 
118  // data parsing
119  usRawFileParser rawParser;
120  rawParser.read(image, m_sequenceDirectory + vpIoTools::path("/") + m_sequenceFiles.at(2 * m_imageCounter + 1));
121 
122  m_imageCounter++;
123 }
124 
131 {
132  if (m_imageCounter > m_totalImageNumber)
133  throw(vpException(vpException::fatalError, "usMHDSequenceReader : end of sequence reached !"));
134 
135  if (usImageIo::getHeaderFormat(m_sequenceFiles.at(2 * m_imageCounter)) !=
136  usImageIo::FORMAT_MHD) // check file extention
137  throw(vpException(vpException::fatalError, "usMHDSequenceReader trying to open a non-mhd file !"));
138 
139  usMetaHeaderParser mhdParser;
140  mhdParser.read(m_sequenceDirectory + vpIoTools::path("/") +
141  m_sequenceFiles.at(2 * m_imageCounter)); // we skip raw files
142  m_sequenceImageType = mhdParser.getImageType();
143  if (m_sequenceImageType != us::POSTSCAN_2D && m_sequenceImageType != us::NOT_SET) {
144  throw(vpException(vpException::badValue, "Reading a non post-scan 2D image!"));
145  }
146  if (mhdParser.getElementType() != usMetaHeaderParser::MET_UCHAR) {
147  throw(vpException(vpException::badValue, "Reading a non unsigned char image!"));
148  }
149 
150  usMetaHeaderParser::MHDHeader mhdHeader = mhdParser.getMHDHeader();
151  timestamp = mhdHeader.timestamp.at(0);
152 
153  usImagePreScanSettings settings;
154  image.setTransducerRadius(mhdHeader.transducerRadius);
155  image.setScanLinePitch(mhdHeader.scanLinePitch);
156  image.setTransducerConvexity(mhdHeader.isTransducerConvex);
157 
158  // computing image depth from the pixel size and the transducer settings
159  if (mhdHeader.isTransducerConvex) {
160  // distance
161  double deltaDepthPostScan2D =
162  mhdHeader.transducerRadius *
163  (1 - std::cos((double)((mhdHeader.scanLineNumber - 1) * mhdHeader.scanLinePitch / 2.0)));
164  image.setDepth(mhdHeader.elementSpacing[1] * mhdHeader.dim[1] - deltaDepthPostScan2D);
165  } else // linear transducer
166  image.setDepth(mhdHeader.elementSpacing[1] * mhdHeader.dim[1]);
167 
168  image.setWidthResolution(mhdHeader.dim[0]);
169  image.setWidthResolution(mhdHeader.dim[1]);
170  image.setSamplingFrequency(mhdHeader.samplingFrequency);
171  image.setTransmitFrequency(mhdHeader.transmitFrequency);
172 
173  // resizing image in memory
174  image.resize(mhdHeader.dim[1], mhdHeader.dim[0]);
175 
176  // data parsing
177  usRawFileParser rawParser;
178  rawParser.read(image, m_sequenceDirectory + vpIoTools::path("/") + m_sequenceFiles.at(2 * m_imageCounter + 1));
179 
180  m_imageCounter++;
181 }
182 
192 void usMHDSequenceReader::acquire(usImageRF3D<short int> &image, std::vector<uint64_t> &timestamp)
193 {
194  if (m_imageCounter > m_totalImageNumber)
195  throw(vpException(vpException::fatalError, "usMHDSequenceReader : end of sequence reached !"));
196 
197  if (usImageIo::getHeaderFormat(m_sequenceFiles.at(2 * m_imageCounter)) !=
198  usImageIo::FORMAT_MHD) // check file extention
199  throw(vpException(vpException::fatalError, "usMHDSequenceReader trying to open a non-mhd file !"));
200 
201  usMetaHeaderParser mhdParser;
202  mhdParser.read(m_sequenceDirectory + vpIoTools::path("/") +
203  m_sequenceFiles.at(2 * m_imageCounter)); // we skip raw files
204  m_sequenceImageType = mhdParser.getImageType();
205  if (m_sequenceImageType != us::RF_3D && m_sequenceImageType != us::NOT_SET) {
206  throw(vpException(vpException::badValue, "Reading a non rf 3D image!"));
207  }
208  if (mhdParser.getElementType() != usMetaHeaderParser::MET_SHORT) {
209  throw(vpException(vpException::badValue, "Reading a non short image!"));
210  }
211 
212  usMetaHeaderParser::MHDHeader mhdHeader = mhdParser.getMHDHeader();
213  timestamp = mhdHeader.timestamp;
214  if (m_imageCounter % 2 == 1) // odd volume: we reverse it
215  std::reverse(timestamp.begin(), timestamp.end());
216 
217  usImagePreScanSettings settings;
218  settings.setTransducerRadius(mhdHeader.transducerRadius);
219  settings.setScanLinePitch(mhdHeader.scanLinePitch);
220  settings.setTransducerConvexity(mhdHeader.isTransducerConvex);
221  settings.setAxialResolution(mhdParser.getAxialResolution());
222  settings.setDepth(settings.getAxialResolution() * mhdHeader.dim[1]);
223  settings.setSamplingFrequency(mhdHeader.samplingFrequency);
224  settings.setTransmitFrequency(mhdHeader.transmitFrequency);
225  image.setImagePreScanSettings(settings);
226 
227  usMotorSettings motorSettings;
228  motorSettings.setMotorRadius(mhdHeader.motorRadius);
229  motorSettings.setFramePitch(mhdHeader.framePitch);
230  motorSettings.setMotorType(mhdHeader.motorType);
231  motorSettings.setFrameNumber(mhdHeader.dim[2]);
232  image.setMotorSettings(motorSettings);
233 
234  // resizing image in memory
235  image.resize(mhdHeader.dim[1], mhdHeader.dim[0], mhdHeader.dim[2]);
236 
237  // data parsing
238  usRawFileParser rawParser;
239  rawParser.read(image, m_sequenceDirectory + vpIoTools::path("/") + m_sequenceFiles.at(2 * m_imageCounter + 1));
240 
241  m_imageCounter++;
242 }
243 
253 void usMHDSequenceReader::acquire(usImagePreScan3D<unsigned char> &image, std::vector<uint64_t> &timestamp)
254 {
255  if (m_imageCounter > m_totalImageNumber)
256  throw(vpException(vpException::fatalError, "usMHDSequenceReader : end of sequence reached !"));
257 
258  if (usImageIo::getHeaderFormat(m_sequenceFiles.at(2 * m_imageCounter)) !=
259  usImageIo::FORMAT_MHD) // check file extention
260  throw(vpException(vpException::fatalError, "usMHDSequenceReader trying to open a non-mhd file !"));
261 
262  usMetaHeaderParser mhdParser;
263  mhdParser.read(m_sequenceDirectory + vpIoTools::path("/") +
264  m_sequenceFiles.at(2 * m_imageCounter)); // we skip raw files
265  m_sequenceImageType = mhdParser.getImageType();
266  if (m_sequenceImageType != us::PRESCAN_3D && m_sequenceImageType != us::NOT_SET) {
267  throw(vpException(vpException::badValue, "Reading a non pre-scan 3D image!"));
268  }
269  if (mhdParser.getElementType() != usMetaHeaderParser::MET_UCHAR) {
270  throw(vpException(vpException::badValue, "Reading a non unsigned char image!"));
271  }
272 
273  usMetaHeaderParser::MHDHeader mhdHeader = mhdParser.getMHDHeader();
274  timestamp = mhdHeader.timestamp;
275  if (m_imageCounter % 2 == 1) // odd volume: we reverse it
276  std::reverse(timestamp.begin(), timestamp.end());
277 
278  usImagePreScanSettings settings;
279  settings.setTransducerRadius(mhdHeader.transducerRadius);
280  settings.setScanLinePitch(mhdHeader.scanLinePitch);
281  settings.setTransducerConvexity(mhdHeader.isTransducerConvex);
282  settings.setAxialResolution(mhdParser.getAxialResolution());
283  settings.setDepth(settings.getAxialResolution() * mhdHeader.dim[1]);
284  settings.setSamplingFrequency(mhdHeader.samplingFrequency);
285  settings.setTransmitFrequency(mhdHeader.transmitFrequency);
286  image.setImagePreScanSettings(settings);
287 
288  usMotorSettings motorSettings;
289  motorSettings.setMotorRadius(mhdHeader.motorRadius);
290  motorSettings.setFramePitch(mhdHeader.framePitch);
291  motorSettings.setMotorType(mhdHeader.motorType);
292  motorSettings.setFrameNumber(mhdHeader.dim[2]);
293  image.setMotorSettings(motorSettings);
294 
295  // resizing image in memory
296  image.resize(mhdHeader.dim[1], mhdHeader.dim[0], mhdHeader.dim[2]);
297 
298  // data parsing
299  usRawFileParser rawParser;
300  rawParser.read(image, m_sequenceDirectory + vpIoTools::path("/") + m_sequenceFiles.at(2 * m_imageCounter + 1));
301 
302  m_imageCounter++;
303 }
304 
311 {
312  if (m_imageCounter > m_totalImageNumber)
313  throw(vpException(vpException::fatalError, "usMHDSequenceReader : end of sequence reached !"));
314 
315  if (usImageIo::getHeaderFormat(m_sequenceFiles.at(2 * m_imageCounter)) !=
316  usImageIo::FORMAT_MHD) // check file extention
317  throw(vpException(vpException::fatalError, "usMHDSequenceReader trying to open a non-mhd file !"));
318 
319  usMetaHeaderParser mhdParser;
320  mhdParser.read(m_sequenceDirectory + vpIoTools::path("/") +
321  m_sequenceFiles.at(2 * m_imageCounter)); // we skip raw files
322  m_sequenceImageType = mhdParser.getImageType();
323  if (m_sequenceImageType != us::POSTSCAN_3D && m_sequenceImageType != us::NOT_SET) {
324  throw(vpException(vpException::badValue, "Reading a non post-scan 3D image!"));
325  }
326  if (mhdParser.getElementType() != usMetaHeaderParser::MET_UCHAR) {
327  throw(vpException(vpException::badValue, "Reading a non unsigned char image!"));
328  }
329 
330  usMetaHeaderParser::MHDHeader mhdHeader = mhdParser.getMHDHeader();
331  timestamp = 0;
332  if (mhdHeader.timestamp.size() > 0)
333  timestamp = mhdHeader.timestamp.at(0);
334 
335  // resizing image in memory
336  image.resize(mhdHeader.dim[1], mhdHeader.dim[0], mhdHeader.dim[2]);
337 
338  image.setTransducerRadius(mhdHeader.transducerRadius);
339  image.setScanLinePitch(mhdHeader.scanLinePitch);
340  image.setTransducerConvexity(mhdHeader.isTransducerConvex);
341  image.setScanLineNumber(mhdHeader.scanLineNumber);
342  image.setElementSpacingX(mhdHeader.elementSpacing[0]);
343  image.setElementSpacingY(mhdHeader.elementSpacing[1]);
344  image.setElementSpacingZ(mhdHeader.elementSpacing[2]);
345  image.setMotorRadius(mhdHeader.motorRadius);
346  image.setFramePitch(mhdHeader.framePitch);
347  image.setFrameNumber(mhdHeader.frameNumber);
348  image.setMotorType(mhdHeader.motorType);
349  image.setSamplingFrequency(mhdHeader.samplingFrequency);
350  image.setTransmitFrequency(mhdHeader.transmitFrequency);
351 
352  // data parsing
353  usRawFileParser rawParser;
354  rawParser.read(image, m_sequenceDirectory + vpIoTools::path("/") + m_sequenceFiles.at(2 * m_imageCounter + 1));
355 
356  m_imageCounter++;
357 }
358 
363 bool usMHDSequenceReader::end() { return m_imageCounter >= m_totalImageNumber; }
364 
369 us::ImageType usMHDSequenceReader::getImageType() const { return m_sequenceImageType; }
370 
376 {
377  usMetaHeaderParser mhdParser;
378  mhdParser.read(m_sequenceDirectory + vpIoTools::path("/") +
379  m_sequenceFiles.at(2 * m_imageCounter)); // we skip raw files, imagecounter already incremented
380  return mhdParser.getMHDHeader().timestamp.at(0);
381 }
382 
388 {
389  usMetaHeaderParser mhdParser;
390  mhdParser.read(m_sequenceDirectory + vpIoTools::path("/") +
391  m_sequenceFiles.at(2 * m_imageCounter)); // we skip raw files, imagecounter already incremented
392  std::vector<uint64_t> timestamps = mhdParser.getMHDHeader().timestamp;
393  if (m_imageCounter % 2 == 0) // current volume is even => next volume is odd
394  std::reverse(timestamps.begin(), timestamps.end());
395  return timestamps;
396 }
397 
402 int usMHDSequenceReader::getImageNumber() const { return m_imageCounter; }
403 
408 int usMHDSequenceReader::getTotalImageNumber() const { return m_totalImageNumber; }
409 
417 void usMHDSequenceReader::getImage(unsigned int imageNumber, usImageRF2D<short int> &image, uint64_t &timestamp)
418 {
419 
420  if (imageNumber > (unsigned int)m_totalImageNumber)
421  throw(vpException(vpException::fatalError,
422  "usMHDSequenceReader : trying to acquire an image with an index out of sequence bounds !"));
423 
424  if (usImageIo::getHeaderFormat(m_sequenceFiles.at(2 * imageNumber)) != usImageIo::FORMAT_MHD) // check file extention
425  throw(vpException(vpException::fatalError, "usMHDSequenceReader trying to open a non-mhd file !"));
426 
427  usMetaHeaderParser mhdParser;
428  mhdParser.read(m_sequenceDirectory + vpIoTools::path("/") + m_sequenceFiles.at(2 * imageNumber)); // we skip raw files
429  m_sequenceImageType = mhdParser.getImageType();
430  if (m_sequenceImageType != us::RF_2D && m_sequenceImageType != us::NOT_SET) {
431  throw(vpException(vpException::badValue, "Reading a non rf 2D image!"));
432  }
433  if (mhdParser.getElementType() != usMetaHeaderParser::MET_SHORT) {
434  throw(vpException(vpException::badValue, "Reading a non short image!"));
435  }
436 
437  usMetaHeaderParser::MHDHeader mhdHeader = mhdParser.getMHDHeader();
438  timestamp = mhdHeader.timestamp.at(0);
439 
440  usImagePreScanSettings settings;
441  settings.setTransducerRadius(mhdHeader.transducerRadius);
442  settings.setScanLinePitch(mhdHeader.scanLinePitch);
443  settings.setTransducerConvexity(mhdHeader.isTransducerConvex);
444  settings.setAxialResolution(mhdParser.getAxialResolution());
445  settings.setDepth(settings.getAxialResolution() * mhdHeader.dim[1]);
446  settings.setSamplingFrequency(mhdHeader.samplingFrequency);
447  settings.setTransmitFrequency(mhdHeader.transmitFrequency);
448  image.setImagePreScanSettings(settings);
449 
450  // resizing image in memory
451  image.resize(mhdHeader.dim[1], mhdHeader.dim[0]);
452 
453  // data parsing
454  usRawFileParser rawParser;
455  rawParser.read(image, m_sequenceDirectory + vpIoTools::path("/") + m_sequenceFiles.at(2 * imageNumber + 1));
456 }
457 
467  uint64_t &timestamp)
468 {
469  if (imageNumber > (unsigned int)m_totalImageNumber)
470  throw(vpException(vpException::fatalError,
471  "usMHDSequenceReader : trying to acquire an image with an index out of sequence bounds !"));
472 
473  if (usImageIo::getHeaderFormat(m_sequenceFiles.at(2 * imageNumber)) != usImageIo::FORMAT_MHD) // check file extention
474  throw(vpException(vpException::fatalError, "usMHDSequenceReader trying to open a non-mhd file !"));
475 
476  usMetaHeaderParser mhdParser;
477  mhdParser.read(m_sequenceDirectory + vpIoTools::path("/") + m_sequenceFiles.at(2 * imageNumber)); // we skip raw files
478  m_sequenceImageType = mhdParser.getImageType();
479  if (m_sequenceImageType != us::PRESCAN_2D && m_sequenceImageType != us::NOT_SET) {
480  throw(vpException(vpException::badValue, "Reading a non pre-scan 2D image!"));
481  }
482  if (mhdParser.getElementType() != usMetaHeaderParser::MET_UCHAR) {
483  throw(vpException(vpException::badValue, "Reading a non unsigned char image!"));
484  }
485 
486  usMetaHeaderParser::MHDHeader mhdHeader = mhdParser.getMHDHeader();
487  timestamp = mhdHeader.timestamp.at(0);
488 
489  usImagePreScanSettings settings;
490  settings.setTransducerRadius(mhdHeader.transducerRadius);
491  settings.setScanLinePitch(mhdHeader.scanLinePitch);
492  settings.setTransducerConvexity(mhdHeader.isTransducerConvex);
493  settings.setAxialResolution(mhdParser.getAxialResolution());
494  settings.setDepth(settings.getAxialResolution() * mhdHeader.dim[1]);
495  settings.setSamplingFrequency(mhdHeader.samplingFrequency);
496  settings.setTransmitFrequency(mhdHeader.transmitFrequency);
497  image.setImagePreScanSettings(settings);
498 
499  // resizing image in memory
500  image.resize(mhdHeader.dim[1], mhdHeader.dim[0]);
501 
502  // data parsing
503  usRawFileParser rawParser;
504  rawParser.read(image, m_sequenceDirectory + vpIoTools::path("/") + m_sequenceFiles.at(2 * imageNumber + 1));
505 }
506 
516  uint64_t &timestamp)
517 {
518  if (imageNumber > (unsigned int)m_totalImageNumber)
519  throw(vpException(vpException::fatalError,
520  "usMHDSequenceReader : trying to acquire an image with an index out of sequence bounds !"));
521 
522  if (usImageIo::getHeaderFormat(m_sequenceFiles.at(2 * imageNumber)) != usImageIo::FORMAT_MHD) // check file extention
523  throw(vpException(vpException::fatalError, "usMHDSequenceReader trying to open a non-mhd file !"));
524 
525  usMetaHeaderParser mhdParser;
526  mhdParser.read(m_sequenceDirectory + vpIoTools::path("/") + m_sequenceFiles.at(2 * imageNumber)); // we skip raw files
527  m_sequenceImageType = mhdParser.getImageType();
528  if (m_sequenceImageType != us::POSTSCAN_2D && m_sequenceImageType != us::NOT_SET) {
529  throw(vpException(vpException::badValue, "Reading a non post-scan 2D image!"));
530  }
531  if (mhdParser.getElementType() != usMetaHeaderParser::MET_UCHAR) {
532  throw(vpException(vpException::badValue, "Reading a non unsigned char image!"));
533  }
534 
535  usMetaHeaderParser::MHDHeader mhdHeader = mhdParser.getMHDHeader();
536  timestamp = mhdHeader.timestamp.at(0);
537 
538  usImagePreScanSettings settings;
539  image.setTransducerRadius(mhdHeader.transducerRadius);
540  image.setScanLinePitch(mhdHeader.scanLinePitch);
541  image.setTransducerConvexity(mhdHeader.isTransducerConvex);
542 
543  // computing image depth from the pixel size and the transducer settings
544  if (mhdHeader.isTransducerConvex) {
545  // distance
546  double deltaDepthPostScan2D =
547  mhdHeader.transducerRadius *
548  (1 - std::cos((double)((mhdHeader.scanLineNumber - 1) * mhdHeader.scanLinePitch / 2.0)));
549  image.setDepth(mhdHeader.elementSpacing[1] * mhdHeader.dim[1] - deltaDepthPostScan2D);
550  } else // linear transducer
551  image.setDepth(mhdHeader.elementSpacing[1] * mhdHeader.dim[1]);
552 
553  image.setWidthResolution(mhdHeader.dim[0]);
554  image.setWidthResolution(mhdHeader.dim[1]);
555  image.setSamplingFrequency(mhdHeader.samplingFrequency);
556  image.setTransmitFrequency(mhdHeader.transmitFrequency);
557 
558  // resizing image in memory
559  image.resize(mhdHeader.dim[1], mhdHeader.dim[0]);
560 
561  // data parsing
562  usRawFileParser rawParser;
563  rawParser.read(image, m_sequenceDirectory + vpIoTools::path("/") + m_sequenceFiles.at(2 * imageNumber + 1));
564 }
565 
573 void usMHDSequenceReader::getImage(unsigned int imageNumber, usImageRF3D<short int> &image,
574  std::vector<uint64_t> &timestamp)
575 {
576  if (imageNumber > (unsigned int)m_totalImageNumber)
577  throw(vpException(vpException::fatalError, "usMHDSequenceReader : end of sequence reached !"));
578 
579  if (usImageIo::getHeaderFormat(m_sequenceFiles.at(2 * imageNumber)) != usImageIo::FORMAT_MHD) // check file extention
580  throw(vpException(vpException::fatalError, "usMHDSequenceReader trying to open a non-mhd file !"));
581 
582  usMetaHeaderParser mhdParser;
583  mhdParser.read(m_sequenceDirectory + vpIoTools::path("/") + m_sequenceFiles.at(2 * imageNumber)); // we skip raw files
584  m_sequenceImageType = mhdParser.getImageType();
585  if (m_sequenceImageType != us::RF_3D && m_sequenceImageType != us::NOT_SET) {
586  throw(vpException(vpException::badValue, "Reading a non rf 3D image!"));
587  }
588  if (mhdParser.getElementType() != usMetaHeaderParser::MET_SHORT) {
589  throw(vpException(vpException::badValue, "Reading a non short image!"));
590  }
591 
592  usMetaHeaderParser::MHDHeader mhdHeader = mhdParser.getMHDHeader();
593  timestamp = mhdHeader.timestamp;
594  if (imageNumber % 2 == 1) // odd volume: we reverse it
595  std::reverse(timestamp.begin(), timestamp.end());
596 
597  usImagePreScanSettings settings;
598  settings.setTransducerRadius(mhdHeader.transducerRadius);
599  settings.setScanLinePitch(mhdHeader.scanLinePitch);
600  settings.setTransducerConvexity(mhdHeader.isTransducerConvex);
601  settings.setAxialResolution(mhdParser.getAxialResolution());
602  settings.setDepth(settings.getAxialResolution() * mhdHeader.dim[1]);
603  settings.setSamplingFrequency(mhdHeader.samplingFrequency);
604  settings.setTransmitFrequency(mhdHeader.transmitFrequency);
605  image.setImagePreScanSettings(settings);
606 
607  usMotorSettings motorSettings;
608  motorSettings.setMotorRadius(mhdHeader.motorRadius);
609  motorSettings.setFramePitch(mhdHeader.framePitch);
610  motorSettings.setMotorType(mhdHeader.motorType);
611  motorSettings.setFrameNumber(mhdHeader.dim[2]);
612  image.setMotorSettings(motorSettings);
613 
614  // resizing image in memory
615  image.resize(mhdHeader.dim[1], mhdHeader.dim[0], mhdHeader.dim[2]);
616 
617  // data parsing
618  usRawFileParser rawParser;
619  rawParser.read(image, m_sequenceDirectory + vpIoTools::path("/") + m_sequenceFiles.at(2 * imageNumber + 1));
620 }
621 
631  std::vector<uint64_t> &timestamp)
632 {
633  if (imageNumber > (unsigned int)m_totalImageNumber)
634  throw(vpException(vpException::fatalError, "usMHDSequenceReader : end of sequence reached !"));
635 
636  if (usImageIo::getHeaderFormat(m_sequenceFiles.at(2 * imageNumber)) != usImageIo::FORMAT_MHD) // check file extention
637  throw(vpException(vpException::fatalError, "usMHDSequenceReader trying to open a non-mhd file !"));
638 
639  usMetaHeaderParser mhdParser;
640  mhdParser.read(m_sequenceDirectory + vpIoTools::path("/") + m_sequenceFiles.at(2 * imageNumber)); // we skip raw files
641  m_sequenceImageType = mhdParser.getImageType();
642  if (m_sequenceImageType != us::PRESCAN_3D && m_sequenceImageType != us::NOT_SET) {
643  throw(vpException(vpException::badValue, "Reading a non pre-scan 3D image!"));
644  }
645  if (mhdParser.getElementType() != usMetaHeaderParser::MET_UCHAR) {
646  throw(vpException(vpException::badValue, "Reading a non unsigned char image!"));
647  }
648 
649  usMetaHeaderParser::MHDHeader mhdHeader = mhdParser.getMHDHeader();
650  timestamp = mhdHeader.timestamp;
651  if (imageNumber % 2 == 1) // odd volume: we reverse it
652  std::reverse(timestamp.begin(), timestamp.end());
653 
654  usImagePreScanSettings settings;
655  settings.setTransducerRadius(mhdHeader.transducerRadius);
656  settings.setScanLinePitch(mhdHeader.scanLinePitch);
657  settings.setTransducerConvexity(mhdHeader.isTransducerConvex);
658  settings.setAxialResolution(mhdParser.getAxialResolution());
659  settings.setDepth(settings.getAxialResolution() * mhdHeader.dim[1]);
660  settings.setSamplingFrequency(mhdHeader.samplingFrequency);
661  settings.setTransmitFrequency(mhdHeader.transmitFrequency);
662  image.setImagePreScanSettings(settings);
663 
664  usMotorSettings motorSettings;
665  motorSettings.setMotorRadius(mhdHeader.motorRadius);
666  motorSettings.setFramePitch(mhdHeader.framePitch);
667  motorSettings.setMotorType(mhdHeader.motorType);
668  motorSettings.setFrameNumber(mhdHeader.dim[2]);
669  image.setMotorSettings(motorSettings);
670 
671  // resizing image in memory
672  image.resize(mhdHeader.dim[1], mhdHeader.dim[0], mhdHeader.dim[2]);
673 
674  // data parsing
675  usRawFileParser rawParser;
676  rawParser.read(image, m_sequenceDirectory + vpIoTools::path("/") + m_sequenceFiles.at(2 * imageNumber + 1));
677 }
678 
688  uint64_t &timestamp)
689 {
690  if (imageNumber > (unsigned int)m_totalImageNumber)
691  throw(vpException(vpException::fatalError,
692  "usMHDSequenceReader : trying to acquire an image with an index out of sequence bounds !"));
693 
694  if (usImageIo::getHeaderFormat(m_sequenceFiles.at(2 * imageNumber)) != usImageIo::FORMAT_MHD) // check file extention
695  throw(vpException(vpException::fatalError, "usMHDSequenceReader trying to open a non-mhd file !"));
696 
697  usMetaHeaderParser mhdParser;
698  mhdParser.read(m_sequenceDirectory + vpIoTools::path("/") + m_sequenceFiles.at(2 * imageNumber)); // we skip raw files
699  m_sequenceImageType = mhdParser.getImageType();
700  if (m_sequenceImageType != us::POSTSCAN_3D && m_sequenceImageType != us::NOT_SET) {
701  throw(vpException(vpException::badValue, "Reading a non post-scan 3D image!"));
702  }
703  if (mhdParser.getElementType() != usMetaHeaderParser::MET_UCHAR) {
704  throw(vpException(vpException::badValue, "Reading a non unsigned char image!"));
705  }
706 
707  usMetaHeaderParser::MHDHeader mhdHeader = mhdParser.getMHDHeader();
708  timestamp = 0;
709  if (mhdHeader.timestamp.size() > 0)
710  timestamp = mhdHeader.timestamp.at(0);
711 
712  // resizing image in memory
713  image.resize(mhdHeader.dim[1], mhdHeader.dim[0], mhdHeader.dim[2]);
714 
715  image.setTransducerRadius(mhdHeader.transducerRadius);
716  image.setScanLinePitch(mhdHeader.scanLinePitch);
717  image.setTransducerConvexity(mhdHeader.isTransducerConvex);
718  image.setScanLineNumber(mhdHeader.scanLineNumber);
719  image.setElementSpacingX(mhdHeader.elementSpacing[0]);
720  image.setElementSpacingY(mhdHeader.elementSpacing[1]);
721  image.setElementSpacingZ(mhdHeader.elementSpacing[2]);
722  image.setMotorRadius(mhdHeader.motorRadius);
723  image.setFramePitch(mhdHeader.framePitch);
724  image.setFrameNumber(mhdHeader.frameNumber);
725  image.setMotorType(mhdHeader.motorType);
726  image.setSamplingFrequency(mhdHeader.samplingFrequency);
727  image.setTransmitFrequency(mhdHeader.transmitFrequency);
728 
729  // data parsing
730  usRawFileParser rawParser;
731  rawParser.read(image, m_sequenceDirectory + vpIoTools::path("/") + m_sequenceFiles.at(2 * imageNumber + 1));
732 }
void resize(unsigned int height, unsigned int width, unsigned int numberOfFrames)
Definition: usImage3D.h:376
static usHeaderFormatType getHeaderFormat(const std::string &headerfilename)
Definition: usImageIo.cpp:50
@ FORMAT_MHD
Definition: usImageIo.h:152
void setWidthResolution(double widthResolution)
void setElementSpacingZ(double elementSpacingZ)
void setElementSpacingX(double elementSpacingX)
void setElementSpacingY(double elementSpacingY)
void resize(const unsigned int h, const unsigned int w)
void resize(unsigned int height, unsigned int width, unsigned int numberOfFrames)
Settings associated to ultrasound pre-scan images implemented in usImageRF2D, usImageRF3D,...
void setImagePreScanSettings(const usImagePreScanSettings &preScanSettings)
void setAxialResolution(const double axialResolution)
void resize(const unsigned int height, const unsigned int width)
Definition: usImageRF2D.h:328
void resize(unsigned int height, unsigned int width, unsigned int numberOfFrames)
Definition: usImageRF3D.h:357
void acquire(usImageRF2D< short int > &image, uint64_t &timestamp)
std::vector< uint64_t > getNextTimeStamps()
void getImage(unsigned int imageNumber, usImageRF2D< short int > &image, uint64_t &timestamp)
void setSequenceDirectory(const std::string sequenceDirectory)
us::ImageType getImageType() const
Generic class for 3D ultrasound motor settings associated to the 3D probe used during acquisition.
void setMotorSettings(const usMotorSettings &other)
void setMotorType(const usMotorType &motorType)
void setMotorRadius(double motorRadius)
void setFrameNumber(unsigned int frameNumber)
void setFramePitch(double framePitch)
void setTransducerConvexity(const bool isTransducerConvex)
void setDepth(double depth)
void setScanLinePitch(const double scanLinePitch)
void setTransmitFrequency(const int transmitFrequency)
void setSamplingFrequency(const int samplingFrequency)
void setTransducerRadius(const double transducerRadius)
void setScanLineNumber(unsigned int scanLineNumber)
General tools.
ImageType
Definition: us.h:65
@ PRESCAN_2D
Definition: us.h:70
@ POSTSCAN_2D
Definition: us.h:72
@ RF_2D
Definition: us.h:68
@ PRESCAN_3D
Definition: us.h:71
@ NOT_SET
Definition: us.h:67
@ POSTSCAN_3D
Definition: us.h:73
@ RF_3D
Definition: us.h:69