contrib/brl/bseg/brip/brip_gain_offset_solver.cxx
Go to the documentation of this file.
00001 #include "brip_gain_offset_solver.h"
00002 //:
00003 // \file
00004 #include <vil/vil_image_view.h>
00005 #include <vnl/vnl_matrix.h>
00006 #include <vnl/algo/vnl_svd.h>
00007 
00008 //: compute the number of valid corresponding pixels in the case of masks
00009 void brip_gain_offset_solver::compute_valid_pix()
00010 {
00011   unsigned m_msk_ni = model_mask_.ni(), m_msk_nj = model_mask_.nj();
00012   unsigned t_msk_ni = test_mask_.ni(), t_msk_nj = test_mask_.nj();
00013   m_mask_ = m_msk_ni*m_msk_nj>0;
00014   t_mask_ = t_msk_ni*t_msk_nj>0;
00015 
00016   if (m_mask_ && (m_msk_ni!=ni_||m_msk_nj!=nj_)) {
00017     n_valid_pix_ = 0;
00018     return;
00019   }
00020   if (t_mask_ && (t_msk_ni!=ni_||t_msk_nj!=nj_)) {
00021     n_valid_pix_ = 0;
00022     return;
00023   }
00024   // four cases
00025   // both masks empty
00026   if (!t_mask_ && !m_mask_) {
00027     n_valid_pix_ = ni_*nj_;
00028     return;
00029   }
00030   if (!t_mask_ && m_mask_) {
00031     n_valid_pix_ = 0;
00032     for (unsigned j = 0; j<m_msk_nj; ++j)
00033       for (unsigned i = 0; i<m_msk_ni; ++i)
00034         if (model_mask_(i,j))
00035           n_valid_pix_++;
00036     return;
00037   }
00038   if (t_mask_ && !m_mask_) {
00039     n_valid_pix_ = 0;
00040     for (unsigned j = 0; j<t_msk_nj; ++j)
00041       for (unsigned i = 0; i<t_msk_ni; ++i)
00042         if (test_mask_(i,j))
00043           n_valid_pix_++;
00044     return;
00045   }
00046   if (t_mask_ && m_mask_) {
00047     n_valid_pix_ = 0;
00048     for (unsigned j = 0; j<t_msk_nj; ++j)
00049       for (unsigned i = 0; i<t_msk_ni; ++i)
00050         if (test_mask_(i,j)&&model_mask_(i,j))
00051           n_valid_pix_++;
00052     return;
00053   }
00054 }
00055 
00056 brip_gain_offset_solver::
00057 brip_gain_offset_solver(vil_image_view<float> const& model_image,
00058                         vil_image_view<float> const& test_image)
00059 : ni_(model_image.ni()), nj_(model_image.nj()),
00060   model_image_(model_image), test_image_(test_image),
00061   gain_(1.0f), offset_(0.0f),
00062   t_mask_(false), m_mask_(false), n_valid_pix_(0)
00063 {}
00064 
00065 brip_gain_offset_solver::
00066 brip_gain_offset_solver(vil_image_view<float> const& model_image,
00067                         vil_image_view<float> const& test_image,
00068                         vil_image_view<unsigned char> const& model_mask,
00069                         vil_image_view<unsigned char> const& test_mask)
00070 : ni_(model_image.ni()), nj_(model_image.nj()),
00071   model_image_(model_image), test_image_(test_image),
00072   gain_(1.0f), offset_(0.0f),
00073   model_mask_(model_mask), test_mask_(test_mask),
00074   t_mask_(false), m_mask_(false), n_valid_pix_(0)
00075 {}
00076 
00077 //:
00078 // Im = model_image intensity, It = test_image intensity
00079 //
00080 // each pixel defines an equation
00081 //
00082 //  gain*It(i,j) + off  = Im(i,j)
00083 //
00084 //  Define the matrix A, and vector b
00085 // \verbatim
00086 //     [It(0,0)        1]     [Im(0,0)      ]
00087 //     [It(1,0)        1]     [Im(1,0)      ]
00088 // A = [     ...        ]  b =[  ...        ]
00089 //     [It(ni-1, nj-1) 1]     [Im(ni-1,nj-1)]
00090 // \endverbatim
00091 //  Use SVD to solve A [gain] = b
00092 //                     [off]
00093 //
00094 bool brip_gain_offset_solver::solve()
00095 {
00096   if (test_image_.ni() !=ni_ ||
00097       test_image_.nj() !=nj_ ||
00098       model_image_.ni()!=ni_ ||
00099       model_image_.nj()!=nj_)
00100     return false;
00101   this->compute_valid_pix();
00102   if (n_valid_pix_ == 0)
00103     return false;
00104   vnl_matrix<double> A(n_valid_pix_, 2);
00105   vnl_matrix<double> b(n_valid_pix_, 1);
00106   unsigned r = 0;
00107   for (unsigned j = 0; j<nj_; ++j)
00108     for (unsigned i = 0; i<ni_; ++i) {
00109       bool t_valid = !t_mask_ || test_mask_(i,j);
00110       bool m_valid = !m_mask_ || model_mask_(i,j);
00111       if (t_valid&&m_valid) {
00112       A[r][0]=test_image_(i,j);    A[r][1]=1.0;
00113       b[r][0]=model_image_(i,j);
00114       ++r;
00115       }
00116     }
00117   vnl_svd<double> svd(A);
00118   vnl_matrix<double> x = svd.solve(b);
00119   gain_ = static_cast<float>(x[0][0]);
00120   offset_ = static_cast<float>(x[1][0]);
00121   return true;
00122 }
00123 
00124 vil_image_view<float> brip_gain_offset_solver::mapped_test_image()
00125 {
00126   vil_image_view<float> temp(ni_, nj_);
00127   temp.fill(0.0f);
00128   for (unsigned j = 0; j<nj_; ++j)
00129     for (unsigned i = 0; i<ni_; ++i) {
00130       bool t_valid = !t_mask_ || test_mask_(i,j);
00131       bool m_valid = !m_mask_ || model_mask_(i,j);
00132       if (t_valid&&m_valid) {
00133         float v = test_image_(i,j);
00134         temp(i,j) = gain_*v + offset_;
00135       }
00136     }
00137   return temp;
00138 }