PlusLib  2.9.0
Software library for tracked ultrasound image acquisition, calibration, and processing.
vtkPlusSonixVolumeReader.cxx
Go to the documentation of this file.
1 /*=Plus=header=begin======================================================
2 Program: Plus
3 Copyright (c) Laboratory for Percutaneous Surgery. All rights reserved.
4 See License.txt for details.
5 =========================================================Plus=header=end*/
6 
7 // Local includes
8 #include "PlusConfigure.h"
10 
11 // VTK includes
12 #include <vtkImageData.h>
13 #include <vtkObjectFactory.h>
14 #include <vtkSmartPointer.h>
15 
16 // IGSIO includes
17 #include <igsioTrackedFrame.h>
18 #include <igsioVideoFrame.h>
19 #include <vtkIGSIOTrackedFrameList.h>
20 
21 // STD includes
22 #include <iostream>
23 #include <sstream>
24 
25 // Sonix includes
26 #include <ulterius_def.h>
27 #if PLUS_ULTRASONIX_SDK_MAJOR_VERSION == 1
28  #include <utx_imaging_modes.h>
29 #endif
30 
31 
33 
34 //----------------------------------------------------------------------------
36 {
37 }
38 
39 
40 //----------------------------------------------------------------------------
42 {
43 }
44 
45 //----------------------------------------------------------------------------
46 void vtkPlusSonixVolumeReader::PrintSelf(ostream& os, vtkIndent indent)
47 {
48  this->Superclass::PrintSelf(os, indent);
49 }
50 
51 //----------------------------------------------------------------------------
52 // static
53 PlusStatus vtkPlusSonixVolumeReader::GenerateTrackedFrameFromSonixVolume(const char* volumeFileName, vtkIGSIOTrackedFrameList* trackedFrameList, double acquisitionFrameRate/* = 10*/)
54 {
55  if (volumeFileName == NULL)
56  {
57  LOG_ERROR("Failed to generate tracked frame from sonix volume - input file name is NULL!");
58  return PLUS_FAIL;
59  }
60 
61  if (trackedFrameList == NULL)
62  {
63  LOG_ERROR("Failed to generate tracked frame from sonix volume - output tracked frame list is NULL!");
64  return PLUS_FAIL;
65  }
66 
67  // read data file
68  FILE* fp;
69  errno_t err = fopen_s(&fp, volumeFileName, "rb");
70 
71  if (err != 0)
72  {
73  LOG_ERROR("Error opening volume file: " << volumeFileName << " Error No.: " << err);
74  return PLUS_FAIL;
75  }
76 
77  // Determine file size
78  fseek(fp, 0, SEEK_END);
79  long fileSizeInBytes = ftell(fp);
80  rewind(fp);
81 
82  // Ultrasonix header
83  uFileHeader hdr;
84 
85  // read header
86  fread(&hdr, sizeof(hdr), 1, fp);
87 
88  unsigned int dataType = static_cast<unsigned int>(hdr.type);
89  unsigned int sampleSizeInBytes = static_cast<unsigned int>(hdr.ss / 8);
90  unsigned int numberOfFrames = static_cast<unsigned int>(hdr.frames);
91  unsigned int frameSizeInBytes = static_cast<unsigned int>(hdr.w * hdr.h * sampleSizeInBytes);
92  FrameSizeType frameSize = { static_cast<unsigned int>(hdr.w), static_cast<unsigned int>(hdr.h), 1};
93 
94  // Custom frame fields
95  std::ostringstream strDataType;
96  strDataType << hdr.type;
97 
98  std::ostringstream strTransmitFrequency;
99  strTransmitFrequency << hdr.txf;
100 
101  std::ostringstream strSamplingFrequency;
102  strSamplingFrequency << hdr.sf;
103 
104  std::ostringstream strProbeID;
105  strProbeID << hdr.probe;
106 
107  std::ostringstream strDataRate;
108  strDataRate << hdr.dr;
109 
110  std::ostringstream strLineDensity;
111  strLineDensity << hdr.ld;
112 
113  unsigned int numberOfBytesToSkip = 0;
114  if ((fileSizeInBytes - sizeof(hdr)) > frameSizeInBytes * numberOfFrames)
115  {
116  numberOfBytesToSkip = (fileSizeInBytes - sizeof(hdr)) / numberOfFrames - frameSizeInBytes;
117  LOG_DEBUG("Each frame has " << numberOfBytesToSkip << " bytes header before the actual data");
118  }
119  else if ((fileSizeInBytes - sizeof(hdr)) < frameSizeInBytes * numberOfFrames)
120  {
121  LOG_ERROR("Expected data size for reading (" << frameSizeInBytes * numberOfFrames
122  << " bytes) is larger than actual data size (" << fileSizeInBytes - sizeof(hdr) << " bytes).");
123  return PLUS_FAIL;
124  }
125 
126  // if vector data switch width and height, because the image
127  // is not rasterized like a bitmap, but written rayline by rayline
128  if ((dataType == udtBPre) || (dataType == udtRF) || (dataType == udtMPre) || (dataType == udtPWRF) || (dataType == udtColorRF))
129  {
130  frameSize[0] = hdr.h; // number of data points recorded for one crystal (vectors)
131  frameSize[1] = hdr.w; // number of transducer crystals (samples)
132  frameSize[2] = 1; // only 1 slice
133  }
134 
135  // Pointer to data from file
136  unsigned char* dataFromFile = new unsigned char[frameSizeInBytes];
137 
138  for (unsigned int i = 0; i < numberOfFrames; i++)
139  {
140  // Skip header data
141  fread(dataFromFile, numberOfBytesToSkip, 1, fp);
142 
143  // Read data from file
144  fread(dataFromFile, frameSizeInBytes, 1, fp);
145 
146  igsioCommon::VTKScalarPixelType pixelType = VTK_VOID;
147  switch (dataType)
148  {
149  case udtBPost:
150  pixelType = VTK_UNSIGNED_CHAR;
151  break;
152  case udtRF:
153  pixelType = VTK_SHORT;
154  break;
155  default:
156  LOG_ERROR("Uknown pixel type for data type: " << dataType);
157  continue;
158  }
159 
160  // If in the future sonix generates color images, we can change this to support that
161  unsigned int numberOfScalarComponents = 1;
162 
163  igsioVideoFrame videoFrame;
164  if (videoFrame.AllocateFrame(frameSize, pixelType, numberOfScalarComponents) != PLUS_SUCCESS)
165  {
166  LOG_ERROR("Failed to allocate image data for frame #" << i);
167  continue;
168  }
169 
170  // Copy the frame data form file to vtkImageDataSet
171  memcpy(videoFrame.GetScalarPointer(), dataFromFile, frameSizeInBytes);
172 
173  igsioTrackedFrame trackedFrame;
174  trackedFrame.SetImageData(videoFrame);
175  trackedFrame.SetTimestamp((1.0 * (i + 1)) / acquisitionFrameRate); // Generate timestamp, but don't start from 0
176 
177  trackedFrame.SetFrameField("SonixDataType", strDataType.str());
178  trackedFrame.SetFrameField("SonixTransmitFrequency", strTransmitFrequency.str());
179  trackedFrame.SetFrameField("SonixSamplingFrequency", strSamplingFrequency.str());
180  trackedFrame.SetFrameField("SonixDataRate", strDataRate.str());
181  trackedFrame.SetFrameField("SonixLineDensity", strLineDensity.str());
182  trackedFrame.SetFrameField("SonixProbeID", strProbeID.str());
183 
184 
185  trackedFrameList->AddTrackedFrame(&trackedFrame);
186  }
187 
188  fclose(fp);
189  delete [] dataFromFile;
190 
191  return PLUS_SUCCESS;
192 }
193 
194 
igsioStatus PlusStatus
Definition: PlusCommon.h:40
for i
#define PLUS_FAIL
Definition: PlusCommon.h:43
static PlusStatus GenerateTrackedFrameFromSonixVolume(const char *volumeFileName, vtkIGSIOTrackedFrameList *trackedFrameList, double acquisitionFrameRate=10)
virtual void PrintSelf(ostream &os, vtkIndent indent) VTK_OVERRIDE
#define PLUS_SUCCESS
Definition: PlusCommon.h:44
int VTKScalarPixelType
Definition: PlusCommon.h:55
Reads a volume from file to tracked frame list.
vtkStandardNewMacro(vtkPlusSonixVolumeReader)