X-Git-Url: http://git.kpe.io/?a=blobdiff_plain;f=libctsim%2Fprojections.cpp;h=b3d6d35b2df647b5595d60c01bebcf30771af957;hb=b361677a2f7d5b443641faec70b057f2a84dc77e;hp=bec5c0af5fdad93201d403bedfb5cf66dadac009;hpb=0ec398f6f64d51a3a6cc3005d404c74c0c91b271;p=ctsim.git diff --git a/libctsim/projections.cpp b/libctsim/projections.cpp index bec5c0a..b3d6d35 100644 --- a/libctsim/projections.cpp +++ b/libctsim/projections.cpp @@ -8,7 +8,7 @@ ** This is part of the CTSim program ** Copyright (c) 1983-2001 Kevin Rosenberg ** -** $Id: projections.cpp,v 1.53 2001/03/02 20:07:10 kevin Exp $ +** $Id: projections.cpp,v 1.55 2001/03/10 23:14:16 kevin Exp $ ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License (version 2) as @@ -687,6 +687,11 @@ Projections::convertPolar (ImageFile& rIF, int iInterpolationID) if (! v || nx == 0 || ny == 0) return false; + + if (m_geometry != Scanner::GEOMETRY_PARALLEL) { + sys_error (ERR_WARNING, "convertPolar supports Parallel only"); + return false; + } Array2d adView (nx, ny); Array2d adDet (nx, ny); @@ -727,6 +732,11 @@ Projections::convertFFTPolar (ImageFile& rIF, int iInterpolationID, int iZeropad if (! v || nx == 0 || ny == 0) return false; + if (m_geometry != Scanner::GEOMETRY_PARALLEL) { + sys_error (ERR_WARNING, "convertFFTPolar supports Parallel only"); + return false; + } + #ifndef HAVE_FFT return false; #else @@ -784,11 +794,6 @@ Projections::calcArrayPolarCoordinates (unsigned int nx, unsigned int ny, double int iDetCenter = (m_nDet - 1) / 2; // index refering to L=0 projection - if (m_geometry != Scanner::GEOMETRY_PARALLEL) { - sys_error (ERR_WARNING, "convertPolar supports Parallel only"); - return false; - } - // Calculates polar coordinates (view#, det#) for each point on phantom grid double x = xMin + xInc / 2; // Rectang coords of center of pixel for (unsigned int ix = 0; ix < nx; x += xInc, ix++) { @@ -820,8 +825,8 @@ Projections::interpolatePolar (ImageFileArray& v, ImageFileArray& vImag, for (unsigned int ix = 0; ix < ny; ix++) { for (unsigned int iy = 0; iy < ny; iy++) { if (iInterpolationID == POLAR_INTERP_NEAREST) { - int iView = nearest (ppdView[ix][iy]); - int iDet = nearest (ppdDet[ix][iy]); + unsigned int iView = nearest (ppdView[ix][iy]); + unsigned int iDet = nearest (ppdDet[ix][iy]); if (iView == nView) { iView = 0; // iDet = m_nDet - iDet; @@ -836,9 +841,9 @@ Projections::interpolatePolar (ImageFileArray& v, ImageFileArray& vImag, v[ix][iy] = 0; } } else if (iInterpolationID == POLAR_INTERP_BILINEAR) { - int iFloorView = static_cast(ppdView[ix][iy]); + unsigned int iFloorView = static_cast(ppdView[ix][iy]); double dFracView = ppdView[ix][iy] - iFloorView; - int iFloorDet = static_cast(ppdDet[ix][iy]); + unsigned int iFloorDet = static_cast(ppdDet[ix][iy]); double dFracDet = ppdDet[ix][iy] - iFloorDet; if (iFloorDet >= 0 && iFloorView >= 0) { @@ -903,41 +908,42 @@ Projections::initFromSomatomAR_STAR (int iNViews, int iNDets, unsigned char* pDa long lDataPos = 0; for (int iv = 0; iv < iNViews; iv++) { - long* pLong = reinterpret_cast(pData + lDataPos+0); + unsigned char* pArgBase = pData + lDataPos; + unsigned char* p = pArgBase+0; #ifndef WORDS_BIGENDIAN - SwapBytes4 (pLong); + SwapBytes4 (p); #endif - long lProjNumber = *pLong; + long lProjNumber = *reinterpret_cast(p); - pLong = reinterpret_cast(pData + lDataPos+20); + p = pArgBase+20; #ifndef WORDS_BIGENDIAN - SwapBytes4 (pLong); + SwapBytes4 (p); #endif - long lEscale = *pLong; + long lEscale = *reinterpret_cast(p); - pLong = reinterpret_cast(pData + lDataPos+28); + p = pArgBase+28; #ifndef WORDS_BIGENDIAN - SwapBytes4 (pLong); + SwapBytes4 (p); #endif - long lTime = *pLong; + long lTime = *reinterpret_cast(p); - float* pFloat = reinterpret_cast(pData + lDataPos+4); + p = pArgBase + 4; #ifndef WORDS_BIGENDIAN - SwapBytes4 (pFloat); + SwapBytes4 (p); #endif - double dAlpha = *pFloat + HALFPI; + double dAlpha = *reinterpret_cast(p) + HALFPI; - pFloat = reinterpret_cast(pData + lDataPos+12); + p = pArgBase+12; #ifndef WORDS_BIGENDIAN - SwapBytes4 (pFloat); + SwapBytes4 (p); #endif - double dAlign = *pFloat; + double dAlign = *reinterpret_cast(p); - pFloat = reinterpret_cast(pData + lDataPos+16); + p = pArgBase + 16; #ifndef WORDS_BIGENDIAN - SwapBytes4 (pFloat); + SwapBytes4 (p); #endif - double dMaxValue = *pFloat; + double dMaxValue = *reinterpret_cast(p); lDataPos += 32; double dEScale = pow (2.0, -lEscale); @@ -951,7 +957,7 @@ Projections::initFromSomatomAR_STAR (int iNViews, int iNDets, unsigned char* pDa double dTempScale = 2294.4871 * dEScale; for (int id = 0; id < iNDets; id++) { int iV = pData[lDataPos+1] + 256 * pData[lDataPos]; - if (iV > 32767) + if (iV > 32767) // two's complement signed conversion iV = iV - 65536; double dCosScale = cos ((id + 1 - iCenter) * dBetaInc); detval[id] = iV / (dTempScale * dCosScale); @@ -962,3 +968,74 @@ Projections::initFromSomatomAR_STAR (int iNViews, int iNDets, unsigned char* pDa return true; } + +ParallelRaysums::ParallelRaysums (Projections* pProjections) +: m_ppCoordinates(NULL), m_iNumCoordinates(0) +{ + int nDet = pProjections->nDet(); + int nView = pProjections->nView(); + int iGeometry = pProjections->geometry(); + double dDetInc = pProjections->detInc(); + double dDetStart = pProjections->detStart(); + double dFocalLength = pProjections->focalLength(); + + m_iNumCoordinates = nDet * nView; + m_ppCoordinates = new ParallelRaysumCoordinate* [m_iNumCoordinates]; + for (int i = 0; i < m_iNumCoordinates; i++) + m_ppCoordinates[i] = new ParallelRaysumCoordinate; + + ParallelRaysumCoordinate** ppCurrentCoordinate = m_ppCoordinates; + + for (int iV = 0; iV < nView; iV++) { + double dViewAngle = pProjections->getDetectorArray(iV).viewAngle(); + for (int iD = 0; iD < nDet; iD++) { + ParallelRaysumCoordinate* pC = *ppCurrentCoordinate; + if (iGeometry == Scanner::GEOMETRY_PARALLEL) { + pC->m_dTheta = dViewAngle; + pC->m_dT = dDetStart + (iD * dDetInc); + } else if (iGeometry == Scanner::GEOMETRY_EQUILINEAR) { + double dDetPos = dDetStart + (iD * dDetInc); + double dFanAngle = atan (dDetPos / pProjections->sourceDetectorLength()); + pC->m_dTheta = dViewAngle + dFanAngle; + pC->m_dT = dFocalLength * sin(dFanAngle); + } else if (iGeometry == Scanner::GEOMETRY_EQUIANGULAR) { + double dFanAngle = dDetStart + (iD * dDetInc); + pC->m_dTheta = dViewAngle + dFanAngle; + pC->m_dT = dFocalLength * sin(dFanAngle); + } + ++ppCurrentCoordinate; + } + } +} + +ParallelRaysums::~ParallelRaysums() +{ + for (int i = 0; i < m_iNumCoordinates; i++) + delete m_ppCoordinates[i]; + + delete m_ppCoordinates; +} + +void +ParallelRaysums::getLimits (double* dMinT, double* dMaxT, double* dMinTheta, double* dMaxTheta) const +{ + if (m_iNumCoordinates <= 0) + return; + + *dMinT = *dMaxT = m_ppCoordinates[0]->m_dT; + *dMinTheta = *dMaxTheta = m_ppCoordinates[0]->m_dTheta; + + for (int i = 0; i < m_iNumCoordinates; i++) { + double dT = m_ppCoordinates[i]->m_dT; + double dTheta = m_ppCoordinates[i]->m_dTheta; + if (dT < *dMinT) + *dMinT = dT; + else if (dT > *dMaxT) + *dMaxT = dT; + + if (dTheta < *dMinTheta) + *dMinTheta = dTheta; + else if (dTheta > *dMaxTheta) + *dMaxTheta = dTheta; + } +}