Filter Library Camera Interface Physics

ScanFilterNCCFFTOld.cpp

00001 /*
00002  * ScanFilterNCCFFTOld.cpp - fast normalized cross-correlation filter.
00003  *
00004  * This file is part of the Camera Filter Library.
00005  * Computer Aided Measurement Environment for Realtime Atomic imaging (Camera)
00006  *
00007  * Copyright (C) 2004, Leiden Probe Microscopy.
00008  * Copyright (C) 2004, Universiteit Leiden.
00009  *
00010  * Authors: Martin J. Moene
00011  *
00012  * $Id: ScanFilterNCCFFTOld.cpp 458 2007-01-04 15:20:34Z moene $
00013  */
00014 
00015 #include "stdafx.h"                     // for common (pre-compiled) headers
00016 //#include <cfl/stdafx.h>                 // for common (pre-compiled) headers
00017 #include <cfl/resource.h>               // for messages and other resources
00018 
00019 #include <Camera/InterfaceDll.h>        // Camera--Filter Library interface
00020 
00021 #include <cfl/ScanFilterNCCFFTOld.h>      // this filter's header FIXME
00022 #include <cfl/FilterDlg_NCCFFTOld.h>      // this filter's dialog
00023 #include <cfl/ToolCilImage.h>                   // for Image type and ToImage conversion shim
00024 
00025 #include <cil/Traits.h>                         // type traits
00026 #include <cil/CorrelationImageFilterOld.h> // CorrelationImageFilterOld image filter (FFT)
00027 #include <cil/ShiftScaleImageFilter.h>  // for class ShiftScaleImageFilter
00028 
00029 /*
00030  * configuration defines:
00031  */
00032 
00033 // none
00034 
00035 /*
00036  * end of configuration defines.
00037  */
00038 
00039 #ifdef _DEBUG
00040 #undef THIS_FILE
00041 static char THIS_FILE[]=__FILE__;
00042 #define new DEBUG_NEW
00043 #endif
00044 
00045 /*
00046  * convenience types.
00047  */
00048 
00049 /**
00050  * the correlation image type.
00051  */
00052 typedef cil::Image< double > CorrelationImageType;
00053 
00054 /**
00055  * the correlation filter type.
00056  */
00057 typedef cil::CorrelationImageFilterOld< Image, Image, CorrelationImageType > CorrelationImageFilterType;
00058 
00059 /**
00060  * the shift-scale filter type.
00061  */
00062 typedef cil::ShiftScaleImageFilter< CorrelationImageType, Image > ShiftScaleImageFilterType;
00063 
00064 #define CFL_SCHEMAVERSION_FILTERNCCFFT 0 ///< permanent storage schema version
00065                                         // this filter's name
00066 LPCTSTR CScanFilterNCCFFTOld::m_lpcsFilterName = _T("FNCC");
00067                                         // this filter's short name
00068 LPCTSTR CScanFilterNCCFFTOld::m_lpcsShortFilterName = CScanFilterNCCFFTOld::m_lpcsFilterName;
00069                                         // serialization
00070 IMPLEMENT_SERIAL(CScanFilterNCCFFTOld, CScanFilter, CFL_SCHEMAVERSION_FILTERNCCFFT)
00071 
00072 /*
00073  * the default scale factor.
00074  */
00075 const CScanFilterNCCFFTOld::ScaleType CScanFilterNCCFFTOld::m_defScale = 1000;
00076 
00077 /*
00078  * default constructor: setup filter to run without dialog;
00079  * see also CScanFilterNull::CScanFilterNull().
00080  */
00081 CScanFilterNCCFFTOld::CScanFilterNCCFFTOld()
00082    : m_lpsbIn2( NULL )
00083 {
00084 //    Q_LOG( _T("CScanFilterNCCFFTOld::CScanFilterNCCFFTOld()") );
00085 
00086    /*
00087     * we define our own normlization (sub-)type values to decouple this filter's
00088     * header from the Camera Imaging Library (CIL). Nonetheless, we want to use
00089     * the mode values as if they were from the CIL Threshld filter. Here we check
00090     * at compile-time if the values do match.
00091     */
00092    cil_static_assert( nmNone     == CorrelationImageFilterType::Normalization::None  , nmNone_values_must_match   );
00093    cil_static_assert( nmNormal   == CorrelationImageFilterType::Normalization::Normal, nmNormal_values_must_match   );
00094    cil_static_assert( nmPhase    == CorrelationImageFilterType::Normalization::Phase , nmPhase_values_must_match   );
00095 
00096    cil_static_assert( nsZeroMean == CorrelationImageFilterType::NormalizationSub::ZeroMean, nsZeroMean_values_must_match   );
00097    cil_static_assert( nsEnergy   == CorrelationImageFilterType::NormalizationSub::Energy  , nsEnergy_values_must_match   );
00098 
00099    m_csFilterName = m_lpcsFilterName;
00100 
00101    ReadFilterSettings();
00102 }
00103 
00104 /*
00105  * destructor.
00106  */
00107 CScanFilterNCCFFTOld::~CScanFilterNCCFFTOld()
00108 {
00109 //    Q_LOG( _T("CScanFilterNCCFFTOld::~CScanFilterNCCFFTOld()") );
00110 
00111    ; // do nothing
00112 }
00113 
00114 /*
00115  * store or retrieve the object's settings;
00116  * currently filter serialization is not used;
00117  * see also CScanFilterNull::Serialize().
00118  */
00119 void CScanFilterNCCFFTOld::Serialize(CArchive& ar)
00120 {
00121 //   Q_LOG( _T("CScanFilterNCCFFTOld::Serialize()") );
00122 
00123    CScanFilter::Serialize( ar );
00124 
00125    if ( ar.IsStoring() )
00126    {
00127 //        ar << m_mode << m_lower << m_upper << m_outside;
00128    }
00129    else
00130    {
00131 //       int mode;
00132 //
00133 //       ar >> mode >> m_lower >> m_upper >> m_outside;
00134 //
00135 //       m_mode = static_cast< NormalizationMode >( mode );
00136    }
00137 };
00138 
00139 /*
00140  * \brief configure filter with settings as provided by the application on the
00141  * filterlist window (e.g. via registry); see also CScanFilterNull::ReadFilterSettings().
00142  */
00143 void CScanFilterNCCFFTOld::ReadFilterSettings()
00144 {
00145 //    Q_LOG( _T("CScanFilterNCCFFTOld::ReadFilterSettings()") );
00146 
00147    CWinApp* pApp = AfxGetApp();
00148 
00149    if ( Q_INVALID( NULL == pApp ) )
00150       return ;
00151 
00152    /*
00153     * parameter string:
00154     */
00155    SetParameters( pApp->GetProfileString( gCflRegistrySubkey, m_lpcsFilterName, _T( "1,0,0,1e-6,1000,1000" ) ) );
00156 }
00157 
00158 /*
00159  * \brief save filter settings e.g. for use with the filterlist window (e.g. via registry);
00160  * see also ReadFilterSettings().
00161  */
00162 void CScanFilterNCCFFTOld::WriteFilterSettings() const
00163 {
00164 //    Q_LOG( _T("CScanFilterNCCFFTOld::WriteFilterSettings()") );
00165 
00166    CWinApp* pApp = AfxGetApp();
00167 
00168    if ( Q_INVALID( NULL == pApp ) )
00169       return ;
00170 
00171    /*
00172     * parameter string:
00173     */
00174    LPCTSTR pStr = GetParameters();
00175 
00176    if ( pStr )
00177    {
00178       pApp->WriteProfileString( gCflRegistrySubkey, m_lpcsFilterName, pStr );
00179       delete const_cast<LPTSTR>( pStr );
00180    }
00181 }
00182 
00183 /*
00184  * provide current filter parameter(s) for filter-scripting capture
00185  * in the main application;
00186  * see also CScanFilterNull::GetParameters().
00187  */
00188 LPCTSTR CScanFilterNCCFFTOld::GetParameters() const
00189 {
00190 //    Q_LOG( _T("CScanFilterNCCFFTOld::GetParameters()") );
00191 
00192    /*
00193     * format parameters and return a c-string on the heap:
00194     */
00195    CString csParameters;
00196 
00197    csParameters.Format
00198       ( _T( "%d,%d,%d,%g,%g,%g" )
00199       , GetNormalizationType()
00200       , GetNormalizationSubType()
00201       , DoRelaxFFTSize()
00202       , GetScale( nmNone )
00203       , GetScale( nmNormal )
00204       , GetScale( nmPhase )
00205    );
00206 
00207    return strcpy( new TCHAR[ csParameters.GetLength() + 1 ], csParameters );
00208 }
00209 
00210 /*
00211  * set parameters for filter-script execution of filter;
00212  * see also CScanFilterNull::SetParameters().
00213  */
00214 BOOL CScanFilterNCCFFTOld::SetParameters( LPCTSTR lpParameters )
00215 {
00216 //    Q_LOG( _T("CScanFilterNCCFFTOld::SetParameters()") );
00217 
00218    if ( Q_INVALID( NULL == lpParameters && "CScanFilterNCCFFTOld (SetParameters): parameters expected, none provided (NULL)." ) )
00219    {
00220       return FALSE;
00221    }
00222 
00223    /*
00224     * set defaults, read parameter string with factor and optional offset:
00225     */
00226    int norm      = nmNormal;
00227    int normsub   = nsEnergy;
00228    int relax     = false;
00229    double scale0 = 1e-6; // m_defScale;
00230    double scale1 = m_defScale;
00231    double scale2 = m_defScale;
00232 
00233    int nfields = _stscanf
00234       ( lpParameters
00235       , _T( "%d,%d,%d,%lg,%lg,%lg" )
00236       , &norm
00237       , &normsub
00238       , &relax
00239       , &scale0
00240       , &scale1
00241       , &scale2
00242    );
00243 
00244    m_norm    = static_cast< NormalizationType >   ( norm );
00245    m_normsub = static_cast< NormalizationSubType >( normsub );
00246    m_relax_fft_size = 0 != relax;
00247    m_scale[0] = scale0;
00248    m_scale[1] = scale1;
00249    m_scale[2] = scale2;
00250 
00251    if ( Q_INVALID( 5 > nfields && "CScanFilterNCCFFTOld (SetParameters): FIXME parameters expected, got less." ) )
00252    {
00253       return FALSE;
00254    }
00255 
00256    return TRUE;
00257 }
00258 
00259 /**
00260  * the number of input buffers.
00261  */
00262 DWORD CScanFilterNCCFFTOld::GetNrOfInBuffers() const
00263 {
00264    return 2;
00265 }
00266 
00267 /**
00268  * return the requested input buffer.
00269  */
00270 CScanBaseBuffer *CScanFilterNCCFFTOld::GetInputBuffer( UINT nNr )
00271 {
00272    Q_ASSERT( 0 <= nNr && nNr < GetNrOfInBuffers() && "ensure valid input buffer nr" );
00273 
00274    if ( 1 == nNr )
00275    {
00276       return m_lpsbIn2;
00277    }
00278 
00279    return m_lpsbIn;
00280 }
00281 
00282 /**
00283  * set the given input buffer.
00284  */
00285 void CScanFilterNCCFFTOld::SetInputBuffer( UINT nNr, CScanBaseBuffer *lpsbIn )
00286 {
00287    Q_ASSERT( 0 <= nNr && nNr < GetNrOfInBuffers() && "ensure valid input buffer nr" );
00288    Q_ASSERT( NULL != lpsbIn && "ensure valid input buffer" );
00289 
00290    if ( 0 == nNr )
00291    {
00292       m_lpsbIn = lpsbIn;
00293    }
00294    else if ( 1 == nNr )
00295    {
00296       m_lpsbIn2 = lpsbIn;
00297    }
00298 }
00299 
00300 /*
00301  * create filter dialog and pre Apply() filter to view result;
00302  * see also CScanFilterNull::RunModeless().
00303  */
00304 BOOL CScanFilterNCCFFTOld::RunModeless( CWnd* pParentWnd, CDocument* pDoc )
00305 {
00306 //    Q_LOG( _T("CScanFilterNCCFFTOld::RunModeless()") );
00307 
00308    CFilterDlg_NCCFFTOldPtr pDlg = new CFilterDlg_NCCFFTOld();
00309 
00310    if ( Q_INVALID( NULL == pDlg ) )
00311       return FALSE;
00312 
00313    pDlg->SetParameters( this, pDoc );   // (void) method
00314 
00315    /*
00316     * Create returns non-zero if dialog was created and initialized succesfully.
00317     * Note: no pDlg->DestroyWindow() must be done.
00318     */
00319    pDlg->Create( IDD_FILTERDLG_NCCFFT, pParentWnd );
00320 
00321    m_pDlg = pDlg;
00322 
00323    BOOL bRet = Apply();
00324 
00325    if ( bRet )
00326    {
00327       pDlg->UpdateView();
00328    }
00329 
00330    return bRet;
00331 }
00332 
00333 /*
00334  * check parameters, take care of a properly sized output buffer, set its name
00335  * and copy filter parameters, CalculatePlane() and SubtractPlane();
00336  * see also CScanFilterNull::ApplyCore().
00337  */
00338 BOOL CScanFilterNCCFFTOld::Apply()
00339 {
00340 //    Q_LOG( _T("CScanFilterNCCFFTOld::Apply()") );
00341 
00342    if ( Q_INVALID( NULL == m_lpsbIn && "ensure first input buffer") )
00343       return FALSE;
00344 
00345    if ( Q_INVALID( NULL == m_lpsbIn2 && "ensure second input buffer" ) )
00346       return FALSE;
00347 
00348    if ( Q_INVALID( NULL == m_lpsbOut && "ensure output buffer" ) )
00349       return FALSE;
00350 
00351    if ( Q_INVALID( !m_lpsbIn->IsCompleteFrame() && "ensure complete frame" ) )
00352       return FALSE;
00353 
00354    if ( Q_INVALID( !m_lpsbIn2->IsCompleteFrame() && "ensure complete frame" ) )
00355       return FALSE;
00356 
00357    /*
00358     * copy the filter settings (not the data):
00359     */
00360    Q_RETURN( m_lpsbOut->CreateOutputBufferFor( *m_lpsbIn ) );
00361 
00362    m_lpsbOut->m_csBufferName.Format
00363       ( _T("%s - %s")
00364       , m_lpsbIn->m_csBufferName
00365       , m_lpcsShortFilterName
00366    );
00367 
00368 //    m_lpsbOut->m_csBufferName.Format
00369 //       ( _T("%s - %s %d,%d,%d,%d")
00370 //       , m_lpsbIn->m_csBufferName
00371 //       , m_lpcsShortFilterName
00372 //       , GetNormalizationMode()
00373 //       , GetLowerNCCFFT()
00374 //       , GetUpperNCCFFT()
00375 //       , GetOutsideValue()
00376 //    );
00377 //
00378    if ( IsInteractive() )
00379    {
00380       m_pDlg->SetDlgItemText( IDC_BUFFEROUTNAME, m_lpsbOut->m_csBufferName );
00381    }
00382 
00383    /*
00384     * apply filter to L2R part:
00385     */
00386    CorrelationImageFilterType filter;
00387    ShiftScaleImageFilterType  scaler;
00388 
00389    filter.SetNormalizationType   ( static_cast<CorrelationImageFilterType::NormalizationType>(GetNormalizationType() )   );
00390    filter.SetNormalizationSubType( static_cast<CorrelationImageFilterType::NormalizationSubType>(GetNormalizationSubType() ) );
00391    filter.SetRelaxFFTSize        ( DoRelaxFFTSize() );
00392    scaler.SetScale               ( GetScale( GetNormalizationType() ) );
00393 
00394    CorrelationImageType correlation;
00395 
00396    //            subject image       , template image     , correlation
00397    filter.Apply( ToImage( m_lpsbIn2 ), ToImage( m_lpsbIn ), correlation );
00398    scaler.Apply( correlation         , ToImage( m_lpsbOut ) );
00399 
00400    /*
00401     * if we have a double buffer, L2R and R2L, process that part tooo.
00402     */
00403    if ( m_lpsbIn->IsBidirectionalScan() && m_lpsbOut->IsBidirectionalScan() )
00404    {
00405       //                     subject image    , template image           , correlation
00406       filter.Apply( ToImage( m_lpsbIn2, true ), ToImage( m_lpsbIn, true ), correlation );
00407       scaler.Apply( correlation               , ToImage( m_lpsbOut, true ) );
00408    }
00409 
00410    return TRUE;
00411 }
00412 
00413 /*
00414  * end of file
00415  */
00416 

Camera Filter Library documentation © 2004-2007 by Leiden Probe Microscopy