From 6b2163676582e4d32020dc765b74cff3a1705d3c Mon Sep 17 00:00:00 2001 From: "Kevin M. Rosenberg" Date: Sat, 15 Mar 2003 10:29:06 +0000 Subject: [PATCH] r4203: *** empty log message *** --- NEWS | 4 ++++ configure | 2 +- configure.ac | 2 +- debian/changelog | 6 ++++++ debian/upload.sh | 2 +- libctsim/projections.cpp | 26 +++++++++++++------------- src/dialogs.h | 4 ++-- src/views.cpp | 39 +++++++++++++++++++++++---------------- src/views.h | 5 ++++- 9 files changed, 55 insertions(+), 35 deletions(-) diff --git a/NEWS b/NEWS index 6f6c8d0..d65c241 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,7 @@ +Version 4.2 Released Mar 2003 + +* Direct Fourier Reconstructions now supported + Version 4.0 Released Jan 2003 * Port to wxWindows 2.4 diff --git a/configure b/configure index df9d60b..26a4a05 100755 --- a/configure +++ b/configure @@ -1492,7 +1492,7 @@ fi PACKAGE=ctsim -VERSION=4.0.2 +VERSION=4.2.0 if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5 diff --git a/configure.ac b/configure.ac index 1f4c7b3..87ba96a 100644 --- a/configure.ac +++ b/configure.ac @@ -5,7 +5,7 @@ dnl CDPATH= AC_INIT AC_CONFIG_SRCDIR([src/ctsim.cpp]) -AM_INIT_AUTOMAKE(ctsim,4.0.2) +AM_INIT_AUTOMAKE(ctsim,4.2.0) AM_CONFIG_HEADER(config.h) dnl Checks for programs. diff --git a/debian/changelog b/debian/changelog index 430b28f..dcb5eba 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +ctsim (4.2.0-1) unstable; urgency=low + + * New feature: Direct inverse Fourier reconstructions + + -- Kevin M. Rosenberg Fri, 14 Mar 2003 23:12:06 -0700 + ctsim (4.1.2-3) unstable; urgency=low * Add build-depends-indep to control file diff --git a/debian/upload.sh b/debian/upload.sh index 14e31d6..dac4288 100755 --- a/debian/upload.sh +++ b/debian/upload.sh @@ -1,4 +1,4 @@ #!/bin/bash -e -dup ctsim -Uftp.med-info.com -D/home/ftp/ctsim -C"(cd /opt/apache/htdocs/ctsim.org; make install)" -su $* +dup ctsim -Uftp.med-info.com -D/home/ftp/ctsim -C"(cd /opt/apache/htdocs/ctsim; make install)" -su $* diff --git a/libctsim/projections.cpp b/libctsim/projections.cpp index 612ab6b..db8fd0c 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.80 2002/06/27 03:19:23 kevin Exp $ +** $Id: projections.cpp,v 1.81 2003/03/15 10:27:30 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 @@ -25,7 +25,7 @@ ******************************************************************************/ #include "ct.h" -#include +#include const kuint16 Projections::m_signature = ('P'*256 + 'J'); @@ -1016,36 +1016,36 @@ Projections::convertFFTPolar (ImageFile& rIF, int iInterpolationID, int iZeropad if (m_geometry == Scanner::GEOMETRY_EQUIANGULAR || m_geometry == Scanner::GEOMETRY_EQUILINEAR) pProj = interpolateToParallel(); - int iInterpDet = nx; -// int iInterpDet = pProj->m_nDet; + int iInterpDet = static_cast(static_cast(sqrt(nx*nx+ny*ny))); int iNumInterpDetWithZeros = ProcessSignal::addZeropadFactor (iInterpDet, iZeropad); - + double dProjScale = iInterpDet / (pProj->viewDiameter() * 0.5); double dZeropadRatio = static_cast(iNumInterpDetWithZeros) / static_cast(iInterpDet); fftw_plan plan = fftw_create_plan (iNumInterpDetWithZeros, FFTW_FORWARD, FFTW_IN_PLACE | FFTW_ESTIMATE | FFTW_USE_WISDOM); fftw_complex* pcIn = new fftw_complex [iNumInterpDetWithZeros]; std::complex** ppcDetValue = new std::complex* [pProj->m_nView]; - double dInterpScale = (pProj->m_nDet-1) / static_cast(iInterpDet-1) / SQRT2; + //double dInterpScale = (pProj->m_nDet-1) / static_cast(iInterpDet-1); + double dInterpScale = pProj->m_nDet / static_cast(iInterpDet); double dFFTScale = 1. / static_cast(iInterpDet * iInterpDet); int iMidPoint = iInterpDet / 2; double dMidPoint = static_cast(iInterpDet) / 2.; int iZerosAdded = iNumInterpDetWithZeros - iInterpDet; - // For each view, interpolate to nx length, shift to center at origin, and FFt transform + // For each view, interpolate, shift to center at origin, and FFT for (int iView = 0; iView < m_nView; iView++) { DetectorValue* detval = pProj->getDetectorArray(iView).detValues(); LinearInterpolator projInterp (detval, pProj->m_nDet); for (int iDet = 0; iDet < iInterpDet; iDet++) { double dInterpPos = (m_nDet / 2.) + (iDet - dMidPoint) * dInterpScale; - pcIn[iDet].re = projInterp.interpolate (dInterpPos) * dInterpScale; + pcIn[iDet].re = projInterp.interpolate (dInterpPos) * dProjScale; pcIn[iDet].im = 0; } Fourier::shuffleFourierToNaturalOrder (pcIn, iInterpDet); if (iZerosAdded > 0) { - for (int iDet1 = iMidPoint; iDet1 < iInterpDet; iDet1++) + for (int iDet1 = iInterpDet -1; iDet1 >= iMidPoint; iDet1--) pcIn[iDet1+iZerosAdded] = pcIn[iDet1]; for (int iDet2 = iMidPoint; iDet2 < iMidPoint + iZerosAdded; iDet2++) pcIn[iDet2].re = pcIn[iDet2].im = 0; @@ -1107,10 +1107,10 @@ Projections::calcArrayPolarCoordinates (unsigned int nx, unsigned int ny, double double xInc = (xMax - xMin) / nx; // size of cells double yInc = (yMax - yMin) / ny; + double dDetCenter = (iNumDetWithZeros - 1) / 2.; // index refering to L=0 projection // +1 is correct for frequency data, ndet-1 is correct for projections - int iDetCenter = (iNumDetWithZeros - 1) / 2; // index refering to L=0 projection - if (isEven (iNumDetWithZeros)) - iDetCenter = (iNumDetWithZeros + 1) / 2; + // if (isEven (iNumDetWithZeros)) + // dDetCenter = (iNumDetWithZeros + 0) / 2; // Calculates polar coordinates (view#, det#) for each point on phantom grid double x = xMin + xInc / 2; // Rectang coords of center of pixel @@ -1128,7 +1128,7 @@ Projections::calcArrayPolarCoordinates (unsigned int nx, unsigned int ny, double } ppdView[ix][iy] = (phi - m_rotStart) / m_rotInc; - ppdDet[ix][iy] = (r / dDetInc) + iDetCenter; + ppdDet[ix][iy] = (r / dDetInc) + dDetCenter; } } } diff --git a/src/dialogs.h b/src/dialogs.h index 79264ff..7714562 100644 --- a/src/dialogs.h +++ b/src/dialogs.h @@ -9,7 +9,7 @@ ** This is part of the CTSim program ** Copyright (c) 1983-2001 Kevin Rosenberg ** -** $Id: dialogs.h,v 1.38 2001/09/24 11:46:17 kevin Exp $ +** $Id: dialogs.h,v 1.39 2003/03/15 10:27:30 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 @@ -393,7 +393,7 @@ class DialogGetConvertPolarParameters : public wxDialog public: DialogGetConvertPolarParameters (wxWindow* pParent, const char* const pszTitle, int iDefaultXSize = 0, int iDefaultYSize = 0, int iDefaultInterpolationID = Projections::POLAR_INTERP_BILINEAR, - int iDefaultZeropad = 1, int iHelpID = IDH_DLG_POLAR); + int iDefaultZeropad = 3, int iHelpID = IDH_DLG_POLAR); virtual ~DialogGetConvertPolarParameters (); unsigned int getXSize(); diff --git a/src/views.cpp b/src/views.cpp index e3922da..cb76637 100644 --- a/src/views.cpp +++ b/src/views.cpp @@ -9,7 +9,7 @@ ** This is part of the CTSim program ** Copyright (c) 1983-2001 Kevin Rosenberg ** -** $Id: views.cpp,v 1.170 2003/01/30 21:53:16 kevin Exp $ +** $Id: views.cpp,v 1.171 2003/03/15 10:27:30 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 @@ -2521,7 +2521,7 @@ ProjectionFileView::ProjectionFileView() m_iDefaultFilterMethod = ProcessSignal::FILTER_METHOD_CONVOLUTION; m_iDefaultFilterGeneration = ProcessSignal::FILTER_GENERATION_DIRECT; #endif - m_iDefaultZeropad = 1; + m_iDefaultZeropad = 2; m_iDefaultBackprojector = Backprojector::BPROJ_IDIFF; m_iDefaultInterpolation = Backprojector::INTERP_LINEAR; m_iDefaultInterpParam = 1; @@ -2530,7 +2530,7 @@ ProjectionFileView::ProjectionFileView() m_iDefaultPolarNX = 256; m_iDefaultPolarNY = 256; m_iDefaultPolarInterpolation = Projections::POLAR_INTERP_BILINEAR; - m_iDefaultPolarZeropad = 1; + m_iDefaultPolarZeropad = 2; } ProjectionFileView::~ProjectionFileView() @@ -3063,12 +3063,12 @@ ProjectionFileView::CreateChildFrame(wxDocument *doc, wxView *view) GetDocumentManager()->FileHistoryAddFilesToMenu(m_pFileMenu); GetDocumentManager()->FileHistoryUseMenu(m_pFileMenu); - wxMenu *convert_menu = new wxMenu; - convert_menu->Append (PJMENU_CONVERT_RECTANGULAR, "&Rectangular Image"); - convert_menu->Append (PJMENU_CONVERT_POLAR, "&Polar Image...\tCtrl-L"); - convert_menu->Append (PJMENU_CONVERT_FFT_POLAR, "FF&T->Polar Image...\tCtrl-T"); - convert_menu->AppendSeparator(); - convert_menu->Append (PJMENU_CONVERT_PARALLEL, "&Interpolate to Parallel"); + m_pConvertMenu = new wxMenu; + m_pConvertMenu->Append (PJMENU_CONVERT_RECTANGULAR, "&Rectangular Image"); + m_pConvertMenu->Append (PJMENU_CONVERT_POLAR, "&Polar Image...\tCtrl-L"); + m_pConvertMenu->Append (PJMENU_CONVERT_FFT_POLAR, "FF&T->Polar Image...\tCtrl-T"); + m_pConvertMenu->AppendSeparator(); + m_pConvertMenu->Append (PJMENU_CONVERT_PARALLEL, "&Interpolate to Parallel"); // wxMenu* filter_menu = new wxMenu; // filter_menu->Append (PJMENU_ARTIFACT_REDUCTION, "&Artifact Reduction"); @@ -3077,11 +3077,10 @@ ProjectionFileView::CreateChildFrame(wxDocument *doc, wxView *view) analyze_menu->Append (PJMENU_PLOT_HISTOGRAM, "&Plot Histogram"); analyze_menu->Append (PJMENU_PLOT_TTHETA_SAMPLING, "Plot T-T&heta Sampling...\tCtrl-H"); - wxMenu *reconstruct_menu = new wxMenu; - reconstruct_menu->Append (PJMENU_RECONSTRUCT_FBP, "&Filtered Backprojection...\tCtrl-R", "Reconstruct image using filtered backprojection"); - reconstruct_menu->Append (PJMENU_RECONSTRUCT_FBP_REBIN, "Filtered &Backprojection (Rebin to Parallel)...\tCtrl-B", "Reconstruct image using filtered backprojection"); - // still buggy - // reconstruct_menu->Append (PJMENU_RECONSTRUCT_FOURIER, "&Fourier...\tCtrl-E", "Reconstruct image using inverse Fourier"); + m_pReconstructMenu = new wxMenu; + m_pReconstructMenu->Append (PJMENU_RECONSTRUCT_FBP, "&Filtered Backprojection...\tCtrl-R", "Reconstruct image using filtered backprojection"); + m_pReconstructMenu->Append (PJMENU_RECONSTRUCT_FBP_REBIN, "Filtered &Backprojection (Rebin to Parallel)...\tCtrl-B", "Reconstruct image using filtered backprojection"); + m_pReconstructMenu->Append (PJMENU_RECONSTRUCT_FOURIER, "&Inverse Fourier...\tCtrl-E", "Direct inverse Fourier"); wxMenu *help_menu = new wxMenu; help_menu->Append(MAINMENU_HELP_CONTENTS, "&Contents\tF1"); @@ -3092,10 +3091,10 @@ ProjectionFileView::CreateChildFrame(wxDocument *doc, wxView *view) wxMenuBar *menu_bar = new wxMenuBar; menu_bar->Append (m_pFileMenu, "&File"); - menu_bar->Append (convert_menu, "&Convert"); + menu_bar->Append (m_pConvertMenu, "&Convert"); // menu_bar->Append (filter_menu, "Fi<er"); menu_bar->Append (analyze_menu, "&Analyze"); - menu_bar->Append (reconstruct_menu, "&Reconstruct"); + menu_bar->Append (m_pReconstructMenu, "&Reconstruct"); menu_bar->Append (help_menu, "&Help"); subframe->SetMenuBar(menu_bar); @@ -3158,6 +3157,14 @@ ProjectionFileView::OnUpdate (wxView *WXUNUSED(sender), wxObject *WXUNUSED(hint) const Projections& rProj = GetDocument()->getProjections(); const int nDet = rProj.nDet(); const int nView = rProj.nView(); + if (rProj.geometry() == Scanner::GEOMETRY_PARALLEL) { + m_pReconstructMenu->Enable (PJMENU_RECONSTRUCT_FBP_REBIN, false); + m_pConvertMenu->Enable (PJMENU_CONVERT_PARALLEL, false); + } else { + m_pReconstructMenu->Enable (PJMENU_RECONSTRUCT_FBP_REBIN, true); + m_pConvertMenu->Enable (PJMENU_CONVERT_PARALLEL, true); + } + if (nDet != 0 && nView != 0) { const DetectorArray& detarray = rProj.getDetectorArray(0); const DetectorValue* detval = detarray.detValues(); diff --git a/src/views.h b/src/views.h index 4239402..0dc47c9 100644 --- a/src/views.h +++ b/src/views.h @@ -9,7 +9,7 @@ ** This is part of the CTSim program ** Copyright (c) 1983-2001 Kevin Rosenberg ** -** $Id: views.h,v 1.60 2003/01/24 05:24:19 kevin Exp $ +** $Id: views.h,v 1.61 2003/03/15 10:27:30 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 @@ -204,6 +204,8 @@ private: ProjectionFileCanvas *m_pCanvas; wxMenu* m_pFileMenu; + wxMenu* m_pReconstructMenu; + wxMenu* m_pConvertMenu; int m_iDefaultNX; int m_iDefaultNY; @@ -262,6 +264,7 @@ public: void setInitialClientSize(); wxMenu* getFileMenu() { return m_pFileMenu; } + wxMenu* getReconstructMenu() { return m_pReconstructMenu; } ProjectionFileDocument* GetDocument() { return dynamic_cast(wxView::GetDocument()); } -- 2.34.1