** This is part of the CTSim program
** Copyright (c) 1983-2001 Kevin Rosenberg
**
-** $Id: backprojectors.cpp,v 1.26 2001/02/11 04:56:37 kevin Exp $
+** $Id: backprojectors.cpp,v 1.32 2001/03/18 18:08:25 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
const int Backprojector::BPROJ_DIFF = 2;
const int Backprojector::BPROJ_IDIFF = 3;
-const char* Backprojector::s_aszBackprojectName[] =
+const char* const Backprojector::s_aszBackprojectName[] =
{
{"trig"},
{"table"},
{"idiff"},
};
-const char* Backprojector::s_aszBackprojectTitle[] =
+const char* const Backprojector::s_aszBackprojectTitle[] =
{
{"Direct Trigometric"},
{"Trigometric Table"},
const int Backprojector::INTERP_3BSPLINE = 7;
#endif
-const char* Backprojector::s_aszInterpName[] =
+const char* const Backprojector::s_aszInterpName[] =
{
{"nearest"},
{"linear"},
#endif
};
-const char* Backprojector::s_aszInterpTitle[] =
+const char* const Backprojector::s_aszInterpTitle[] =
{
{"Nearest"},
{"Linear"},
-Backprojector::Backprojector (const Projections& proj, ImageFile& im, const char* const backprojName, const char* const interpName, const int interpFactor)
+Backprojector::Backprojector (const Projections& proj, ImageFile& im, const char* const backprojName,
+ const char* const interpName, const int interpFactor, const ReconstructionROI* pROI)
{
m_fail = false;
m_pBackprojectImplem = NULL;
- initBackprojector (proj, im, backprojName, interpName, interpFactor);
+ initBackprojector (proj, im, backprojName, interpName, interpFactor, pROI);
}
void
m_pBackprojectImplem->BackprojectView (viewData, viewAngle);
}
+void
+Backprojector::PostProcessing()
+{
+ if (m_pBackprojectImplem != NULL)
+ m_pBackprojectImplem->PostProcessing();
+}
+
Backprojector::~Backprojector ()
{
delete m_pBackprojectImplem;
// and initializes the backprojector
bool
-Backprojector::initBackprojector (const Projections& proj, ImageFile& im, const char* const backprojName, const char* const interpName, const int interpFactor)
+Backprojector::initBackprojector (const Projections& proj, ImageFile& im, const char* const backprojName,
+ const char* const interpName, const int interpFactor, const ReconstructionROI* pROI)
{
m_nameBackproject = backprojName;
m_nameInterpolation = interpName;
}
if (proj.geometry() == Scanner::GEOMETRY_EQUILINEAR)
- m_pBackprojectImplem = static_cast<Backproject*>(new BackprojectEquilinear(proj, im, m_idInterpolation, interpFactor));
+ m_pBackprojectImplem = static_cast<Backproject*>(new BackprojectEquilinear(proj, im, m_idInterpolation, interpFactor, pROI));
else if (proj.geometry() == Scanner::GEOMETRY_EQUIANGULAR)
- m_pBackprojectImplem = static_cast<Backproject*>(new BackprojectEquiangular(proj, im, m_idInterpolation, interpFactor));
+ m_pBackprojectImplem = static_cast<Backproject*>(new BackprojectEquiangular(proj, im, m_idInterpolation, interpFactor, pROI));
else if (proj.geometry() == Scanner::GEOMETRY_PARALLEL) {
if (m_idBackproject == BPROJ_TRIG)
- m_pBackprojectImplem = static_cast<Backproject*>(new BackprojectTrig (proj, im, m_idInterpolation, interpFactor));
+ m_pBackprojectImplem = static_cast<Backproject*>(new BackprojectTrig (proj, im, m_idInterpolation, interpFactor, pROI));
else if (m_idBackproject == BPROJ_TABLE)
- m_pBackprojectImplem = static_cast<Backproject*>(new BackprojectTable (proj, im, m_idInterpolation, interpFactor));
+ m_pBackprojectImplem = static_cast<Backproject*>(new BackprojectTable (proj, im, m_idInterpolation, interpFactor, pROI));
else if (m_idBackproject == BPROJ_DIFF)
- m_pBackprojectImplem = static_cast<Backproject*>(new BackprojectDiff (proj, im, m_idInterpolation, interpFactor));
+ m_pBackprojectImplem = static_cast<Backproject*>(new BackprojectDiff (proj, im, m_idInterpolation, interpFactor, pROI));
else if (m_idBackproject == BPROJ_IDIFF)
- m_pBackprojectImplem = static_cast<Backproject*>(new BackprojectIntDiff (proj, im, m_idInterpolation, interpFactor));
+ m_pBackprojectImplem = static_cast<Backproject*>(new BackprojectIntDiff (proj, im, m_idInterpolation, interpFactor, pROI));
} else {
m_fail = true;
m_failMessage = "Unable to select a backprojection method [Backprojector::initBackprojector]";
// PURPOSE
// Pure virtual base class for all backprojectors.
-Backproject::Backproject (const Projections& proj, ImageFile& im, int interpType, const int interpFactor)
-: proj(proj), im(im), interpType(interpType), m_interpFactor(interpFactor)
+Backproject::Backproject (const Projections& proj, ImageFile& im, int interpType, const int interpFactor,
+ const ReconstructionROI* pROI)
+: proj(proj), im(im), interpType(interpType), m_interpFactor(interpFactor), m_bPostProcessingDone(false)
{
detInc = proj.detInc();
nDet = proj.nDet();
yMin = -proj.phmLen() / 2;
yMax = yMin + proj.phmLen();
+ if (pROI) {
+ if (pROI->m_dXMin > xMin)
+ xMin = pROI->m_dXMin;
+ if (pROI->m_dXMax < xMax)
+ xMax = pROI->m_dXMax;
+ if (pROI->m_dYMin > yMin)
+ yMin = pROI->m_dYMin;
+ if (pROI->m_dYMax < yMax)
+ yMax = pROI->m_dYMax;
+
+ if (xMin > xMax) {
+ double temp = xMin;
+ xMin = xMax;
+ xMax = temp;
+ }
+ if (yMin > yMax) {
+ double temp = yMin;
+ yMin = yMax;
+ yMax = temp;
+ }
+ }
+
xInc = (xMax - xMin) / nx; // size of cells
yInc = (yMax - yMin) / ny;
+ im.setAxisIncrement (xInc, yInc);
+ im.setAxisExtent (xMin, xMax, yMin, yMax);
+
m_dFocalLength = proj.focalLength();
+ m_dSourceDetectorLength = proj.sourceDetectorLength();
}
Backproject::~Backproject ()
{}
+void
+Backproject::PostProcessing()
+{
+ m_bPostProcessingDone = true;
+}
+
void
Backproject::ScaleImageByRotIncrement ()
{
double frac = p - pFloor; // fraction distance from det
if (iDetPos >= 0 && iDetPos < nDet - 1)
v[ix][iy] += rotScale * ((1-frac) * filteredProj[iDetPos] + frac * filteredProj[iDetPos+1]);
- } else if (interpType = Backprojector::INTERP_CUBIC) {
+ } else if (interpType == Backprojector::INTERP_CUBIC) {
double p = iDetCenter + (L / detInc); // position along detector
if (p >= 0 && p < nDet)
v[ix][iy] += rotScale * pCubicInterp->interpolate (p);
// PURPOSE
// Precalculates trigometric function value for each point in image for backprojection.
-BackprojectTable::BackprojectTable (const Projections& proj, ImageFile& im, int interpType, const int interpFactor)
-: Backproject (proj, im, interpType, interpFactor)
+BackprojectTable::BackprojectTable (const Projections& proj, ImageFile& im, int interpType,
+ const int interpFactor, const ReconstructionROI* pROI)
+: Backproject (proj, im, interpType, interpFactor, pROI)
{
arrayR.initSetSize (im.nx(), im.ny());
arrayPhi.initSetSize (im.nx(), im.ny());
BackprojectTable::~BackprojectTable ()
{
- ScaleImageByRotIncrement();
+}
+
+void
+BackprojectTable::PostProcessing()
+{
+ if (! m_bPostProcessingDone) {
+ ScaleImageByRotIncrement();
+ m_bPostProcessingDone = true;
+ }
}
void
double frac = dPos - dPosFloor; // fraction distance from det
if (iDetPos >= 0 && iDetPos < nDet - 1)
pImCol[iy] += ((1-frac) * filteredProj[iDetPos] + frac * filteredProj[iDetPos+1]);
- } else if (interpType = Backprojector::INTERP_CUBIC) {
+ } else if (interpType == Backprojector::INTERP_CUBIC) {
double p = iDetCenter + (L / detInc); // position along detector
if (p >= 0 && p < nDet)
pImCol[iy] += pCubicInterp->interpolate (p);
// Backprojects by precalculating the change in L position for each x & y step in the image.
// Iterates in x & y direction by adding difference in L position
-BackprojectDiff::BackprojectDiff (const Projections& proj, ImageFile& im, int interpType, const int interpFactor)
-: Backproject (proj, im, interpType, interpFactor)
+BackprojectDiff::BackprojectDiff (const Projections& proj, ImageFile& im, int interpType,
+ const int interpFactor, const ReconstructionROI* pROI)
+: Backproject (proj, im, interpType, interpFactor, pROI)
{
// calculate center of first pixel v[0][0]
double x = xMin + xInc / 2;
im.arrayDataClear();
}
-BackprojectDiff::~BackprojectDiff()
+BackprojectDiff::~BackprojectDiff ()
{
- ScaleImageByRotIncrement();
}
+void
+BackprojectDiff::PostProcessing()
+{
+ if (! m_bPostProcessingDone) {
+ ScaleImageByRotIncrement();
+ m_bPostProcessingDone = true;
+ }
+}
void
BackprojectDiff::BackprojectView (const double* const filteredProj, const double view_angle)
double frac = curDetPos - detPosFloor; // fraction distance from det
if (iDetPos > 0 && iDetPos < nDet - 1)
*pImCol++ += filteredProj[iDetPos] + (frac * (filteredProj[iDetPos+1] - filteredProj[iDetPos]));
- } else if (interpType = Backprojector::INTERP_CUBIC) {
+ } else if (interpType == Backprojector::INTERP_CUBIC) {
double p = iDetCenter + curDetPos; // position along detector
if (p >= 0 && p < nDet)
*pImCol++ += pCubicInterp->interpolate (p);
if (iDetPos >= 0 && iDetPos <= iLastDet)
*pImCol++ += filteredProj[iDetPos] + (detRemainder * deltaFilteredProj[iDetPos]);
} // end for iy
- } else if (interpType = Backprojector::INTERP_CUBIC) {
+ } else if (interpType == Backprojector::INTERP_CUBIC) {
for (int iy = 0; iy < ny; iy++, curDetPos += det_dy) {
*pImCol++ += pCubicInterp->interpolate (static_cast<double>(curDetPos) / 65536);
}
double dU = (m_dFocalLength + rsin_t) / m_dFocalLength;
double dDetPos = rcos_t / dU;
- // double to scale for imaginary detector that passes through origin
- // of phantom, see Kak-Slaney Figure 3.22. This assumes that the detector is also
- // located focal-length away from the origin.
- dDetPos *= 2;
+ // Scale for imaginary detector that passes through origin of phantom, see Kak-Slaney Figure 3.22.
+ dDetPos *= m_dSourceDetectorLength / m_dFocalLength;
double dPos = dDetPos / detInc; // position along detector array
if (interpType == Backprojector::INTERP_NEAREST) {