X-Git-Url: http://git.kpe.io/?p=ctsim.git;a=blobdiff_plain;f=libctsim%2Fprojections.cpp;h=b3d6d35b2df647b5595d60c01bebcf30771af957;hp=627ccb91f11ba32f85e8feabbca0297487f57509;hb=b361677a2f7d5b443641faec70b057f2a84dc77e;hpb=af74e42547cbc35de784e30ebdbba746ae0fc9e5 diff --git a/libctsim/projections.cpp b/libctsim/projections.cpp index 627ccb9..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.54 2001/03/05 21:59:55 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++) { @@ -952,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); @@ -963,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; + } +}