UsTK : Ultrasound ToolKit  version 2.0.1 under development (2023-12-07)
usImageRF3D.h
1 /****************************************************************************
2  *
3  * This file is part of the ustk software.
4  * Copyright (C) 2016 - 2017 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * ("GPL") version 2 as published by the Free Software Foundation.
9  * See the file LICENSE.txt at the root directory of this source
10  * distribution for additional information about the GNU GPL.
11  *
12  * For using ustk with software that can not be combined with the GNU
13  * GPL, please contact Inria about acquiring a ViSP Professional
14  * Edition License.
15  *
16  * This software was developed at:
17  * Inria Rennes - Bretagne Atlantique
18  * Campus Universitaire de Beaulieu
19  * 35042 Rennes Cedex
20  * France
21  *
22  * If you have questions regarding the use of this file, please contact
23  * Inria at ustk@inria.fr
24  *
25  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
26  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27  *
28  * Authors:
29  * Marc Pouliquen
30  *
31  *****************************************************************************/
32 
38 #ifndef __usImageRF3D_h_
39 #define __usImageRF3D_h_
40 
41 #include <cstring>
42 
43 #include <visp3/ustk_core/usImageRF2D.h>
44 
45 #include <visp3/ustk_core/usImagePreScanSettings.h>
46 #include <visp3/ustk_core/usMotorSettings.h>
47 
135 template <class Type> class usImageRF3D : public usImagePreScanSettings, public usMotorSettings
136 {
137  friend class usRawFileParser;
138 
139 public:
141  usImageRF3D(unsigned int height, unsigned int width, unsigned int numberOfFrames);
142  usImageRF3D(unsigned int height, unsigned int width, unsigned int numberOfFrames,
143  const usImagePreScanSettings &imageSettings, const usMotorSettings &motorSettings);
145  virtual ~usImageRF3D();
146 
147  void getFrame(usImageRF2D<Type> &image, unsigned int index) const;
148 
149  const Type *getConstData() const;
150 
151  unsigned int getWidth() const;
152  unsigned int getHeight() const;
153  unsigned int getNumberOfFrames() const;
154 
155  unsigned int getRFSampleNumber() const;
156 
157  unsigned int getSize() const;
158 
159  void insertFrame(const usImageRF2D<short> &frame, unsigned int index);
160 
162  bool operator==(const usImageRF3D<Type> &other);
163 
164  Type operator()(unsigned int i, unsigned int indexJ, unsigned int k) const;
165  void operator()(unsigned int i, unsigned int indexJ, unsigned int k, const Type &value);
166 
167  void setFrameNumber(unsigned int frameNumber);
168  void setScanLineNumber(unsigned int scanLineNumber);
169 
170  void resize(unsigned int height, unsigned int width, unsigned int numberOfFrames);
171 
172 private:
173  void init(unsigned int height, unsigned int width, unsigned int numberOfFrames);
174 
175  unsigned int m_width;
176  unsigned int m_height;
177  unsigned int m_numberOfFrames;
178  unsigned int m_size;
180  Type *bitmap;
181  Type **framPointer;
182 };
183 
187 template <class Type>
189  : usImagePreScanSettings(), usMotorSettings(), m_width(0), m_height(0), m_numberOfFrames(0), m_size(0), bitmap(NULL),
190  framPointer(NULL)
191 {
192 }
193 
197 template <class Type>
198 usImageRF3D<Type>::usImageRF3D(unsigned int height, unsigned int width, unsigned int numberOfFrames)
199  : usImagePreScanSettings(), usMotorSettings(), m_width(0), m_height(0), m_numberOfFrames(0), m_size(0), bitmap(NULL),
200  framPointer(NULL)
201 {
202  resize(height, width, numberOfFrames);
203 }
204 
213 template <class Type>
214 usImageRF3D<Type>::usImageRF3D(unsigned int height, unsigned int width, unsigned int numberOfFrames,
215  const usImagePreScanSettings &preScanSettings, const usMotorSettings &motorSettings)
216  : usImagePreScanSettings(preScanSettings), usMotorSettings(motorSettings), m_width(0), m_height(0),
217  m_numberOfFrames(0), m_size(0), bitmap(NULL), framPointer(NULL)
218 {
219  if (width != preScanSettings.getScanLineNumber())
220  throw(vpException(vpException::badValue, "3D RF image U-size differ from transducer scanline number"));
221  if (numberOfFrames != motorSettings.getFrameNumber())
222  throw(vpException(vpException::badValue, "3D RF image W-size differ from motor frame number"));
223 
224  init(height, width, numberOfFrames);
225 }
226 
231 template <class Type>
233  : usImagePreScanSettings(other), usMotorSettings(other), m_width(0), m_height(0), m_numberOfFrames(0), m_size(0),
234  bitmap(NULL)
235 {
236  init(other.getHeight(), other.getWidth(), other.getNumberOfFrames());
237  memcpy(bitmap, other.getConstData(), (size_t)(m_width * m_height * m_numberOfFrames * sizeof(Type)));
238 }
239 
243 template <class Type> usImageRF3D<Type>::~usImageRF3D()
244 {
245  if (bitmap) {
246  delete[] bitmap;
247  bitmap = NULL;
248  }
249  if (framPointer) {
250  delete[] framPointer;
251  framPointer = NULL;
252  }
253 }
254 
260 {
261  // allocation and resize
262  resize(other.getHeight(), other.getWidth(), other.getNumberOfFrames());
263 
264  // filling voxel values
265  memcpy(bitmap, other.getConstData(), (size_t)(m_width * m_height * m_numberOfFrames * sizeof(Type)));
266 
267  // from usImageSettings
269 
270  // from usMotorSettings
272 
273  return *this;
274 }
275 
280 template <class Type> bool usImageRF3D<Type>::operator==(const usImageRF3D<Type> &other)
281 {
282  // test image settings
283  if (!usImagePreScanSettings::operator==(other))
284  return false;
285  if (!usMotorSettings::operator==(other))
286  return false;
287 
288  // test dimentions
289  if (this->m_width != other.getWidth())
290  return false;
291  if (this->m_height != other.getHeight())
292  return false;
293  if (this->m_numberOfFrames != other.getNumberOfFrames())
294  return false;
295 
296  // test bitmap
297  for (unsigned int i = 0; i < m_size; i++) {
298  if (bitmap[i] != other.bitmap[i]) {
299  return false;
300  }
301  }
302 
303  return true;
304 }
305 
309 template <class Type> std::ostream &operator<<(std::ostream &out, const usImageRF3D<Type> &image)
310 {
311  return out << "width : " << image.getWidth() << "\nheight : " << image.getHeight()
312  << "\nnumberOfFrames : " << image.getNumberOfFrames() << std::endl
313  << static_cast<const usImagePreScanSettings &>(image) << static_cast<const usMotorSettings &>(image);
314 }
315 
319 template <class Type> unsigned int usImageRF3D<Type>::getRFSampleNumber() const { return getHeight(); }
320 
327 template <class Type> void usImageRF3D<Type>::setScanLineNumber(unsigned int scanLineNumber)
328 {
329  if (scanLineNumber != m_width)
330  resize(getHeight(), scanLineNumber, getNumberOfFrames());
332 }
333 
340 template <class Type> void usImageRF3D<Type>::setFrameNumber(unsigned int frameNumber)
341 {
342  if (frameNumber != m_numberOfFrames)
343  resize(getHeight(), getWidth(), frameNumber);
344  usMotorSettings::setFrameNumber(frameNumber);
345 }
346 
356 template <class Type>
357 void usImageRF3D<Type>::resize(unsigned int height, unsigned int width, unsigned int numberOfFrames)
358 {
359  init(height, width, numberOfFrames);
360  usMotorSettings::setFrameNumber(numberOfFrames);
362 }
363 
369 template <class Type> void usImageRF3D<Type>::insertFrame(const usImageRF2D<short> &frame, unsigned int index)
370 {
371  // Dimentions checks
372  if (index > this->getNumberOfFrames())
373  throw(vpException(vpException::badValue, "usImageRF3D::insertFrame : frame index out of volume"));
374 
375  if (frame.getHeight() != this->getHeight() || frame.getWidth() != this->getWidth())
376  throw(vpException(vpException::badValue, "usImageRF3D::insertFrame : frame size don't match volume size"));
377 
378  // offset to access the frame in the volume
379  int offset = index * this->getHeight() * this->getWidth();
380  Type *frameBeginning = bitmap + offset;
381 
382  // copy
383  for (unsigned int i = 0; i < this->getHeight(); i++) {
384  for (unsigned int j = 0; j < this->getWidth(); j++) {
385  frameBeginning[i + this->getHeight() * j] = frame(i, j);
386  }
387  }
388 }
389 
395 template <class Type> void usImageRF3D<Type>::getFrame(usImageRF2D<Type> &image, unsigned int index) const
396 {
397  // Dimentions checks
398  if (index > this->getNumberOfFrames())
399  throw(vpException(vpException::badValue, "usImageRF3D::getFrame : frame index out of volume"));
400 
401  image.resize(this->getHeight(), this->getWidth());
402 
403  image.setImagePreScanSettings(getImagePreScanSettings());
404 
405  // offset to access the frame beginning in the volume
406  int offset = index * this->getHeight() * this->getWidth();
407  const Type *frameBeginning = this->getConstData() + offset;
408 
409  // copy
410  for (unsigned int i = 0; i < this->getHeight(); i++) {
411  for (unsigned int j = 0; j < this->getWidth(); j++) {
412  image(i, j, frameBeginning[i + this->getHeight() * j]);
413  }
414  }
415 }
416 
434 template <class Type> void usImageRF3D<Type>::init(unsigned int height, unsigned int width, unsigned int numberOfFrames)
435 {
436  if ((width != this->m_width) || (height != this->m_height) || (numberOfFrames != this->m_numberOfFrames)) {
437  if (bitmap != NULL) {
438  delete[] bitmap;
439  bitmap = NULL;
440  }
441  if (framPointer != NULL) {
442  delete[] framPointer;
443  framPointer = NULL;
444  }
445  }
446 
447  this->m_width = width;
448  this->m_height = height;
449  this->m_numberOfFrames = numberOfFrames;
450 
451  m_size = m_width * m_height * m_numberOfFrames;
452 
453  if (bitmap == NULL)
454  bitmap = new Type[m_size];
455 
456  if (framPointer == NULL)
457  framPointer = new Type *[numberOfFrames];
458 
459  for (unsigned int k = 0; k < numberOfFrames; k++)
460  framPointer[k] = bitmap + m_width * m_height * k;
461 
462  if (bitmap == NULL) {
463  throw(vpException(vpException::memoryAllocationError, "cannot allocate bitmap "));
464  }
465 }
466 
471 template <class Type> unsigned int usImageRF3D<Type>::getWidth() const { return m_width; }
472 
477 template <class Type> unsigned int usImageRF3D<Type>::getHeight() const { return m_height; }
478 
483 template <class Type> unsigned int usImageRF3D<Type>::getNumberOfFrames() const { return m_numberOfFrames; }
484 
489 template <class Type> unsigned int usImageRF3D<Type>::getSize() const { return m_size; }
490 
495 template <class Type> const Type *usImageRF3D<Type>::getConstData() const { return bitmap; }
496 
503 template <class Type> Type usImageRF3D<Type>::operator()(unsigned int i, unsigned int j, unsigned int k) const
504 {
505  bool indexOK = j < m_width && i < m_height && k < m_numberOfFrames;
506  if (!indexOK)
507  throw(vpException(vpException::dimensionError, "usImageRF3D : accessing a voxel out of range !"));
508 
509  return framPointer[k][m_height * j + i];
510 }
511 
519 template <class Type>
520 void usImageRF3D<Type>::operator()(unsigned int i, unsigned int j, unsigned int k, const Type &value)
521 {
522  bool indexOK = j < m_width && i < m_height && k < m_numberOfFrames;
523  if (!indexOK)
524  throw(vpException(vpException::dimensionError, "usImageRF3D : trying to write in a voxel out of range !"));
525  framPointer[k][m_height * j + i] = value;
526 }
527 
528 #endif // __usImageRF3D_h_
Settings associated to ultrasound pre-scan images implemented in usImageRF2D, usImageRF3D,...
void setImagePreScanSettings(const usImagePreScanSettings &preScanSettings)
usImagePreScanSettings & operator=(const usImagePreScanSettings &other)
2D Radio Frequence (RF) ultrasound image.
Definition: usImageRF2D.h:112
unsigned int getHeight() const
Definition: usImageRF2D.h:412
void resize(const unsigned int height, const unsigned int width)
Definition: usImageRF2D.h:328
unsigned int getWidth() const
Definition: usImageRF2D.h:424
3D Radio Frequence (RF) ultrasound image.
Definition: usImageRF3D.h:136
bool operator==(const usImageRF3D< Type > &other)
Definition: usImageRF3D.h:280
usImageRF3D< Type > & operator=(const usImageRF3D< Type > &other)
Definition: usImageRF3D.h:259
void setScanLineNumber(unsigned int scanLineNumber)
Definition: usImageRF3D.h:327
usImageRF3D(unsigned int height, unsigned int width, unsigned int numberOfFrames, const usImagePreScanSettings &imageSettings, const usMotorSettings &motorSettings)
Definition: usImageRF3D.h:214
Type operator()(unsigned int i, unsigned int indexJ, unsigned int k) const
Access operator for value in voxel (i, j, k)
Definition: usImageRF3D.h:503
void getFrame(usImageRF2D< Type > &image, unsigned int index) const
Definition: usImageRF3D.h:395
void setFrameNumber(unsigned int frameNumber)
Definition: usImageRF3D.h:340
usImageRF3D(const usImageRF3D< Type > &other)
Definition: usImageRF3D.h:232
void operator()(unsigned int i, unsigned int indexJ, unsigned int k, const Type &value)
Set value in voxel (i, j, k)
Definition: usImageRF3D.h:520
void insertFrame(const usImageRF2D< short > &frame, unsigned int index)
Definition: usImageRF3D.h:369
usImageRF3D(unsigned int height, unsigned int width, unsigned int numberOfFrames)
Definition: usImageRF3D.h:198
unsigned int getWidth() const
Definition: usImageRF3D.h:471
unsigned int getSize() const
Definition: usImageRF3D.h:489
friend class usRawFileParser
Definition: usImageRF3D.h:137
const Type * getConstData() const
Definition: usImageRF3D.h:495
void resize(unsigned int height, unsigned int width, unsigned int numberOfFrames)
Definition: usImageRF3D.h:357
unsigned int getHeight() const
Definition: usImageRF3D.h:477
unsigned int getRFSampleNumber() const
Definition: usImageRF3D.h:319
unsigned int getNumberOfFrames() const
Definition: usImageRF3D.h:483
virtual ~usImageRF3D()
Definition: usImageRF3D.h:243
Generic class for 3D ultrasound motor settings associated to the 3D probe used during acquisition.
usMotorSettings & operator=(const usMotorSettings &other)
unsigned int getFrameNumber() const
void setFrameNumber(unsigned int frameNumber)
unsigned int getScanLineNumber() const
void setScanLineNumber(unsigned int scanLineNumber)