Example #1
0
void fastTwoPowerFourierTransform2D(unsigned int iHeight,
                                    unsigned int iWidth,
                                    const float32* pfRealIn,
                                    const float32* pfImaginaryIn,
                                    float32* pfRealOut,
                                    float32* pfImaginaryOut,
                                    bool inverse)
{
	//calculate the fourier transform of the columns
	for (unsigned int x = 0; x < iWidth; x++)
	{
		fastTwoPowerFourierTransform1D(iHeight, pfRealIn+x, pfImaginaryIn+x,
		                               pfRealOut+x, pfImaginaryOut+x,
		                               iWidth, iWidth, inverse);
	}

	//calculate the fourier transform of the rows
	for (unsigned int y = 0; y < iHeight; y++)
	{
		fastTwoPowerFourierTransform1D(iWidth,
		                               pfRealOut+y*iWidth,
		                               pfImaginaryOut+y*iWidth,
		                               pfRealOut+y*iWidth,
		                               pfImaginaryOut+y*iWidth,
		                               1, 1, inverse);
	}
}
//----------------------------------------------------------------------------------------
void CFilteredBackProjectionAlgorithm::performFiltering(CFloat32ProjectionData2D * _pFilteredSinogram)
{
	ASTRA_ASSERT(_pFilteredSinogram != NULL);
	ASTRA_ASSERT(_pFilteredSinogram->getAngleCount() == m_pSinogram->getAngleCount());
	ASTRA_ASSERT(_pFilteredSinogram->getDetectorCount() == m_pSinogram->getDetectorCount());


	int iAngleCount = m_pProjector->getProjectionGeometry()->getProjectionAngleCount();
	int iDetectorCount = m_pProjector->getProjectionGeometry()->getDetectorCount();


	// We'll zero-pad to the smallest power of two at least 64 and
	// at least 2*iDetectorCount
	int zpDetector = 64;
	int nextPow2 = 5;
	while (zpDetector < iDetectorCount*2) {
		zpDetector *= 2;
		nextPow2++;
	}

	// Create filter
	float32* filter = new float32[zpDetector];

	for (int iDetector = 0; iDetector <= zpDetector/2; iDetector++)
		filter[iDetector] = (2.0f * iDetector)/zpDetector;

	for (int iDetector = zpDetector/2+1; iDetector < zpDetector; iDetector++)
		filter[iDetector] = (2.0f * (zpDetector - iDetector)) / zpDetector;


	float32* pfRe = new float32[iAngleCount * zpDetector];
	float32* pfIm = new float32[iAngleCount * zpDetector];

	// Copy and zero-pad data
	for (int iAngle = 0; iAngle < iAngleCount; ++iAngle) {
		float32* pfReRow = pfRe + iAngle * zpDetector;
		float32* pfImRow = pfIm + iAngle * zpDetector;
		float32* pfDataRow = _pFilteredSinogram->getData() + iAngle * iDetectorCount;
		for (int iDetector = 0; iDetector < iDetectorCount; ++iDetector) {
			pfReRow[iDetector] = pfDataRow[iDetector];
			pfImRow[iDetector] = 0.0f;
		}
		for (int iDetector = iDetectorCount; iDetector < zpDetector; ++iDetector) {
			pfReRow[iDetector] = 0.0f;
			pfImRow[iDetector] = 0.0f;
		}
	}

	// in-place FFT
	for (int iAngle = 0; iAngle < iAngleCount; ++iAngle) {
		float32* pfReRow = pfRe + iAngle * zpDetector;
		float32* pfImRow = pfIm + iAngle * zpDetector;

		fastTwoPowerFourierTransform1D(zpDetector, pfReRow, pfImRow, pfReRow, pfImRow, 1, 1, false);
	}

	// Filter
	for (int iAngle = 0; iAngle < iAngleCount; ++iAngle) {
		float32* pfReRow = pfRe + iAngle * zpDetector;
		float32* pfImRow = pfIm + iAngle * zpDetector;
		for (int iDetector = 0; iDetector < zpDetector; ++iDetector) {
			pfReRow[iDetector] *= filter[iDetector];
			pfImRow[iDetector] *= filter[iDetector];
		}
	}

	// in-place inverse FFT
	for (int iAngle = 0; iAngle < iAngleCount; ++iAngle) {
		float32* pfReRow = pfRe + iAngle * zpDetector;
		float32* pfImRow = pfIm + iAngle * zpDetector;

		fastTwoPowerFourierTransform1D(zpDetector, pfReRow, pfImRow, pfReRow, pfImRow, 1, 1, true);
	}

	// Copy data back
	for (int iAngle = 0; iAngle < iAngleCount; ++iAngle) {
		float32* pfReRow = pfRe + iAngle * zpDetector;
		float32* pfDataRow = _pFilteredSinogram->getData() + iAngle * iDetectorCount;
		for (int iDetector = 0; iDetector < iDetectorCount; ++iDetector)
			pfDataRow[iDetector] = pfReRow[iDetector];
	}

	delete[] pfRe;
	delete[] pfIm;
	delete[] filter;
}