summaryrefslogtreecommitdiffstats
path: root/cuda
diff options
context:
space:
mode:
Diffstat (limited to 'cuda')
-rw-r--r--cuda/2d/sart.cu7
-rw-r--r--cuda/2d/sart.h4
-rw-r--r--cuda/2d/sirt.cu8
-rw-r--r--cuda/2d/sirt.h4
-rw-r--r--cuda/3d/astra3d.cu13
-rw-r--r--cuda/3d/astra3d.h2
-rw-r--r--cuda/3d/sirt3d.cu8
-rw-r--r--cuda/3d/sirt3d.h5
8 files changed, 48 insertions, 3 deletions
diff --git a/cuda/2d/sart.cu b/cuda/2d/sart.cu
index e5cb5bb..c8608a3 100644
--- a/cuda/2d/sart.cu
+++ b/cuda/2d/sart.cu
@@ -71,6 +71,8 @@ SART::SART() : ReconAlgo()
projectionCount = 0;
iteration = 0;
customOrder = false;
+
+ fRelaxation = 1.0f;
}
@@ -98,6 +100,7 @@ void SART::reset()
projectionCount = 0;
iteration = 0;
customOrder = false;
+ fRelaxation = 1.0f;
ReconAlgo::reset();
}
@@ -200,10 +203,10 @@ bool SART::iterate(unsigned int iterations)
// BP, mask, and add back
// TODO: Try putting the masking directly in the BP
zeroVolumeData(D_tmpData, tmpPitch, dims);
- callBP_SART(D_tmpData, tmpPitch, D_projData, projPitch, angle, 1.0f);
+ callBP_SART(D_tmpData, tmpPitch, D_projData, projPitch, angle, fRelaxation);
processVol<opAddMul>(D_volumeData, D_maskData, D_tmpData, volumePitch, dims);
} else {
- callBP_SART(D_volumeData, volumePitch, D_projData, projPitch, angle, 1.0f);
+ callBP_SART(D_volumeData, volumePitch, D_projData, projPitch, angle, fRelaxation);
}
if (useMinConstraint)
diff --git a/cuda/2d/sart.h b/cuda/2d/sart.h
index 7dcd641..eff9ecf 100644
--- a/cuda/2d/sart.h
+++ b/cuda/2d/sart.h
@@ -50,6 +50,8 @@ public:
virtual float computeDiffNorm();
+ void setRelaxation(float r) { fRelaxation = r; }
+
protected:
void reset();
bool precomputeWeights();
@@ -78,6 +80,8 @@ protected:
// Geometry-specific precomputed data
float* D_lineWeight;
unsigned int linePitch;
+
+ float fRelaxation;
};
}
diff --git a/cuda/2d/sirt.cu b/cuda/2d/sirt.cu
index 162ee77..4baaccb 100644
--- a/cuda/2d/sirt.cu
+++ b/cuda/2d/sirt.cu
@@ -50,6 +50,8 @@ SIRT::SIRT() : ReconAlgo()
D_minMaskData = 0;
D_maxMaskData = 0;
+ fRelaxation = 1.0f;
+
freeMinMaxMasks = false;
}
@@ -83,6 +85,8 @@ void SIRT::reset()
useVolumeMask = false;
useSinogramMask = false;
+ fRelaxation = 1.0f;
+
ReconAlgo::reset();
}
@@ -139,6 +143,9 @@ bool SIRT::precomputeWeights()
processVol<opMul>(D_pixelWeight, D_maskData, pixelPitch, dims);
}
+ // Also fold the relaxation factor into pixel weights
+ processVol<opMul>(D_pixelWeight, fRelaxation, pixelPitch, dims);
+
return true;
}
@@ -253,6 +260,7 @@ bool SIRT::iterate(unsigned int iterations)
callBP(D_tmpData, tmpPitch, D_projData, projPitch, 1.0f);
+ // pixel weights also contain the volume mask and relaxation factor
processVol<opAddMul>(D_volumeData, D_pixelWeight, D_tmpData, volumePitch, dims);
if (useMinConstraint)
diff --git a/cuda/2d/sirt.h b/cuda/2d/sirt.h
index 21094a1..bc913f4 100644
--- a/cuda/2d/sirt.h
+++ b/cuda/2d/sirt.h
@@ -53,6 +53,8 @@ public:
bool uploadMinMaxMasks(const float* minMaskData, const float* maxMaskData,
unsigned int pitch);
+ void setRelaxation(float r) { fRelaxation = r; }
+
virtual bool iterate(unsigned int iterations);
virtual float computeDiffNorm();
@@ -81,6 +83,8 @@ protected:
unsigned int minMaskPitch;
float* D_maxMaskData;
unsigned int maxMaskPitch;
+
+ float fRelaxation;
};
bool doSIRT(float* D_volumeData, unsigned int volumePitch,
diff --git a/cuda/3d/astra3d.cu b/cuda/3d/astra3d.cu
index 8328229..5670873 100644
--- a/cuda/3d/astra3d.cu
+++ b/cuda/3d/astra3d.cu
@@ -267,6 +267,7 @@ public:
float fOriginDetectorDistance;
float fSourceZ;
float fDetSize;
+ float fRelaxation;
SConeProjection* projs;
SPar3DProjection* parprojs;
@@ -311,6 +312,8 @@ AstraSIRT3d::AstraSIRT3d()
pData->parprojs = 0;
pData->fOutputScale = 1.0f;
+ pData->fRelaxation = 1.0f;
+
pData->initialized = false;
pData->setStartReconstruction = false;
@@ -389,6 +392,14 @@ bool AstraSIRT3d::enableSuperSampling(unsigned int iVoxelSuperSampling,
return true;
}
+void AstraSIRT3d::setRelaxation(float r)
+{
+ if (pData->initialized)
+ return;
+
+ pData->fRelaxation = r;
+}
+
bool AstraSIRT3d::enableVolumeMask()
{
if (pData->initialized)
@@ -448,6 +459,8 @@ bool AstraSIRT3d::init()
if (!ok)
return false;
+ pData->sirt.setRelaxation(pData->fRelaxation);
+
pData->D_volumeData = allocateVolumeData(pData->dims);
ok = pData->D_volumeData.ptr;
if (!ok)
diff --git a/cuda/3d/astra3d.h b/cuda/3d/astra3d.h
index 2782994..2137587 100644
--- a/cuda/3d/astra3d.h
+++ b/cuda/3d/astra3d.h
@@ -68,6 +68,8 @@ public:
bool enableSuperSampling(unsigned int iVoxelSuperSampling,
unsigned int iDetectorSuperSampling);
+ void setRelaxation(float r);
+
// Enable volume/sinogram masks
//
// This may optionally be called before init().
diff --git a/cuda/3d/sirt3d.cu b/cuda/3d/sirt3d.cu
index 484521e..713944b 100644
--- a/cuda/3d/sirt3d.cu
+++ b/cuda/3d/sirt3d.cu
@@ -59,6 +59,8 @@ SIRT::SIRT() : ReconAlgo3D()
useMinConstraint = false;
useMaxConstraint = false;
+
+ fRelaxation = 1.0f;
}
@@ -89,6 +91,8 @@ void SIRT::reset()
useVolumeMask = false;
useSinogramMask = false;
+ fRelaxation = 1.0f;
+
ReconAlgo3D::reset();
}
@@ -196,6 +200,8 @@ bool SIRT::precomputeWeights()
// scale pixel weights with mask to zero out masked pixels
processVol3D<opMul>(D_pixelWeight, D_maskData, dims);
}
+ processVol3D<opMul>(D_pixelWeight, fRelaxation, dims);
+
return true;
}
@@ -307,7 +313,7 @@ bool SIRT::iterate(unsigned int iterations)
}
#endif
-
+ // pixel weights also contain the volume mask and relaxation factor
processVol3D<opAddMul>(D_volumeData, D_tmpData, D_pixelWeight, dims);
if (useMinConstraint)
diff --git a/cuda/3d/sirt3d.h b/cuda/3d/sirt3d.h
index bb3864a..5e93deb 100644
--- a/cuda/3d/sirt3d.h
+++ b/cuda/3d/sirt3d.h
@@ -48,6 +48,9 @@ public:
// init should be called after setting all geometry
bool init();
+ // Set relaxation factor. This may be called after init and before iterate.
+ void setRelaxation(float r) { fRelaxation = r; }
+
// setVolumeMask should be called after init and before iterate,
// but only if enableVolumeMask was called before init.
// It may be called again after iterate.
@@ -91,6 +94,8 @@ protected:
float fMinConstraint;
float fMaxConstraint;
+ float fRelaxation;
+
cudaPitchedPtr D_maskData;
cudaPitchedPtr D_smaskData;