00001
00002
00028 #include <config.h>
00029 #include "panoinc_WX.h"
00030 #include "panoinc.h"
00031
00032 #include "base_wx/wxPlatform.h"
00033 #include "base_wx/platform.h"
00034 #include "base_wx/LensTools.h"
00035 #include "hugin/huginApp.h"
00036 #include "hugin/HFOVDialog.h"
00037 #include "hugin/MainFrame.h"
00038
00039 using namespace PT;
00040 using namespace std;
00041 using namespace hugin_utils;
00042
00043 BEGIN_EVENT_TABLE(HFOVDialog, wxDialog)
00044 EVT_CHOICE (XRCID("lensdlg_type_choice"),HFOVDialog::OnTypeChanged)
00045 EVT_TEXT ( XRCID("lensdlg_cropfactor_text"), HFOVDialog::OnCropFactorChanged )
00046 EVT_TEXT ( XRCID("lensdlg_hfov_text"), HFOVDialog::OnHFOVChanged )
00047 EVT_TEXT ( XRCID("lensdlg_focallength_text"), HFOVDialog::OnFocalLengthChanged )
00048 EVT_BUTTON( XRCID("lensdlg_load_lens_button"), HFOVDialog::OnLoadLensParameters )
00049 EVT_BUTTON ( wxID_OK, HFOVDialog::OnOk)
00050 END_EVENT_TABLE()
00051
00052 HFOVDialog::HFOVDialog(wxWindow * parent, SrcPanoImage & srcImg, double focalLength, double cropFactor)
00053 : m_srcImg(srcImg), m_focalLength(focalLength), m_cropFactor(cropFactor)
00054 {
00055 m_HFOV = srcImg.getHFOV();
00056 wxXmlResource::Get()->LoadDialog(this, parent, wxT("dlg_focallength"));
00057
00058 m_cropText = XRCCTRL(*this, "lensdlg_cropfactor_text", wxTextCtrl);
00059 DEBUG_ASSERT(m_cropText);
00060
00061 m_hfovText = XRCCTRL(*this, "lensdlg_hfov_text", wxTextCtrl);
00062 DEBUG_ASSERT(m_hfovText);
00063
00064 m_focalLengthText = XRCCTRL(*this, "lensdlg_focallength_text", wxTextCtrl);
00065 DEBUG_ASSERT(m_focalLengthText);
00066
00067 m_projChoice = XRCCTRL(*this, "lensdlg_type_choice", wxChoice);
00068 DEBUG_ASSERT(m_projChoice);
00069 FillLensProjectionList(m_projChoice);
00070
00071 m_okButton = XRCCTRL(*this, "wxID_OK", wxButton);
00072 DEBUG_ASSERT(m_okButton);
00073
00074
00075 wxString fn(srcImg.getFilename().c_str(), HUGIN_CONV_FILENAME);
00076 wxString message;
00077 message.Printf(_("No or only partial information about field of view was found in image file\n%s\n\nPlease enter the horizontal field of view (HFOV) or the focal length and crop factor."), fn.c_str());
00078 XRCCTRL(*this, "lensdlg_message", wxStaticText)->SetLabel(message);
00079 SelectProjection(m_projChoice,m_srcImg.getProjection());
00080
00081 if (m_cropFactor > 0 && m_focalLength > 0) {
00082
00083 m_HFOV = calcHFOV(m_srcImg.getProjection(), m_focalLength,
00084 m_cropFactor, m_srcImg.getSize());
00085
00086 m_HFOVStr = doubleTowxString(m_HFOV,2);
00087 m_hfovText->SetValue(m_HFOVStr);
00088 m_focalLengthStr = doubleTowxString(m_focalLength,2);
00089 m_focalLengthText->SetValue(m_focalLengthStr);
00090 m_cropFactorStr = doubleTowxString(m_cropFactor,2);
00091 m_cropText->SetValue(m_cropFactorStr);
00092 } else if (m_cropFactor > 0 && m_focalLength <= 0) {
00093
00094 m_cropFactorStr = doubleTowxString(m_cropFactor,2);
00095 m_cropText->SetValue(m_cropFactorStr);
00096 m_okButton->Disable();
00097 } else if (m_cropFactor <= 0 && m_focalLength > 0) {
00098
00099 m_focalLengthStr = doubleTowxString(m_focalLength,2);
00100 m_focalLengthText->SetValue(m_focalLengthStr);
00101 m_okButton->Disable();
00102 } else {
00103
00104
00105 m_cropFactor = 1;
00106 m_cropFactorStr = doubleTowxString(m_cropFactor,2);
00107 m_cropText->SetValue(m_cropFactorStr);
00108 m_okButton->Disable();
00109 }
00110
00111 this->GetSizer()->SetSizeHints(this);
00112 }
00113
00114 void HFOVDialog::OnTypeChanged(wxCommandEvent & e)
00115 {
00116 SrcPanoImage::Projection new_proj=(SrcPanoImage::Projection)(GetSelectedProjection(m_projChoice));
00117 DEBUG_DEBUG("new type: " << new_proj);
00118 m_srcImg.setProjection(new_proj);
00119 if (m_cropFactor > 0 && m_focalLength > 0) {
00120 m_HFOV = calcHFOV(m_srcImg.getProjection(), m_focalLength,
00121 m_cropFactor, m_srcImg.getSize());
00122 m_HFOVStr = doubleTowxString(m_HFOV,2);
00123 m_hfovText->SetValue(m_HFOVStr);
00124 }
00125 }
00126
00127 void HFOVDialog::OnHFOVChanged(wxCommandEvent & e)
00128 {
00129 wxString text = m_hfovText->GetValue();
00130 DEBUG_DEBUG("state: " << m_HFOVStr.mb_str(wxConvLocal) << ", change:" << text.mb_str(wxConvLocal));
00131 DEBUG_DEBUG("cmd str: " << e.GetString().mb_str(wxConvLocal));
00132 if (text.empty()) {
00133
00134 return;
00135 }
00136
00137 if (m_hfovText->GetValue() == m_HFOVStr) {
00138 DEBUG_DEBUG("ignoring programatic HFOV change");
00139 return;
00140 }
00141
00142
00143 m_HFOVStr = text;
00144
00145 if (text.empty()) {
00146 m_HFOV = 0;
00147 m_okButton->Disable();
00148 return;
00149 }
00150
00151 if (!str2double(text, m_HFOV)) {
00152 m_okButton->Disable();
00153 return;
00154 }
00155
00156 DEBUG_DEBUG(m_HFOV);
00157
00158 if (m_HFOV <= 0) {
00159 wxMessageBox(_("The horizontal field of view must be positive."));
00160 m_HFOV = 50;
00161 m_HFOVStr = doubleTowxString(m_HFOV,2);
00162 m_hfovText->SetValue(m_HFOVStr);
00163 return;
00164 }
00165
00166 if (m_srcImg.getProjection() == SrcPanoImage::RECTILINEAR && m_HFOV > 179) {
00167 DEBUG_DEBUG("HFOV " << m_HFOV << " too big, resetting to 179");
00168 m_HFOV=179;
00169 m_HFOVStr = doubleTowxString(m_HFOV,2);
00170 m_hfovText->SetValue(m_HFOVStr);
00171 }
00172
00173 if (m_cropFactor > 0) {
00174
00175 m_focalLength = calcFocalLength(m_srcImg.getProjection(), m_HFOV, m_cropFactor, m_srcImg.getSize());
00176 m_focalLengthStr = doubleTowxString(m_focalLength,2);
00177 m_focalLengthText->SetValue(m_focalLengthStr);
00178 }
00179 m_okButton->Enable();
00180 }
00181
00182 void HFOVDialog::OnFocalLengthChanged(wxCommandEvent & e)
00183 {
00184 wxString text = m_focalLengthText->GetValue();
00185 DEBUG_DEBUG(m_focalLengthStr.mb_str(wxConvLocal) << " => " << text.mb_str(wxConvLocal));
00186
00187 if (m_focalLengthText->GetValue() == m_focalLengthStr) {
00188 DEBUG_DEBUG("ignore focal length change");
00189 return;
00190 }
00191
00192 m_focalLengthStr = text;
00193
00194 if (text.empty()) {
00195 m_focalLength = 0;
00196 return;
00197 }
00198 if (!str2double(text, m_focalLength)) {
00199 return;
00200 }
00201 DEBUG_DEBUG(m_focalLength);
00202
00203
00204 if (m_focalLength == 0) {
00205 return;
00206 }
00207 if (m_focalLength <= 0) {
00208 m_focalLength=1;
00209 m_focalLengthStr = doubleTowxString(m_focalLength,2);
00210 m_focalLengthText->SetValue(m_focalLengthStr);
00211 wxMessageBox(_("The focal length must be positive."));
00212 }
00213
00214 if (m_cropFactor > 0) {
00215
00216 m_HFOV = calcHFOV(m_srcImg.getProjection(), m_focalLength,
00217 m_cropFactor, m_srcImg.getSize());
00218 m_HFOVStr = doubleTowxString(m_HFOV,2);
00219 m_hfovText->SetValue(m_HFOVStr);
00220 m_okButton->Enable();
00221 }
00222 }
00223
00224 void HFOVDialog::OnCropFactorChanged(wxCommandEvent & e)
00225 {
00226
00227 wxString text = m_cropText->GetValue();
00228 DEBUG_DEBUG(m_cropFactorStr.mb_str(wxConvLocal) << " => " << text.mb_str(wxConvLocal));
00229 if (text == m_cropFactorStr) {
00230 DEBUG_DEBUG("ignore crop change");
00231 return;
00232 }
00233
00234 m_cropFactorStr = text;
00235
00236 if (text.empty()) {
00237 m_cropFactor = 0;
00238 return;
00239 }
00240 if (!str2double(text, m_cropFactor)) {
00241 return;
00242 }
00243
00244
00245 if (m_cropFactor == 0) {
00246 m_cropFactorStr = text;
00247 return;
00248 }
00249
00250 if (m_cropFactor <= 0) {
00251 wxMessageBox(_("The crop factor must be positive."));
00252 m_cropFactor=1;
00253 m_cropFactorStr = doubleTowxString(m_cropFactor,2);
00254 m_cropText->SetValue(m_cropFactorStr);
00255 return;
00256 }
00257
00258 if (m_focalLength > 0) {
00259 m_HFOV = calcHFOV(m_srcImg.getProjection(), m_focalLength,
00260 m_cropFactor, m_srcImg.getSize());
00261 m_HFOVStr = doubleTowxString(m_HFOV,2);
00262 m_hfovText->SetValue(m_HFOVStr);
00263 m_okButton->Enable();
00264 }
00265 }
00266
00267 void HFOVDialog::OnLoadLensParameters(wxCommandEvent & e)
00268 {
00269 Lens lens;
00270 lens.setImageSize(m_srcImg.getSize());
00271
00272 bool cropped=false;
00273 bool autoCenterCrop=false;
00274 vigra::Rect2D cropRect;
00275
00276 if (LoadLensParametersChoose(this, lens, cropped, autoCenterCrop, cropRect)) {
00277 m_HFOV = lens.getHFOV();
00278 m_cropFactor = lens.getCropFactor();
00279
00280 m_srcImg.setExifCropFactor(lens.getCropFactor());
00281 m_srcImg.setExifFocalLength(lens.getFocalLength());
00282 m_srcImg.setHFOV(const_map_get(lens.variables,"v").getValue());
00283 m_srcImg.setProjection((SrcPanoImage::Projection) lens.getProjection());
00284
00285 m_focalLength = calcFocalLength(m_srcImg.getProjection(), m_HFOV, m_cropFactor, m_srcImg.getSize());
00286
00287
00288 std::vector<double> radialDist(4);
00289 radialDist[0] = const_map_get(lens.variables,"a").getValue();
00290 radialDist[1] = const_map_get(lens.variables,"b").getValue();
00291 radialDist[2] = const_map_get(lens.variables,"c").getValue();
00292 radialDist[3] = 1 - radialDist[0] - radialDist[1] - radialDist[2];
00293 m_srcImg.setRadialDistortion(radialDist);
00294 FDiff2D t;
00295 t.x = const_map_get(lens.variables,"d").getValue();
00296 t.y = const_map_get(lens.variables,"e").getValue();
00297 m_srcImg.setRadialDistortionCenterShift(t);
00298 t.x = const_map_get(lens.variables,"g").getValue();
00299 t.y = const_map_get(lens.variables,"t").getValue();
00300 m_srcImg.setShear(t);
00301
00302
00303 std::vector<double> vigCorrCoeff(4);
00304 vigCorrCoeff[0] = const_map_get(lens.variables,"Va").getValue();
00305 vigCorrCoeff[1] = const_map_get(lens.variables,"Vb").getValue();
00306 vigCorrCoeff[2] = const_map_get(lens.variables,"Vc").getValue();
00307 vigCorrCoeff[3] = const_map_get(lens.variables,"Vd").getValue();
00308 m_srcImg.setRadialVigCorrCoeff(vigCorrCoeff);
00309 t.x = const_map_get(lens.variables,"Vx").getValue();
00310 t.y = const_map_get(lens.variables,"Vy").getValue();
00311 m_srcImg.setRadialVigCorrCenterShift(t);
00312
00313
00314 m_srcImg.setWhiteBalanceRed(const_map_get(lens.variables,"Er").getValue());
00315 m_srcImg.setWhiteBalanceBlue(const_map_get(lens.variables,"Eb").getValue());
00316
00317 std::vector<float> resp(5);
00318 resp[0] = const_map_get(lens.variables,"Ra").getValue();
00319 resp[1] = const_map_get(lens.variables,"Rb").getValue();
00320 resp[2] = const_map_get(lens.variables,"Rc").getValue();
00321 resp[3] = const_map_get(lens.variables,"Rd").getValue();
00322 resp[4] = const_map_get(lens.variables,"Re").getValue();
00323 m_srcImg.setEMoRParams(resp);
00324
00325 if (!cropped)
00326 {
00327 m_srcImg.setCropMode(SrcPanoImage::NO_CROP);
00328 }
00329 else
00330 {
00331 if (m_srcImg.isCircularCrop())
00332 {
00333 m_srcImg.setCropMode(SrcPanoImage::CROP_CIRCLE);
00334 }
00335 else
00336 {
00337 m_srcImg.setCropMode(SrcPanoImage::CROP_RECTANGLE);
00338 };
00339 m_srcImg.setCropRect(cropRect);
00340 };
00341
00342
00343 m_focalLengthStr = doubleTowxString(m_focalLength,2);
00344 m_focalLengthText->SetValue(m_focalLengthStr);
00345 m_cropFactorStr = doubleTowxString(m_cropFactor,2);
00346 m_cropText->SetValue(m_cropFactorStr);
00347 m_HFOVStr = doubleTowxString(m_HFOV,2);
00348 m_hfovText->SetValue(m_HFOVStr);
00349 SelectProjection(m_projChoice, m_srcImg.getProjection());
00350
00351
00352 m_okButton->Enable();
00353 }
00354 }
00355
00356
00357 SrcPanoImage HFOVDialog::GetSrcImage()
00358 {
00359 m_srcImg.setExifFocalLength(m_focalLength);
00360 m_srcImg.setExifCropFactor(m_cropFactor);
00361 m_srcImg.setHFOV(m_HFOV);
00362 return m_srcImg;
00363 }
00364
00365 double HFOVDialog::GetCropFactor()
00366 {
00367 return m_cropFactor;
00368 }
00369
00370 double HFOVDialog::GetFocalLength()
00371 {
00372 return m_focalLength;
00373 }
00374
00375 void HFOVDialog::OnOk(wxCommandEvent & e)
00376 {
00377 if(m_srcImg.getProjection()==SrcPanoImage::FISHEYE_ORTHOGRAPHIC && m_HFOV>190)
00378 {
00379 if(wxMessageBox(
00380 wxString::Format(_("You have given a field of view of %.2f degrees.\n But the orthographic projection is limited to a field of view of 180 degress.\nDo you want still use that high value?"), m_HFOV),
00381 #ifdef __WXMSW__
00382 _("Hugin"),
00383 #else
00384 wxT(""),
00385 #endif
00386 wxICON_EXCLAMATION | wxYES_NO)==wxNO)
00387 {
00388 return;
00389 };
00390 };
00391 EndModal(wxID_OK);
00392 };