33 #ifndef __EMSCRIPTEN__ 35 #include "image_mhd.h" 36 #include "boost/algorithm/string.hpp" 40 template<
typename T,
int nDims>
41 ImageMHD<T, nDims>::ImageMHD(std::string full_path_to_file):
45 binaryDataByteOrderMSB_(false),
46 compressedData_(false),
47 transformMatrix_(Mat3d(1.0)),
48 offset_(Vec3d(0.0,0.0,0.0)),
49 centerOfRotation_(Vec3d(0.0,0.0,0.0)),
50 elementSpacing_(Vec3d(1.0,1.0,1.0)),
51 dimSize_(Vec3i(1,1,1)),
55 size_(dimSize_[0] * dimSize_[1] * dimSize_[2]),
56 anatomicalOrientation_(
"???"),
57 elementType_(MET_FLOAT),
60 max_value_(-Infinity),
64 std::ifstream dataFile(full_path_to_file, std::ifstream::in);
65 std::string file_path_to_raw_file;
66 if (dataFile.is_open())
69 std::vector<std::string> values;
70 while (std::getline(dataFile, line))
72 std::stringstream ss(line);
73 std::vector<std::string> elements;
74 split(line,
'=', elements);
75 if (elements.size() == 2)
77 boost::trim(elements[0]);
78 boost::trim(elements[1]);
79 if (elements[0].compare(
"TransformMatrix") == 0)
81 std::vector<std::string> values;
82 split(elements[1],
' ', values);
83 transformMatrix_[0][0] = std::stof(values[0]);
84 transformMatrix_[0][1] = std::stof(values[1]);
85 transformMatrix_[0][2] = std::stof(values[2]);
86 transformMatrix_[1][0] = std::stof(values[3]);
87 transformMatrix_[1][1] = std::stof(values[4]);
88 transformMatrix_[1][2] = std::stof(values[5]);
89 transformMatrix_[2][0] = std::stof(values[6]);
90 transformMatrix_[2][1] = std::stof(values[7]);
91 transformMatrix_[2][2] = std::stof(values[8]);
93 else if (elements[0].compare(
"Offset") == 0)
95 std::vector<std::string> values;
96 split(elements[1],
' ', values);
97 offset_[0] = std::stof(values[0]);
98 offset_[1] = std::stof(values[1]);
99 offset_[2] = std::stof(values[2]);
101 else if (elements[0].compare(
"ElementSpacing") == 0)
103 std::vector<std::string> values;
104 split(elements[1],
' ', values);
105 elementSpacing_[0] = std::stof(values[0]);
106 elementSpacing_[1] = std::stof(values[1]);
107 elementSpacing_[2] = std::stof(values[2]);
109 else if (elements[0].compare(
"DimSize") == 0)
111 std::vector<std::string> values;
112 split(elements[1],
' ', values);
113 dimSize_[0] = std::stoi(values[0]);
114 dimSize_[1] = std::stoi(values[1]);
115 dimSize_[2] = std::stoi(values[2]);
116 width_ = dimSize_[0];
117 height_ = dimSize_[1];
118 depth_ = dimSize_[2];
119 size_ = width_ * height_*depth_;
121 data_ =
new T[dimSize_[0] * dimSize_[1] * dimSize_[2]];
123 else if (elements[0].compare(
"ElementDataFile") == 0)
125 full_path_to_file = full_path_to_file.substr(0, full_path_to_file.find_last_of(
"\\/"));
126 file_path_to_raw_file = full_path_to_file +
'/' + elements[1];
133 std::cout <<
"dimensions: " << dimSize_ << std::endl;
134 std::cout <<
"spacing: " << elementSpacing_ << std::endl;
135 std::cout <<
"offset: " << offset_ << std::endl;
136 std::cout <<
"transformMatrix: " << transformMatrix_ << std::endl;
139 std::ifstream dataFileRaw(file_path_to_raw_file, std::ios::in | std::ios::binary);
141 if (dataFileRaw.is_open())
143 dataFileRaw.read((
char*)data_,
sizeof(T)*size_);
145 for(
int index = 0; index<size_; index++)
147 distance = data_[index];
148 data_[index] = distance;
150 if (distance < min_value_) min_value_ = distance;
151 if (distance > max_value_) max_value_ = distance;
158 template<
typename T,
int nDims>
159 ImageMHD<T, nDims>::ImageMHD(
Real radius, Vec3i NxNyNz, Vec3d spacings):
160 objectType_(
"Image"),
163 binaryDataByteOrderMSB_(false),
164 compressedData_(false),
165 transformMatrix_(Mat3d(1.0)),
166 offset_(Vec3d(-0.5*NxNyNz[0]*spacings[0], -0.5*NxNyNz[1] * spacings[1], -0.5*NxNyNz[2] * spacings[2])),
167 centerOfRotation_(Vec3d(0.0, 0.0, 0.0)),
168 elementSpacing_(spacings),
171 height_(dimSize_[1]),
173 size_(width_*height_*depth_),
174 anatomicalOrientation_(
"???"),
175 elementType_(MET_FLOAT),
176 elementDataFile_(
""),
177 min_value_(Infinity),
178 max_value_(-Infinity),
182 data_ =
new float[size_];
184 Vec3d center(0.5*width_, 0.5*height_, 0.5*depth_);
186 for (
int z = 0; z < depth_; z++)
188 for (
int y = 0; y < height_; y++)
190 for (
int x = 0; x < width_; x++)
192 int index = z * width_*height_ + y * width_ + x;
193 double distance = (Vec3d(x, y, z) - center).norm() - radius;
194 if (distance < min_value_) min_value_ = distance;
195 if (distance > max_value_) max_value_ = distance;
196 data_[index] = float(distance);
200 write(std::string(
"sphere"), BINARY);
203 template<
typename T,
int nDims>
204 ImageMHD<T, nDims>::~ImageMHD()
214 template<
typename T,
int nDims>
215 std::vector<int> ImageMHD<T, nDims>::findNeighbors(
const Vec3d& input_pnt, Vec3i& this_cell)
217 std::vector<int> neighbors;
219 Vec3d image_coord = transformMatrix_.invert()*(input_pnt - offset_);
222 int z = int(floor(image_coord[2]));
223 int y = int(floor(image_coord[1]));
224 int x = int(floor(image_coord[0]));
227 if (x < 0 || x > width_ - 1 || y < 0 || y > height_ - 1 || z < 0 || z > depth_ - 1)
return neighbors;
229 for (
int k = z - 1; k < z + 2; k = k + 2)
231 for (
int j = y - 1; j < y + 2; j = j + 2)
233 for (
int i = x - 1; i < x + 2; i = i + 2)
235 if (i<0 || i >width_ - 1 || j <0 || j >height_ - 1 || k<0 || k >depth_)
237 int index = z * width_*height_ + y * width_ + x;
238 neighbors.push_back(index);
248 template<
typename T,
int nDims>
249 Vec3d ImageMHD<T, nDims>::computeGradientAtCell(
int i)
253 int height = height_;
255 int sliceSize = width * height;
256 int z = i / sliceSize;
257 int y = (i%sliceSize) / width;
258 int x = (i%sliceSize) % width;
260 double gradx = 0.0;
double grady = 0.0;
double gradz = 0.0;
265 int indexHigh = z * sliceSize + y * width + (x + 1);
266 gradx = (getValueAtCell(indexHigh) - getValueAtCell(i));
268 else if (x == width - 1)
270 int indexLow = z * sliceSize + y * width + (x - 1);
271 gradx = -(getValueAtCell(indexLow) - getValueAtCell(i));
273 else if (x > 0 && x < width_ - 1)
275 int indexHigh = z * sliceSize + y * width + (x + 1);
276 int indexLow = z * sliceSize + y * width + (x - 1);
277 gradx = (getValueAtCell(indexHigh) - getValueAtCell(indexLow)) / 2.0;
282 int indexHigh = z * sliceSize + (y + 1)*width + x;
283 grady = (getValueAtCell(indexHigh) - getValueAtCell(i));
285 else if (y == height - 1)
287 int indexLow = z * sliceSize + (y - 1)*width + x;
288 grady = -(getValueAtCell(indexLow) - getValueAtCell(i));
290 else if (y > 0 && y < height_ - 1)
292 int indexHigh = z * sliceSize + (y + 1)*width + x;
293 int indexLow = z * sliceSize + (y - 1)*width + x;
294 grady = (getValueAtCell(indexHigh) - getValueAtCell(indexLow)) / 2.0;
299 int indexHigh = (z + 1)*sliceSize + y * width + x;
300 gradz = (getValueAtCell(indexHigh) - getValueAtCell(i));
302 else if (z == depth - 1)
304 int indexLow = (z - 1)*sliceSize + y * width + x;
305 gradz = -(getValueAtCell(indexLow) - getValueAtCell(i));
307 else if (z > 0 && z < depth_ - 1)
309 int indexHigh = (z + 1)*sliceSize + y * width + x;
310 int indexLow = (z - 1)*sliceSize + y * width + x;
311 gradz = (getValueAtCell(indexHigh) - getValueAtCell(indexLow)) / 2.0;
313 gradx = gradx / elementSpacing_[0];
314 grady = grady / elementSpacing_[1];
315 gradz = gradz / elementSpacing_[2];
316 return Vec3d(gradx, grady, gradz);
320 template<
typename T,
int nDims>
321 Vec3d ImageMHD<T, nDims>::computeNormalAtCell(
int i)
323 Vec3d grad_phi = computeGradientAtCell(i);
324 Vec3d n = grad_phi.normalize();
328 template<
typename T,
int nDims>
329 T ImageMHD<T, nDims>::getValueAtCell(
int i)
331 if (i < 0 || i > size_)
333 return float(max_value_);
342 template<
typename T,
int nDims>
343 Vec3d ImageMHD<T, nDims>::convertToPhysicalSpace(Vec3d p)
345 Vec3d position = transformMatrix_ * p + offset_;
346 for (
int i = 0; i < position.size(); i++)
348 position[i] = position[i] * elementSpacing_[i];
354 template<
typename T,
int nDims>
355 void ImageMHD<T, nDims>::split(
const std::string &s,
char delim, \
356 std::vector<std::string> &elems)
358 std::stringstream ss(s);
360 while (std::getline(ss, item, delim)) {
361 if (item.length() > 0) elems.push_back(item);
365 template<
typename T,
int nDims>
366 Vec3d ImageMHD<T, nDims>::findClosestPoint(
const Vec3d& input_pnt)
369 std::vector<int> neighbors = findNeighbors(input_pnt, this_cell);
370 Vec3d n_sum(0.0, 0.0, 0.0);
371 double weight_sum = 0.0;
373 for (
const int& i : neighbors)
376 Vec3d nCj = computeNormalAtCell(i);
377 double dCj = float(getValueAtCell(i));
378 double weight_Cj = 1.0 / (fabs(dCj) + Eps);
379 n_sum = n_sum + weight_Cj * nCj;
380 weight_sum = weight_sum + weight_Cj;
383 Vec3d n = n_sum / (weight_sum + Eps);
384 double d = d_sum / (weight_sum + Eps);
386 Vec3d p_image = Vec3d(this_cell[0], this_cell[1], this_cell[2]) + n.normalize()*d;
387 Vec3d p = convertToPhysicalSpace(p_image);
392 template<
typename T,
int nDims>
393 BoundingBox ImageMHD<T, nDims>::findBounds()
396 Vec3d lower_bound = Vec3d(Infinity);
397 Vec3d upper_bound = Vec3d(-Infinity);
399 for (
int z = 0; z < depth_ + 1; z++)
401 for (
int y = 0; y < height_ + 1; y++)
403 for (
int x = 0; x < width_ + 1; x++)
405 Vec3d p_image = Vec3d(x, y, z);
406 Vec3d vertex_position = convertToPhysicalSpace(p_image);
407 for (
int j = 0; j != 3; ++j) {
408 lower_bound[j] = SMIN(lower_bound[j], vertex_position[j]);
409 upper_bound[j] = SMAX(upper_bound[j], vertex_position[j]);
414 return BoundingBox(lower_bound, upper_bound);
417 template<
typename T,
int nDims>
418 Real ImageMHD<T, nDims>::findValueAtPoint(
const Vec3d& input_pnt)
421 std::vector<int> neighbors = findNeighbors(input_pnt, this_cell);
422 double weight_sum = 0.0;
424 if (neighbors.size() > 0)
426 for (
const int& i : neighbors)
429 double dCj = float(getValueAtCell(i));
430 double weight_Cj = 1.0 / (fabs(dCj) + Eps);
431 weight_sum = weight_sum + weight_Cj;
434 return d_sum / (weight_sum + Eps);
443 template<
typename T,
int nDims>
444 Vec3d ImageMHD<T, nDims>::findNormalAtPoint(
const Vec3d & input_pnt)
447 std::vector<int> neighbors = findNeighbors(input_pnt, this_cell);
448 Vec3d n_sum(0.0, 0.0, 0.0);
449 double weight_sum = 0.0;
451 if (neighbors.size() > 0)
453 for (
const int& i : neighbors)
456 Vec3d nCj = computeNormalAtCell(i);
457 double dCj = float(getValueAtCell(i));
458 double weight_Cj = 1.0 / (fabs(dCj) + Eps);
459 n_sum = n_sum + weight_Cj * nCj;
460 weight_sum = weight_sum + weight_Cj;
463 Vec3d n = n_sum / (weight_sum + Eps);
464 return n.normalize();
468 return Vec3d(1.0, 1.0, 1.0).normalize();
473 template<
typename T,
int nDims>
474 void ImageMHD<T, nDims>::write(std::string filename, Output_Mode mode)
476 std::ofstream output_file(filename+
".mhd", std::ofstream::out);
477 output_file <<
"ObjectType = " << objectType_ <<
"\n";
478 output_file <<
"NDims = " << ndims_ <<
"\n";
480 output_file <<
"BinaryData = True" <<
"\n";
482 output_file <<
"BinaryData = False" <<
"\n";
483 output_file <<
"BinaryDataByteOrderMSB = " << binaryDataByteOrderMSB_ <<
"\n";
484 output_file <<
"CompressedData = " << compressedData_ <<
"\n";
485 output_file <<
"TransformMatrix = " 486 << transformMatrix_[0][0] <<
" " << transformMatrix_[0][1] <<
" " << transformMatrix_[0][2] <<
" " 487 << transformMatrix_[1][0] <<
" " << transformMatrix_[1][1] <<
" " << transformMatrix_[1][2] <<
" " 488 << transformMatrix_[2][0] <<
" " << transformMatrix_[2][1] <<
" " << transformMatrix_[2][2] <<
"\n";
489 output_file <<
"Offset = " 490 << offset_[0] <<
" " << offset_[1] <<
" " << offset_[2] <<
"\n";
491 output_file <<
"CenterOfRotation = " 492 << centerOfRotation_[0] <<
" " << centerOfRotation_[1] <<
" " << centerOfRotation_[2] <<
"\n";
493 output_file <<
"ElementSpacing = " 494 << elementSpacing_[0] <<
" " << elementSpacing_[1] <<
" " << elementSpacing_[2] <<
"\n";
495 output_file <<
"DimSize = " 496 << dimSize_[0] <<
" " << dimSize_[1] <<
" " << dimSize_[2] <<
"\n";
497 output_file <<
"AnatomicalOrientation = " << anatomicalOrientation_ <<
"\n";
498 if (elementType_ == MET_FLOAT)
499 output_file <<
"ElementType = MET_FLOAT" <<
"\n";
500 else if (elementType_ == MET_UCHAR)
501 output_file <<
"ElementType = MET_UCHAR" <<
"\n";
502 if (elementType_ == MET_LONG)
503 output_file <<
"ElementType = MET_LONG" <<
"\n";
504 output_file <<
"ElementDataFile = "<< filename+
".raw" <<
"\n";
510 std::ofstream output_file_raw(filename +
".raw", std::ios::binary | std::ios::out);
511 output_file_raw.write((
const char*)data_,
sizeof(T)*size_);
512 output_file_raw.close();
516 std::ofstream output_file_raw(filename +
".raw");
517 for (
int index = 0; index < size_; index++)
519 output_file_raw << data_[index] << std::endl;
521 output_file_raw.close();
527 #endif //__EMSCRIPTEN__ 529 #endif //IMAGE_MHD_HPP
Definition: solid_body_supplementary.cpp:9