00001 #pragma once
00002
00003 #include "common.h"
00004 #include <stdlib.h>
00005 #include <vector>
00006
00007 #include <algorithm>
00008 #include <functional>
00009
00010 #include "Matrix.h"
00011
00012
00014 class Volume
00015 {
00016 public:
00017
00018 class Voxel
00019 {
00020 public:
00021
00025 Voxel()
00026 {
00027 SetValue(0.0f);
00028 };
00029
00034 Voxel(const Voxel & datOther)
00035 {
00036 m_fValue = datOther.m_fValue;
00037 };
00038
00043 Voxel(const float fValue)
00044 {
00045 SetValue(fValue);
00046 };
00047
00048
00052 ~Voxel()
00053 {
00054 };
00055
00056
00061 void SetValue(const float fValue)
00062 {
00063 m_fValue = fValue;
00064 };
00065
00070 const float GetValue() const
00071 {
00072 return m_fValue;
00073 };
00074
00075 const bool operator==(const Voxel &datOther) const
00076 {
00077 return (GetValue() == datOther.GetValue());
00078 };
00079
00080 const bool operator!=(const Voxel &datOther) const
00081 {
00082 return !(*this == datOther);
00083 };
00084
00085 const bool operator>(const Voxel &datOther) const
00086 {
00087 return GetValue() > datOther.GetValue();
00088 };
00089
00090 const bool operator>=(const Voxel &datOther) const
00091 {
00092 return GetValue() >= datOther.GetValue();
00093 };
00094
00095 const bool operator<(const Voxel &datOther) const
00096 {
00097 return GetValue() < datOther.GetValue();
00098 };
00099
00100 const bool operator<=(const Voxel &datOther) const
00101 {
00102 return GetValue() <= datOther.GetValue();
00103 };
00104
00105 const Voxel & operator+=(const Voxel & datOther)
00106 {
00107 m_fValue += datOther.m_fValue;
00108 return *this;
00109 };
00110
00111 const Voxel & operator-=(const Voxel & datOther)
00112 {
00113 m_fValue -= datOther.m_fValue;
00114 return *this;
00115 };
00116
00117 const Voxel & operator*=(const float & fOther)
00118 {
00119 m_fValue *= fOther;
00120 return *this;
00121 };
00122
00123 const Voxel & operator/=(const float & fOther)
00124 {
00125 m_fValue /= fOther;
00126 return *this;
00127 };
00128
00129 const Voxel operator+(const Voxel & datOther) const
00130 {
00131 Voxel voxNew = *this;
00132 voxNew += datOther;
00133 return voxNew;
00134 };
00135
00136 const Voxel operator-(const Voxel & datOther) const
00137 {
00138 Voxel voxNew = *this;
00139 voxNew -= datOther;
00140 return voxNew;
00141 };
00142
00143 const Voxel operator*(const float & fOther) const
00144 {
00145 Voxel voxNew = *this;
00146 voxNew *= fOther;
00147 return voxNew;
00148 };
00149
00150 const Voxel operator/(const float & fOther) const
00151 {
00152 Voxel voxNew = *this;
00153 voxNew /= fOther;
00154 return voxNew;
00155 };
00156
00157 private:
00158 float m_fValue;
00159 };
00160
00161 public:
00162
00166 Volume() : m_iWidth(1), m_iHeight(1), m_iDepth(1), m_vecVoxels(1)
00167 {
00168 };
00169
00174 Volume(const std::string &strFilename) : m_iWidth(1), m_iHeight(1), m_iDepth(1), m_vecVoxels(1)
00175 {
00176 load(strFilename);
00177 };
00178
00179
00183 ~Volume(void)
00184 {
00185 };
00186
00187
00194 const Voxel & Get(const int iX, const int iY, const int iZ) const
00195 {
00196 return m_vecVoxels[iX + iY*m_iWidth + iZ*m_iWidth*m_iHeight];
00197 };
00198
00204 const Voxel & Get(const int iIndex) const
00205 {
00206 return m_vecVoxels[iIndex];
00207 };
00208
00209
00214 const Voxel * Get() const
00215 {
00216 return &(m_vecVoxels.front());
00217 };
00218
00219
00224 const int GetWidth() const
00225 {
00226 return m_iWidth;
00227 };
00228
00229
00234 const int GetHeight() const
00235 {
00236 return m_iHeight;
00237 };
00238
00239
00244 const int GetDepth() const
00245 {
00246 return m_iDepth;
00247 };
00248
00253 const int GetSize() const
00254 {
00255 return int(m_vecVoxels.size());
00256 };
00257
00262 void load(const std::string & strFilename)
00263 {
00264 std::cout << "- Loading file '" << strFilename << "' ... " << std::endl;
00265 FILE *fp = NULL;
00266
00267 fopen_s(&fp,strFilename.c_str(),"rb");
00268
00269 if (!fp)
00270 {
00271 std::cerr << "+ Error loading file." << std::endl << std::endl;
00272 }
00273 else
00274 {
00275
00276 char vcPath[1024];
00277 char *pFileName = NULL;
00278 GetFullPathName(strFilename.c_str(),1024,vcPath,&pFileName);
00279 char vcDrive[1024], vcDirectory[1024], vcFilename[1024], vcExtension[1024];
00280 _splitpath_s(vcPath,vcDrive,vcDirectory,vcFilename,vcExtension);
00281 const std::string strAdditionalFilename = std::string(vcDrive)+std::string(vcDirectory)+std::string(vcFilename)+std::string(".ini");
00282
00283 char vpSpacingX[1024],vpSpacingY[1024],vpSpacingZ[1024];
00284 GetPrivateProfileString("DatFile","oldDat Spacing X","1.0",vpSpacingX,256,strAdditionalFilename.c_str());
00285 GetPrivateProfileString("DatFile","oldDat Spacing Y","1.0",vpSpacingY,256,strAdditionalFilename.c_str());
00286 GetPrivateProfileString("DatFile","oldDat Spacing Z","1.0",vpSpacingZ,256,strAdditionalFilename.c_str());
00287
00288
00289 unsigned short uWidth, uHeight, uDepth;
00290 fread(&uWidth,sizeof(unsigned short),1,fp);
00291 fread(&uHeight,sizeof(unsigned short),1,fp);
00292 fread(&uDepth,sizeof(unsigned short),1,fp);
00293
00294 m_iWidth = int(uWidth);
00295 m_iHeight = int(uHeight);
00296 m_iDepth = int(uDepth);
00297
00298 const int iSlice = m_iWidth * m_iHeight;
00299 const int iSize = iSlice * m_iDepth;
00300 m_vecVoxels.resize(iSize);
00301
00302 std::vector<unsigned short> vecData;
00303 vecData.resize(iSize);
00304
00305 fread((void*)&(vecData.front()),sizeof(unsigned short),iSize,fp);
00306 fclose(fp);
00307
00308 std::cout << "- File loaded." << std::endl;
00309
00310 for (int k=0;k<m_iDepth;k++)
00311 {
00312 for (int j=0;j<m_iHeight;j++)
00313 {
00314 for (int i=0;i<m_iWidth;i++)
00315 {
00316
00317 const float fValue = min(1.0f,float(vecData[i + j*m_iWidth + k*iSlice]) / 4095.0f);
00318 m_vecVoxels[i+j*m_iWidth+k*iSlice] = Voxel(fValue);
00319 }
00320 }
00321 std::cout << "\r- Preparing data (" << (k*100) / (m_iDepth-1) << "%) ...";
00322 }
00323 std::cout << std::endl << "- Data prepared." << std::endl;
00324 }
00325 };
00326
00330 void computeGradients()
00331 {
00332 float *volume = (float*)((void * ) Get());
00333 int actIndex;
00334 int xpreIndex;
00335 int xpostIndex;
00336 int ypreIndex;
00337 int ypostIndex;
00338 int zpreIndex;
00339 int zpostIndex;
00340 int gradIndex;
00341
00342
00343 gradients = new float[3 * m_iWidth * m_iHeight * m_iDepth];
00344
00345 float *gradient = new float[3];
00346 const int iSlice = m_iWidth * m_iHeight;
00347 float min = 999.99f;
00348 float max = -999.99f;
00349
00350 for(int k = 0, kThird = 0; kThird < m_iDepth; k = k+3, kThird++)
00351 {
00352 for(int j = 0, jThird = 0; jThird < m_iHeight; j = j+3, jThird++)
00353 {
00354 for(int i = 0, iThird = 0; iThird < m_iWidth; i = i+3, iThird++)
00355 {
00356
00357 gradIndex = i + j * m_iWidth + k * iSlice;
00358 actIndex = iThird + jThird * m_iWidth + kThird * iSlice;
00359 xpreIndex = actIndex - 1;
00360 xpostIndex = actIndex + 1;
00361 ypreIndex = actIndex - m_iWidth;
00362 ypostIndex = actIndex + m_iWidth;
00363 zpreIndex = actIndex - iSlice;
00364 zpostIndex = actIndex + iSlice;
00365
00366
00367 if(iThird == 0)
00368
00369 gradient[0] = volume[xpostIndex] - volume[actIndex];
00370 else if (iThird == m_iWidth - 1)
00371
00372 gradient[0] = volume[actIndex] - volume[xpreIndex];
00373 else
00374
00375 gradient[0] = 0.5f * (volume[xpostIndex] - volume[xpreIndex]);
00376
00377 gradients[gradIndex] = (gradient[0] + 1.0f) / 2.0f;
00378
00379
00380 if(gradient[0] < min)
00381 min = gradient[0];
00382 if(gradient[0] > max)
00383 max = gradient[0];
00384
00385
00386
00387 if(jThird == 0)
00388
00389 gradient[1] = volume[ypostIndex] - volume[actIndex];
00390 else if (jThird == m_iHeight - 1)
00391
00392 gradient[1] = volume[actIndex] - volume[ypreIndex];
00393 else
00394
00395 gradient[1] = 0.5f * (volume[ypostIndex] - volume[ypreIndex]);
00396
00397 gradients[gradIndex + 1] = (gradient[1] + 1.0f) / 2.0f;
00398
00399
00400 if(gradient[1] < min)
00401 min = gradient[1];
00402 if(gradient[1] > max)
00403 max = gradient[1];
00404
00405
00406
00407 if(kThird == 0)
00408
00409 gradient[2] = volume[zpostIndex] - volume[actIndex];
00410 else if (kThird == m_iDepth - 1)
00411
00412 gradient[2] = volume[actIndex] - volume[zpreIndex];
00413 else
00414
00415 gradient[2] = 0.5f * (volume[zpostIndex] - volume[zpreIndex]);
00416
00417 gradients[gradIndex + 2] = (gradient[2] * 1.0f) / 2.0f;
00418
00419 if(gradient[2] < min)
00420 min = gradient[2];
00421 if(gradient[2] > max)
00422 max = gradient[2];
00423
00424
00425 }
00426
00427
00428
00429 }
00430
00431
00432 std::cout << "\r- Computing gradients (" <<(kThird * 100) / (m_iDepth-1) << "%) ...";
00433
00434 }
00435
00436 std::cout << std::endl << "- Gradients computed - "<< std::endl;
00437
00438
00439
00440 };
00441
00446 float *getGradients()
00447 {
00448 return gradients;
00449 };
00450
00451 protected:
00452
00453 private:
00455 std::vector<Voxel> m_vecVoxels;
00457 int m_iWidth,m_iHeight,m_iDepth;
00458
00460 float *gradients;
00461 };