/** * @brief Robertson02 algorithm for automatic self-calibration. * * * This file is a part of PFS CALIBRATION package. * ---------------------------------------------------------------------- * Copyright (C) 2004 Grzegorz Krawczyk * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ---------------------------------------------------------------------- * * @author Grzegorz Krawczyk, * * $Id: robertson02.cpp,v 1.4 2006/03/16 12:22:46 gkrawczyk Exp $ */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #define PROG_NAME "robertson02" // maximum iterations after algorithm accepts local minima #define MAXIT 500 // maximum accepted error #define MAX_DELTA 1e-5f float normalizeI( float* I, int M ); int robertson02_applyResponse( pfs::Array2D* xj, const ExposureList &imgs, const float* I, const float* w, int M ) { // number of exposures int N = imgs.size(); // frame size int width = xj->getCols(); int height = xj->getRows(); // number of saturated pixels int saturated_pixels = 0; // --- anti saturation: calculate trusted camera output range int minM = 0; for( int m=0 ; m0 ) { minM = m; break; } int maxM = M-1; for( int m=M-1 ; m>=0 ; m-- ) if( w[m]>0 ) { maxM = m; break; } // --- anti ghosting: for each image i, find images with // the immediately higher and lower exposure times int* i_lower = new int[N]; int* i_upper = new int[N]; for( int i=0 ; iti && imgs[j].titi_lower ) { ti_lower=imgs[j].ti; i_lower[i]=j; } } if( i_lower[i]==-1 ) i_lower[i]=i; if( i_upper[i]==-1 ) i_upper[i]=i; } // all pixels for( int j=0 ; jmaxM ) minti = fminf(minti,ti); if( mm || m_upper-1e6f ) { sum = I[minM]; div = maxti; } if( div==0.0f && minti<+1e6f ) { sum = I[maxM]; div = minti; } if( div!=0.0f ) (*xj)(j) = sum/div; else (*xj)(j) = 0.0f; } delete[] i_lower; delete[] i_upper; return saturated_pixels; } int robertson02_getResponse( pfs::Array2D* xj, const ExposureList &imgs, float* I, const float* w, int M ) { // number of exposures int N = imgs.size(); // frame size int width = imgs[0].yi->getCols(); int height = imgs[0].yi->getRows(); // number of saturated pixels int saturated_pixels = 0; // indexes int i,j,m; float* Ip = new float[M]; // previous response // 0. Initialization normalizeI( I, M ); for( m=0 ; m=0 ) { sum[m] += ti * (*xj)(j); cardEm[m]++; } else std::cerr << "robertson02: m out of range: " << m << std::endl; } } for( m=0 ; mMAXIT && pdelta0 && I[Mmax]==0 ; Mmax-- ); int Mmid = Mmin+(Mmax-Mmin)/2; float mid = I[Mmid]; // std::cerr << "robertson02: middle response, mid=" << mid // << " [" << Mmid << "]" // << " " << Mmin << ".." << Mmax << std::endl; if( mid==0.0f ) { // find first non-zero middle response while( Mmid