27 #include "hugin_config.h" 
   57 #include "vigra/cornerdetection.hxx" 
   58 #include "vigra/localminmax.hxx" 
   80     if (! wxPanel::Create(parent, 
id, pos, size, style, name) ) {
 
   95     wxXmlResource::Get()->LoadPanel(
this, 
"cp_editor_panel");
 
   96     wxPanel * panel = XRCCTRL(*
this, 
"cp_editor_panel", wxPanel);
 
   98     wxBoxSizer *topsizer = 
new wxBoxSizer( wxVERTICAL );
 
   99     topsizer->Add(panel, 1, wxEXPAND, 0);
 
  119     m_cpList = XRCCTRL(*
this, 
"cp_editor_cp_list", wxListCtrl);
 
  120     m_cpList->InsertColumn( 0, _(
"#"), wxLIST_FORMAT_RIGHT, 35);
 
  121     m_cpList->InsertColumn( 1, _(
"left x"), wxLIST_FORMAT_RIGHT, 65);
 
  122     m_cpList->InsertColumn( 2, _(
"left y"), wxLIST_FORMAT_RIGHT, 65);
 
  123     m_cpList->InsertColumn( 3, _(
"right x"), wxLIST_FORMAT_RIGHT, 65);
 
  124     m_cpList->InsertColumn( 4, _(
"right y"), wxLIST_FORMAT_RIGHT, 65);
 
  125     m_cpList->InsertColumn( 5, _(
"Alignment"), wxLIST_FORMAT_LEFT,110 );
 
  126     m_cpList->InsertColumn( 6, _(
"Distance"), wxLIST_FORMAT_RIGHT, 110);
 
  134     wxConfigBase* config = wxConfig::Get();
 
  135     for ( 
int j=0; j < 
m_cpList->GetColumnCount() ; j++ )
 
  138         int width = config->Read(wxString::Format( 
"/CPEditorPanel/ColumnWidth%d", j ), -1);
 
  142     m_sortCol = config->Read(
"/CPEditorPanel/SortColumn", -1);
 
  143     m_sortAscending = config->Read(
"/CPEditorPanel/SortAscending", 1) == 1 ? 
true : 
false;
 
  150     m_x1Text = XRCCTRL(*
this,
"cp_editor_x1", wxTextCtrl);
 
  153     m_y1Text = XRCCTRL(*
this,
"cp_editor_y1", wxTextCtrl);
 
  156     m_x2Text = XRCCTRL(*
this,
"cp_editor_x2", wxTextCtrl);
 
  159     m_y2Text = XRCCTRL(*
this,
"cp_editor_y2", wxTextCtrl);
 
  165     m_addButton = XRCCTRL(*
this, 
"cp_editor_add", wxButton);
 
  167     m_delButton = XRCCTRL(*
this, 
"cp_editor_delete", wxButton);
 
  170     m_autoAddCB = XRCCTRL(*
this,
"cp_editor_auto_add", wxCheckBox);
 
  172     m_fineTuneCB = XRCCTRL(*
this,
"cp_editor_fine_tune_check",wxCheckBox);
 
  175     m_estimateCB = XRCCTRL(*
this,
"cp_editor_auto_estimate", wxCheckBox);
 
  178     m_showLinesCB = XRCCTRL(*
this, 
"cp_editor_show_lines", wxCheckBox);
 
  189     m_actionButton = XRCCTRL(*
this, 
"cp_editor_action_button", wxButton);
 
  194     m_cp_ctrls = XRCCTRL(*
this, 
"cp_controls_panel", wxPanel);
 
  197     m_zoomChoice = XRCCTRL(*
this, 
"cp_editor_choice_zoom", wxChoice);
 
  200     m_autoAddCB->SetValue(config->Read(
"/CPEditorPanel/autoAdd",0l) != 0 );
 
  201     m_fineTuneCB->SetValue(config->Read(
"/CPEditorPanel/autoFineTune",1l) != 0 );
 
  202     m_estimateCB->SetValue(config->Read(
"/CPEditorPanel/autoEstimate",1l) != 0 );
 
  203     m_showLinesCB->SetValue(config->Read(
"/CPEditorPanel/showLines", 1l) != 0);
 
  224     wxCommandEvent dummy;
 
  228     SetSizer( topsizer );
 
  281     wxConfigBase* config = wxConfig::Get();
 
  282     config->Write(
"/CPEditorPanel/autoAdd", 
m_autoAddCB->IsChecked() ? 1 : 0);
 
  283     config->Write(
"/CPEditorPanel/autoFineTune", 
m_fineTuneCB->IsChecked() ? 1 : 0);
 
  284     config->Write(
"/CPEditorPanel/autoEstimate", 
m_estimateCB->IsChecked() ? 1 : 0);
 
  285     config->Write(
"/CPEditorPanel/showLines", 
m_showLinesCB->IsChecked() ? 1 : 0);
 
  286     config->Write(
"/CPEditorPanel/SortColumn", 
m_sortCol);
 
  287     config->Write(
"/CPEditorPanel/SortAscending", 
m_sortAscending ? 1 : 0);
 
  297     if (imgNr == UINT_MAX) {
 
  321     ImageCache::getInstance().softFlush();
 
  329     if (imgNr == UINT_MAX) {
 
  358     ImageCache::getInstance().softFlush();
 
  370     if(m_leftImageNr<m_pano->getNrOfImages())
 
  382         img.setTranslationPlaneYaw(0);
 
  383         img.setTranslationPlanePitch(0);
 
  391     if(m_rightImageNr<m_pano->getNrOfImages())
 
  403         img.setTranslationPlaneYaw(0);
 
  404         img.setTranslationPlanePitch(0);
 
  433 #define SORTASCENDING(functionName, var) \ 
  434 int wxCALLBACK functionName(wxIntPtr item1, wxIntPtr item2, wxIntPtr sortData)\ 
  436     HuginBase::CPointVector* data = (HuginBase::CPointVector*)(sortData);\ 
  437     if (data->at(item1).second.var > data->at(item2).second.var)\ 
  439     if (data->at(item1).second.var < data->at(item2).second.var)\ 
  444 #define SORTDESCENDING(functionName, var) \ 
  445 int wxCALLBACK functionName(wxIntPtr item1, wxIntPtr item2, wxIntPtr sortData)\ 
  447     HuginBase::CPointVector* data = (HuginBase::CPointVector*)(sortData); \ 
  448     if (data->at(item1).second.var < data->at(item2).second.var)\ 
  450     if (data->at(item1).second.var > data->at(item2).second.var)\ 
  469 #undef SORTDESCENDING 
  560     } 
else  if (ev.GetEventObject() == 
m_rightImg){
 
  591             const long selectedPoint = 
m_cpList->FindItem(-1, nr);
 
  594             m_cpList->SetItemState(selectedPoint, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
 
  604             bool  hor = std::abs(cp.
x1 - cp.
x2) > (std::abs(cp.
y1 - cp.
y2) * vertBias);
 
  637                 DEBUG_ERROR(
"invalid point number while moving point")
 
  643                         << 
"  " << cp.
x2 << 
"," << cp.
y2);
 
  712             if(!cpToRemove.empty())
 
  744             bool  hor = std::abs(p1.
x - p2.
x) > (std::abs(p1.
y - p2.
y) * vertBias);
 
  808     if (selectedPoint != wxNOT_FOUND)
 
  810         m_cpList->SetItemState(selectedPoint, 0, wxLIST_STATE_SELECTED);
 
  822     DEBUG_TRACE(
"selectLocalPoint(" << LVpointNr << 
")");
 
  833     m_x1Text->SetValue(wxString::Format(
"%.2f",p.
x1));
 
  834     m_y1Text->SetValue(wxString::Format(
"%.2f",p.
y1));
 
  835     m_x2Text->SetValue(wxString::Format(
"%.2f",p.
x2));
 
  836     m_y2Text->SetValue(wxString::Format(
"%.2f",p.
y2));
 
  840     const long selectedPoint = 
m_cpList->FindItem(-1, LVpointNr);
 
  841     if (scrollLeft && scrollRight)
 
  845         m_cpList->SetItemState(selectedPoint, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
 
  847     m_cpList->EnsureVisible(selectedPoint);
 
  854     unsigned int localNr;
 
  856         DEBUG_DEBUG(
"CPEditor::setGlobalPoint(" << globalNr << 
") found local point " << localNr);
 
  859         DEBUG_ERROR(
"CPEditor::setGlobalPoint: point " << globalNr << 
" not found in currentPoints");
 
  865     HuginBase::CPointVector::const_iterator it = 
currentPoints.begin();
 
  867     while(it != 
currentPoints.end() && (*it).first != globalNr) {
 
  889                                              unsigned int thisImgNr,
 
  893                                              unsigned int otherImgNr,
 
  901     if (op.
x < (
int) pImg.getSize().width() && op.
x >= 0
 
  902         && op.
y < (int) pImg.getSize().height() && op.
y >= 0)
 
  908             MainFrame::Get()->SetStatusText(_(
"searching similar points..."),0);
 
  926             } 
catch (std::exception & e) {
 
  927                 hugin_utils::HuginMessageBox(wxString::Format(_(
"Error during Fine-tune (%s)"), wxString(e.what(), wxConvLocal)), _(
"Hugin"), wxOK, 
this);
 
  931                 if (corrPoint.corrPos.x >= 0 && corrPoint.corrPos.y >= 0 && corrPoint.maxpos.x > 0 && corrPoint.maxpos.y > 0)
 
  946                     s1.Printf(_(
"Point fine-tuned, angle: %.0f deg, correlation coefficient: %0.3f, curvature: %0.3f %0.3f"),
 
  947                               corrPoint.maxAngle, corrPoint.maxi, corrPoint.curv.x, corrPoint.curv.y );
 
  949                     wxString s2 = s1 + 
" -- " + wxString(_(
"change points, or press right mouse button to add the pair"));
 
  970         MainFrame::Get()->SetStatusText(_(
"Estimated point outside image"),0);
 
 1012             bool hasNormalCP = 
false;
 
 1017             if (estimate && (thisImgNr != otherImgNr) && hasNormalCP) {
 
 1019                                          thisImg, thisImgNr, THIS_POINT, THIS_POINT_RETRY,
 
 1020                                          otherImg, otherImgNr, OTHER_POINT, OTHER_POINT_RETRY);
 
 1029         bool hasNormalCP = 
false;
 
 1034         if (estimate && (thisImgNr != otherImgNr) && hasNormalCP) {
 
 1036                                      thisImg, thisImgNr, THIS_POINT, THIS_POINT_RETRY,
 
 1037                                      otherImg, otherImgNr, OTHER_POINT, OTHER_POINT_RETRY);
 
 1052                 double sAreaPercent = wxConfigBase::Get()->Read(
"/Finetune/SearchAreaPercent",
 
 1055                 bool corrOk = 
false;
 
 1057                 vigra::Diff2D newPoint_round = newPoint.
toDiff2D();
 
 1066                 } 
catch (std::exception & e) {
 
 1067                     hugin_utils::HuginMessageBox(wxString::Format(_(
"Error during Fine-tune (%s)"), wxString(e.what(), wxConvLocal)), _(
"Hugin"), wxOK, 
this);
 
 1091                     s1.Printf(_(
"Point fine-tuned, angle: %.0f deg, correlation coefficient: %0.3f, curvature: %0.3f %0.3f"),
 
 1094                     corrMsg = s1 + 
" -- " +  wxString(_(
"change points, or press right mouse button to add the pair"));
 
 1127             if (corrMsg != wxEmptyString) {
 
 1147     imgMod.
setSize(img.getSize());
 
 1148     imgMod.setProjection(img.getProjection());
 
 1149     imgMod.setHFOV(img.getHFOV());
 
 1186             neededHFOV = 2.0 * (x1 - x2);
 
 1191             neededHFOV = 2.0 * (360 - x2 + x1);
 
 1194         if (neededHFOV > 90)
 
 1206             neededHFOV = 2.0 * (x2 - x1);
 
 1211             neededHFOV = 2.0 * (360 + x2 - x1);
 
 1214         if (neededHFOV > 90)
 
 1226     vigra::Diff2D templPos, 
int templSize,
 
 1228     vigra::Diff2D searchPos, 
int sWidth)
 
 1232     wxConfigBase *cfg = wxConfigBase::Get();
 
 1242     if (templ.getProjection() == search.getProjection()
 
 1243         && templ.getHFOV() < 65 && search.getHFOV() < 65
 
 1244         && fabs(templ.getHFOV() - search.getHFOV()) < 5)
 
 1247         if (rotatingFinetune)
 
 1250                 searchImg, searchPos, sWidth, startAngle, stopAngle, nSteps);
 
 1254             res = 
vigra_ext::PointFineTune(templImg, vigra::RGBToGrayAccessor<vigra::RGBValue<vigra::UInt8> >(), templPos, templSize,
 
 1255                 searchImg, vigra::RGBToGrayAccessor<vigra::RGBValue<vigra::UInt8> >(), searchPos, sWidth);
 
 1263     double templHFOV = 0;
 
 1264     double searchHFOV = 0;
 
 1270     if (templHFOV < 0 || searchHFOV < 0)
 
 1287     double templX, templY, searchX, searchY;
 
 1295     vigra::UInt8RGBImage searchImgMod(opts.
getSize());
 
 1296     vigra::BImage alpha(opts.
getSize());
 
 1302     vigra::Rect2D rect(templPointInt.x - templSize - 2, templPointInt.y - templSize - 2,
 
 1303         templPointInt.x + templSize + 2, templPointInt.y + templSize + 2);
 
 1304     rect &= vigra::Rect2D(opts.
getSize());
 
 1306     vigra::UInt8RGBImage templImgMod(opts.
getSize());
 
 1309 #if defined DEBUG_EXPORT_FINE_TUNE_REMAPPING 
 1311         vigra::ImageExportInfo templExport(
"template_remapped.tif");
 
 1312         vigra::exportImage(
srcImageRange(templImgMod), templExport.setPixelType(
"UINT8"));
 
 1313         vigra::ImageExportInfo searchExport(
"search_remapped.tif");
 
 1314         vigra::exportImage(
srcImageRange(searchImgMod), searchExport.setPixelType(
"UINT8"));
 
 1332                                   const vigra::Diff2D & tmplPoint,
 
 1334                                   unsigned int subjImgNr,
 
 1339     DEBUG_TRACE(
"tmpl img nr: " << tmplImgNr << 
" corr src: " 
 1341     if (tmplImgNr == subjImgNr)
 
 1346         const double distance = (tmplPoint - o_subjPoint.
toDiff2D()).magnitude();
 
 1347         if (distance < sWidth)
 
 1349             sWidth = 0.9 * distance;
 
 1351         if (sWidth < 1.1 * templSize)
 
 1353             MainFrame::Get()->SetStatusText(_(
"Distance between line control points too short, skipping fine-tune."));
 
 1358     MainFrame::Get()->SetStatusText(_(
"searching similar points..."),0);
 
 1361     wxConfigBase::Get()->Read(
"/Finetune/CorrThreshold",&corrThresh,
 
 1366     if (tmplImgNr != subjImgNr)
 
 1384     MainFrame::Get()->SetStatusText(wxString::Format(_(
"Point fine-tuned, angle: %.0f deg, correlation coefficient: %0.3f, curvature: %0.3f %0.3f"),
 
 1390         dlg->SetExtendedMessage(_(
"An internal transformation went wrong.\nCheck that the point is inside the image."));
 
 1394     if (res.
maxi < corrThresh || res.
curv.
x < curvThresh || res.
curv.
y < curvThresh )
 
 1398         dlg->SetExtendedMessage(wxString::Format(_(
"Check the similarity visually.\nCorrelation coefficient (%.3f) is lower than the threshold set in the preferences."),
 
 1411     DEBUG_DEBUG(
"mode choice: " << nGui << 
" entries, required: " << nPano);
 
 1417         for (
int i = nGui-1; i > nPano-1; --i) {
 
 1424     } 
else if (nGui < nPano) {
 
 1427             m_cpModeChoice->SetString(nGui-1, wxString::Format(_(
"Line %d"), nGui-1));
 
 1429         for (
int i = nGui; i < nPano-1; i++) {
 
 1448             item.SetText(_(
"Correlation"));
 
 1452             item.SetText(_(
"Distance"));
 
 1468     DEBUG_TRACE(
"nrImages:" << nrImages << 
" nrTabs:" << nrTabs);
 
 1509         ImageCache::getInstance().softFlush();
 
 1513         for (
unsigned int i=0; i < ((nrTabs < nrImages)? nrTabs: nrImages); i++) {
 
 1515             m_leftChoice->SetString(i, wxString::Format(
"%d", i) + 
". - " + fileName.GetFullName());
 
 1516             m_rightChoice->SetString(i, wxString::Format(
"%d", i) + 
". - " + fileName.GetFullName());
 
 1524         if (nrTabs < nrImages)
 
 1526             for (
unsigned int i=nrTabs; i < nrImages; i++)
 
 1529                 m_leftChoice->Append(wxString::Format(
"%d", i) + 
". - " + fileName.GetFullName());
 
 1530                 m_rightChoice->Append(wxString::Format(
"%d", i) + 
". - " + fileName.GetFullName());
 
 1536     if (nrTabs > nrImages)
 
 1544         for (
int i=nrTabs-1; i >= (int)nrImages; i--) {
 
 1573     for(HuginBase::UIntSet::const_iterator it = changed.begin(); it != changed.end(); ++it) {
 
 1574         unsigned int imgNr = *it;
 
 1628     if (update || nrImages == 0) {
 
 1672     HuginBase::CPVector::size_type i = 0;
 
 1675     for (HuginBase::CPVector::size_type index = 0; index < controlPoints.size(); ++index)
 
 1696     unsigned int selectedItem = UINT_MAX;
 
 1697     long selectedCP = -1;
 
 1698     for (
int i = 0; i < 
m_cpList->GetItemCount(); i++)
 
 1700       if ( 
m_cpList->GetItemState( i, wxLIST_STATE_SELECTED))
 
 1702           selectedItem = (
unsigned int) i;            
 
 1703           selectedCP = 
m_cpList->GetItemData(i);
 
 1713         long item = 
m_cpList->InsertItem(i, wxString::Format(
"%d", i), -1);
 
 1716         m_cpList->SetItem(i,1,wxString::Format(
"%.2f",p.
x1));
 
 1717         m_cpList->SetItem(i,2,wxString::Format(
"%.2f",p.
y1));
 
 1718         m_cpList->SetItem(i,3,wxString::Format(
"%.2f",p.
x2));
 
 1719         m_cpList->SetItem(i,4,wxString::Format(
"%.2f",p.
y2));
 
 1726             mode = _(
"vert. Line");
 
 1729             mode = _(
"horiz. Line");
 
 1732             mode = wxString::Format(_(
"Line %d"), p.
mode);
 
 1740     if (selectedItem <= (
unsigned int)
m_cpList->GetItemCount() && !newPair && 
m_cpList->GetItemCount() > 0)
 
 1747             long selected = 
m_cpList->FindItem(-1, selectedCP);
 
 1748             m_cpList->SetItemState(selected, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
 
 1755             if (selectedItem == (
unsigned int)
m_cpList->GetItemCount())
 
 1758                 selectedItem = 
m_cpList->GetItemCount() - 1;
 
 1760             m_cpList->SetItemState(selectedItem, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
 
 1761             m_cpList->EnsureVisible(selectedItem);
 
 1767         m_x1Text->SetValue(wxString::Format(
"%.2f",p.
x1));
 
 1768         m_y1Text->SetValue(wxString::Format(
"%.2f",p.
y1));
 
 1769         m_x2Text->SetValue(wxString::Format(
"%.2f",p.
x2));
 
 1770         m_y2Text->SetValue(wxString::Format(
"%.2f",p.
y2));
 
 1780     for ( 
int j=0; j < 
m_cpList->GetColumnCount() ; j++ )
 
 1784         int width = wxConfigBase::Get()->Read(wxString::Format( 
"/CPEditorPanel/ColumnWidth%d", j ), -1);
 
 1786             m_cpList->SetColumnWidth(j, width);
 
 1810                                  wxLIST_STATE_SELECTED);
 
 1815     const unsigned int nr = 
m_cpList->GetItemData(item);
 
 1820     double oldValue=cp.x1;
 
 1870     DEBUG_TRACE(
"OnLeftChoiceChange() to " << e.GetSelection());
 
 1878     DEBUG_TRACE(
"OnRightChoiceChange() to " << e.GetSelection());
 
 1885     int t = ev.GetIndex();
 
 1923     const wxSize leftSize = 
m_leftImg->GetClientSize();
 
 1924     const wxSize rightSize = 
m_rightImg->GetClientSize();
 
 1934     switch (e.GetSelection()) {
 
 1975             m_leftImg->Scroll(leftX*factor - leftSize.GetWidth() / 2, leftY*factor - leftSize.GetHeight() / 2);
 
 1976             m_rightImg->Scroll(rightX*factor - rightSize.GetWidth() / 2, rightY*factor - rightSize.GetHeight() / 2);
 
 1984                 << 
" origin: id:" << e.GetId() << 
" obj: " 
 1985                 << e.GetEventObject());
 
 1987     if (e.m_keyCode == WXK_DELETE){
 
 1998                                          wxLIST_STATE_SELECTED);
 
 2010     } 
else if (e.m_keyCode == 
'0') {
 
 2011         wxCommandEvent dummy;
 
 2015     } 
else if (e.m_keyCode == 
'1') {
 
 2016         wxCommandEvent dummy;
 
 2020     } 
else if (e.m_keyCode == 
'2') {
 
 2021         wxCommandEvent dummy;
 
 2025     } 
else if (e.CmdDown() && e.GetKeyCode() == WXK_LEFT) {
 
 2027         wxCommandEvent dummy;
 
 2029     } 
else if (e.CmdDown() && e.GetKeyCode() == WXK_RIGHT) {
 
 2031         wxCommandEvent dummy;
 
 2033     } 
else if (e.GetKeyCode() == 
'f') {
 
 2034         bool left =  e.GetEventObject() == 
m_leftImg;
 
 2040     } 
else if (e.GetKeyCode() == 
'g') {
 
 2042         long th = wxGetNumberFromUser(_(
"Create control points.\nTo create less points,\nenter a higher number."), _(
"Corner Detection threshold"), _(
"Create control points"), 400, 0, 32000);
 
 2046         long scale = wxGetNumberFromUser(_(
"Create control points"), _(
"Corner Detection scale"), _(
"Create control points"), 2);
 
 2053             DEBUG_DEBUG(
"corner threshold: " << th << 
"  scale: " << scale);
 
 2057         } 
catch (std::exception & e) {
 
 2058             wxLogError(_(
"Error during control point creation:\n") + wxString(e.what(), wxConvLocal));
 
 2084                                      wxLIST_STATE_SELECTED);
 
 2134             wxCommandEvent tmpEvt;
 
 2155         MainFrame::Get()->SetStatusText(_(
"Select point in right image"),0);
 
 2167         MainFrame::Get()->SetStatusText(_(
"Select point in left image"),0);
 
 2199     } 
else if (left >= nImgs) {
 
 2205     } 
else if (right >= nImgs) {
 
 2220     } 
else if (left >= nImgs) {
 
 2226     } 
else if (right >= nImgs) {
 
 2273         linefindSetting.
SetProg(
"linefind.exe");
 
 2275         linefindSetting.
SetProg(
"linefind");
 
 2277         linefindSetting.
SetArgs(
"-o %o %s");
 
 2295         hugin_utils::HuginMessageBox(_(
"Cannot run celeste without at least one control point connecting the two images"), _(
"Hugin"), wxOK | wxICON_INFORMATION, 
this);
 
 2296         std::cout << 
"Cannot run celeste without at least one control point connecting the two images" << std::endl;
 
 2310         wxConfigBase *cfg = wxConfigBase::Get();
 
 2317         int radius=(t)?10:20;
 
 2326         vigra::UInt16RGBImage in;
 
 2327         if(img->image16->width()>0)
 
 2329             in.resize(img->image16->size());
 
 2335             in.resize(im8->size());
 
 2339         if (!img->iccProfile->empty())
 
 2354         if(!cloudCP.empty())
 
 2362         hugin_utils::HuginMessageBox(wxString::Format(_(
"Removed %lu control points"), static_cast<unsigned long int>(cloudCP.size())), _(
"Hugin"), wxOK | wxICON_INFORMATION, 
this);
 
 2381         double x = it->second.error;
 
 2382         double delta = x - mean;
 
 2384         var += delta*(x - mean);
 
 2386     var = var / (n - 1);
 
 2387     const double limit = (sqrt(var) > mean) ? mean : (mean + sqrt(var));
 
 2391         if (it->second.error > limit)
 
 2393             removedCPs.insert(it->first);
 
 2396     if (!removedCPs.empty())
 
 2398         hugin_utils::HuginMessageBox(wxString::Format(_(
"Removed %lu control points"), (
unsigned long int)removedCPs.size()), _(
"Hugin"), wxOK | wxICON_INFORMATION, 
this);
 
 2410     wxString s(_(
"Create cp"));
 
 2411     s.Append(wxUniChar(0x25bc));
 
 2413     m_actionButton->SetToolTip(_(
"Create control points for image pair with currently selected control point detector on photos tab."));
 
 2421     wxString s(_(
"Celeste"));
 
 2422     s.Append(wxUniChar(0x25bc));
 
 2424     m_actionButton->SetToolTip(_(
"Tries to remove control points from clouds"));
 
 2432     wxString s(_(
"Clean cp"));
 
 2433     s.Append(wxUniChar(0x25bc));
 
 2435     m_actionButton->SetToolTip(_(
"Remove outlying control points by statistical method"));
 
 2441                                           const vigra::Diff2D & srcPnt,
 
 2443                                           unsigned int moveNr,
 
 2449     if (!
PointFineTune(srcNr, srcPnt, templWidth, moveNr, movePnt, sWidth, result))
 
 2469     unsigned int srcNr = cp.image1Nr;
 
 2470     unsigned int moveNr = cp.image2Nr;
 
 2474         srcNr = cp.image2Nr;
 
 2475         moveNr = cp.image1Nr;
 
 2483     if (result.
x < 0 || result.
y < 0)
 
 2492        cp.x2 = movedSrcPnt.
x;
 
 2493        cp.y2 = movedSrcPnt.
y;
 
 2497        cp.x1 = movedSrcPnt.
x;
 
 2498        cp.y1 = movedSrcPnt.
y;
 
 2524     vigra::Diff2D srcPnt(leftP.
toDiff2D());
 
 2526     vigra::Diff2D movePnt(rightP.
toDiff2D());
 
 2537     if (result.
x < 0 || result.
y < 0)
 
 2558     size_t nrNormalCp = 0;
 
 2568         DEBUG_WARN(
"Cannot estimate position without at least one point");
 
 2575     leftImg.setPitch(0);
 
 2582     rightImg.setPitch(0);
 
 2583     rightImg.setRoll(0);
 
 2593     std::set<std::string> opt;
 
 2594     optVec.push_back(opt);
 
 2601     optVec.push_back(opt);
 
 2631             if (t.
x < 0) t.
x = 0;
 
 2632             if (t.
y < 0) t.
y = 0;
 
 2645     int colNum = e.GetColumn();
 
 2646     wxConfigBase::Get()->Write( wxString::Format(
"/CPEditorPanel/ColumnWidth%d",colNum), 
m_cpList->GetColumnWidth(colNum) );
 
 2651     const int newCol = e.GetColumn();
 
 2677     while (roll > 360) roll-= 360;
 
 2678     while (roll < 0) roll += 360;
 
 2680     while (pitch > 180) pitch -= 360;
 
 2681     while (pitch < -180) pitch += 360;
 
 2682     bool headOver = (pitch > 90 || pitch < -90);
 
 2684     if (wxConfig::Get()->Read(
"/CPEditorPanel/AutoRot",1L)) {
 
 2685         if (roll >= 315 || roll < 45) {
 
 2687         } 
else if (roll >= 45 && roll < 135) {
 
 2689         } 
else if (roll >= 135 && roll < 225) {
 
 2701                 : wxXmlResourceHandler()
 
 2710     cp->Create(m_parentAsWindow,
 
 2712                    GetPosition(), GetSize(),
 
 2723     return IsOfClass(node, 
"CPEditorPanel");
 
void CalcCPDistance(HuginBase::Panorama *pano)
Get maximum CP distance for all images pairs containing the reference image. 
wxButton * m_finetuneButton
PanoramaOptions::ProjectionFormat getProjection() const 
void ScrollDelta(const wxPoint &delta)
scroll the window by delta pixels 
void OnColumnHeaderClick(wxListEvent &e)
Dummy progress display, without output. 
void SelectGlobalPoint(unsigned int globalNr)
Select a point. 
void NewPointChange(hugin_utils::FDiff2D p, bool left)
static double calcOptimalPanoScale(const SrcPanoImage &src, const PanoramaOptions &dest)
function to calculate the scaling factor so that the distances in the input image and panorama image ...
wxButton * m_prevImgButton
HuginBase::PTools::Transform m_leftInvTransformMag
void setHeight(unsigned int h)
set panorama height 
bool updateDisplayValue(const wxString &message, const wxString &filename=wxEmptyString)
virtual wxObject * DoCreateResource()
void setNewPoint(const hugin_utils::FDiff2D &p)
set new point to a specific point 
void transformImage(vigra::triple< SrcImageIterator, SrcImageIterator, SrcAccessor > src, vigra::triple< DestImageIterator, DestImageIterator, DestAccessor > dest, std::pair< AlphaImageIterator, AlphaAccessor > alpha, vigra::Diff2D destUL, TRANSFORM &transform, PixelTransform &pixelTransform, bool warparound, Interpolator interpol, AppBase::ProgressDisplay *progress, bool singleThreaded=false)
Transform an image into the panorama. 
CPEventMode getMode()
accessor functions (they could check mode to see if a getXYZ() is allowed 
#define HUGIN_FT_LOCAL_SEARCH_WIDTH
vigra_ext::CorrelationResult PointFineTuneProjectionAware(const HuginBase::SrcPanoImage &templ, const vigra::UInt8RGBImage &templImg, vigra::Diff2D templPos, int templSize, const HuginBase::SrcPanoImage &search, const vigra::UInt8RGBImage &searchImg, vigra::Diff2D searchPos, int sWidth)
function for fine-tune with remapping to stereographic projection 
#define HUGIN_FT_SEARCH_AREA_PERCENT
bool str2double(const wxString &s, double &d)
SrcPanoImage getSrcImage(unsigned imgNr) const 
get a description of a source image 
void deselect()
remove selection. 
wxMenu * m_cpActionContextMenu
CPImagesComboBox * m_leftChoice
void SortList()
sorting functions 
control point editor panel. 
bool PointFineTune(unsigned int tmplImgNr, const vigra::Diff2D &tmplPoint, int tmplWidth, unsigned int subjImgNr, const hugin_utils::FDiff2D &subjPoint, int searchWidth, vigra_ext::CorrelationResult &tunedPos)
search for region in destImg 
bool removeObserver(PanoramaObserver *observer)
remove a panorama observer. 
void OnCPListDeselect(wxListEvent &e)
std::unique_ptr< wxMessageDialogBase > MessageDialog
CPImagesComboBox * m_rightChoice
virtual bool CanHandle(wxXmlNode *node)
hugin_utils::FDiff2D corrPos
CorrelationResult PointFineTune(const IMAGET &templImg, ACCESSORT access_t, vigra::Diff2D templPos, int templSize, const IMAGES &searchImg, ACCESSORS access_s, vigra::Diff2D searchPos, int sWidth)
fine tune a point with normalized cross correlation 
void OnAddButton(wxCommandEvent &e)
void OnCreateCPButton(wxCommandEvent &e)
#define HUGIN_FT_CURV_THRESHOLD
void registerPTWXDlgFcn()
void OnCPListSelect(wxListEvent &e)
#define HUGIN_FT_ROTATION_STEPS
CPTabActionButtonMode m_cpActionButtonMode
void selectPoint(unsigned int, bool scrollTo=true)
select a point for usage 
Events to notify about new point / region / point change. 
void FineTuneSelectedPoint(bool left)
int wxCALLBACK SortIndexAscending(wxIntPtr item1, wxIntPtr item2, wxIntPtr WXUNUSED(sortData))
void OnKey(wxKeyEvent &e)
void deregisterPTWXDlgFcn()
int getNextCPTypeLineNumber() const 
get the number of a control point 
general : Matrix3 is a class for handling 3x3 Matrix manipulation. 
std::size_t getNrOfCtrlPoints() const 
number of control points 
bool set_contains(const _Container &c, const typename _Container::key_type &key)
#define SORTASCENDING(functionName, var)
wxButton * m_nextImgButton
#define DEBUG_ASSERT(cond)
HuginBase::ImageCache::ImageCacheRGB8Ptr ImageCacheRGB8Ptr
void SetArgs(wxString new_args)
sets arguments of one step detector or feature descriptor 
void OnFineTuneButton(wxCommandEvent &e)
include file for the hugin project 
void setLeftImage(unsigned int imgNr)
set left image 
void GetRotationPT(double &Yaw, double &Pitch, double &Roll)
GetRotation in panotools style. 
Owner Drawn ComboBox for showing connected images on CP tab. 
const CPVector & getCtrlPoints() const 
get all control point of this Panorama 
int getHeight() const 
Get the height of the image in pixels. 
void EnablePointEdit(bool state)
enable or disable controls for editing other points 
void OnNextImg(wxCommandEvent &e)
unsigned int getPointNr()
remove several control points 
represents a control point 
const Map::mapped_type & const_map_get(const Map &m, const typename Map::key_type &key)
void SetRotationPT(double yaw, double pitch, double roll)
set rotation in panotools style, code adapted from Panotools-Script by Bruno Postle ...
void ShowControlPoint(unsigned int cpNr)
show a control point 
void setOptimizeVector(const OptimizeVector &optvec)
set optimize setting 
CorrelationResult PointFineTuneRotSearch(const IMAGET &templImg, vigra::Diff2D templPos, int templSize, const IMAGES &searchImg, vigra::Diff2D searchPos, int sWidth, double startAngle, double stopAngle, int angleSteps)
fine tune a point with normalized cross correlation, searches x,y and phi (rotation around z) ...
MessageDialog GetMessageDialog(const wxString &message, const wxString &caption, int style, wxWindow *parent)
void OnActionContextMenu(wxContextMenuEvent &e)
virtual ~CPEditorPanel()
dtor. 
void OnActionButton(wxCommandEvent &e)
unsigned int m_leftImageNr
std::set< unsigned int > UIntSet
void OnCleanCPButton(wxCommandEvent &e)
void OnTextPointChange(wxCommandEvent &e)
void clearNewPoint()
clear new point 
wxCheckBox * m_fineTuneCB
double getScale()
return scale factor, 0 for autoscale 
right point, finetune for left point failed 
void OnLeftChoiceChange(wxCommandEvent &e)
#define HUGIN_FT_TEMPLATE_SIZE
class, which stores all settings of one cp detector 
void CreateNewPoint()
this is used to finally create the point in the panorama model 
wxCheckBox * m_showLinesCB
const VariableMap getImageVariables(unsigned int imgNr) const 
Get the variables of an image. 
void OnZoom(wxCommandEvent &e)
bool Create(wxWindow *parent, wxWindowID id=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxTAB_TRAVERSAL, const wxString &name="panel")
std::size_t getNrOfImages() const 
number of images. 
static MainFrame * Get()
hack.. kind of a pseudo singleton... 
void Init(CPEditorPanel *parent)
void clearCtrlPointList()
clear internal control point list 
CPCreationState
the state machine for point selection: it is set to the current selection 
void FineTuneNewPoint(bool left)
void setCtrlPoints(const CPVector &points)
set all control points (Ippei: Is this supposed to be 'add' method?) 
void SetProg(wxString new_prog)
sets program for one step detector or feature descriptor 
#define HUGIN_CELESTE_FILTER
int getWidth() const 
Get the width of the image in pixels. 
CPImageCtrl::ImageRotation GetRot(double yaw, double roll, double pitch)
calculate rotation required for upright image display from roll, pitch and yaw angles ...
const ControlPoint & getCtrlPoint(std::size_t nr) const 
get a control point, counting starts with 0 
hugin_utils::FDiff2D EstimatePoint(const hugin_utils::FDiff2D &p, bool left)
Estimate position of point in the other image. 
#define HUGIN_CELESTE_THRESHOLD
HuginBase::PTools::Transform m_rightTransform
void showTemplateArea(bool show=true)
wxPoint MaxScrollDelta(wxPoint delta)
calculate maximum delta that is allowed when scrolling 
IMPLEMENT_DYNAMIC_CLASS(wxTreeListHeaderWindow, wxWindow)
Maximum of correlation, position and value. 
void OnDeleteButton(wxCommandEvent &e)
hugin_utils::FDiff2D curv
bool globalPNr2LocalPNr(unsigned int &localNr, unsigned int globalNr) const 
map a global point nr to a local one, if possible 
#define SORTDESCENDING(functionName, var)
CPCreationState cpCreationState
wxwindows specific panorama commands 
evaluate x, points are on a vertical line 
unsigned int localPNr2GlobalPNr(unsigned int localNr) const 
find a local point 
void OnActionSelectCleanCP(wxCommandEvent &e)
static GlobalCmdHist & getInstance()
void OnActionSelectCeleste(wxCommandEvent &e)
point in left image selected 
void OnShowLinesCheckbox(wxCommandEvent &e)
std::set< unsigned int > mirroredPoints
TDiff2D< double > FDiff2D
const hugin_utils::FDiff2D & getPoint()
CPImageCtrl::ImageRotation m_rightRot
HuginBase::PTools::Transform m_leftTransformMag
void addCommand(PanoCommand *command, bool execute=true)
Adds a command to the history. 
vigra::pair< typename ROIImage< Image, Alpha >::image_traverser, typename ROIImage< Image, Alpha >::ImageAccessor > destImage(ROIImage< Image, Alpha > &img)
void ClearSelection()
unselect a point 
HuginBase::PTools::Transform m_leftInvTransform
vigra::triple< typename ROIImage< Image, Mask >::image_const_traverser, typename ROIImage< Image, Mask >::image_const_traverser, typename ROIImage< Image, Mask >::ImageConstAccessor > srcImageRange(const ROIImage< Image, Mask > &img)
helper function for ROIImages 
void setTransforms(HuginBase::PTools::Transform *firstTrans, HuginBase::PTools::Transform *firstInvTrans, HuginBase::PTools::Transform *secondInvTrans)
!! from PTOptimise.h 1951 
HuginBase::PTools::Transform m_rightInvTransform
unsigned int addImage(const SrcPanoImage &img)
the the number for a specific image 
void showSearchArea(bool show=true)
show/hide the search area rectangle 
CPImageCtrl::ImageRotation m_leftRot
void RunCPGenerator(CPDetectorSetting &setting, const HuginBase::UIntSet &img)
run the cp generator with the given setting on selected images 
std::vector< deghosting::BImagePtr > threshold(const std::vector< deghosting::FImagePtr > &inputImages, const double threshold, const uint16_t flags)
Threshold function used for creating alpha masks for images. 
wxButton * m_actionButton
unsigned int m_rightImageNr
void Init(HuginBase::Panorama *pano)
void setHFOV(double h, bool keepView=true)
set the horizontal field of view. 
int wxCALLBACK SortIndexDescending(wxIntPtr item1, wxIntPtr item2, wxIntPtr WXUNUSED(sortData))
void addObserver(PanoramaObserver *o)
add a panorama observer. 
void estimateAndAddOtherPoint(const hugin_utils::FDiff2D &p, bool left, CPImageCtrl *thisImg, unsigned int thisImgNr, CPCreationState THIS_POINT, CPCreationState THIS_POINT_RETRY, CPImageCtrl *otherImg, unsigned int otherImgNr, CPCreationState OTHER_POINT, CPCreationState OTHER_POINT_RETRY)
estimate and set point in other image 
struct celeste::svm_model * GetSVMModel()
unsigned int getWidth() const 
hugin_utils::FDiff2D getNewPoint()
get the new point 
void OnCPEvent(CPEvent &ev)
void changeState(CPCreationState newState)
#define HUGIN_FT_ROTATION_START_ANGLE
include file for the hugin project 
void UpdateTransforms()
updated the internal transform object for drawing line in controls 
void OnPrevImg(wxCommandEvent &e)
const PanoramaOptions & getOptions() const 
returns the options for this panorama 
void OnRightChoiceChange(wxCommandEvent &e)
Handle EVT_KILL_FOCUS and convert it to a EVT_TEXT_ENTER event. 
void SelectLocalPoint(unsigned int LVpointNr, bool scrollLeft=true, bool scrollRight=true)
select a local point. 
HuginBase::UIntSet getCelesteControlPoints(struct svm_model *model, vigra::UInt16RGBImage &input, HuginBase::CPointVector cps, int radius, float threshold, int resize_dimension, bool verbose)
HuginBase::Panorama * m_pano
void setRightImage(unsigned int imgNr)
set right image 
#define HUGIN_FT_CORR_THRESHOLD
CPScrollHint m_scrollHint
void panoramaChanged(HuginBase::Panorama &pano)
called when the panorama changes and we should update our display 
void OnActionSelectCreate(wxCommandEvent &e)
void OnColumnWidthChange(wxListEvent &e)
void setCtrlPoint(const HuginBase::ControlPoint &cp, const bool mirrored)
add control piont to internal cp list 
HuginBase::PTools::Transform m_rightInvTransformMag
void setSize(vigra::Size2D val)
Set the image size in pixels. 
void setScale(double factor)
set the scaling factor for cp display. 
hugin_utils::FDiff2D maxpos
std::vector< ControlPoint > CPVector
vigra::triple< typename ROIImage< Image, Alpha >::image_traverser, typename ROIImage< Image, Alpha >::image_traverser, typename ROIImage< Image, Alpha >::ImageAccessor > destImageRange(ROIImage< Image, Alpha > &img)
void transformImage(SrcImageIterator src_upperleft, SrcImageIterator src_lowerright, SrcAccessor src_acc, DestImageIterator dest_upperleft, DestAccessor dest_acc, const Functor &func)
const float getVerticalCPBias()
void copyImage(SrcImageIterator src_upperleft, SrcImageIterator src_lowerright, SrcAccessor src_acc, DestImageIterator dest_upperleft, DestAccessor dest_acc)
std::vector< std::set< std::string > > OptimizeVector
const HuginBase::ControlPoint & getControlPoint()
vigra::Diff2D toDiff2D() const 
void setImage(const std::string &filename, ImageRotation rot)
display img. 
bool updateDisplay(const wxString &message)
const SrcPanoImage & getImage(std::size_t nr) const 
get a panorama image, counting starts with 0 
bool m_listenToPageChange
HuginBase::PTools::Transform m_rightTransformMag
void setMagTransforms(HuginBase::PTools::Transform *magTrans, HuginBase::PTools::Transform *magInvTrans)
void showPosition(hugin_utils::FDiff2D point, bool warpPointer=false)
Show point x, y. 
ProjectionFormat
Projection of final panorama. 
wxCheckBox * m_estimateCB
selected point in right image 
wxChoice * m_cpModeChoice
void setSameImage(bool sameImage)
point in left image selected, finetune failed in right image 
hugin_utils::FDiff2D LocalFineTunePoint(unsigned int srcNr, const vigra::Diff2D &srcPnt, hugin_utils::FDiff2D &movedSrcPnt, unsigned int moveNr, const hugin_utils::FDiff2D &movePnt)
HuginBase::PTools::Transform m_leftTransform
All variables of a source image. 
void setProjection(ProjectionFormat f)
set the Projection format and adjust the hfov/vfov if nessecary 
HuginBase::CPointVector currentPoints
bool IsShowingCorrelation() const 
vigra::Size2D getSize() const 
get size of output image 
#define HUGIN_FT_ROTATION_STOP_ANGLE
evaluate y, points are on a horizontal line 
functions to handle icc profiles in images 
left and right point selected, waiting for add point. 
double m_detailZoomFactor
int HuginMessageBox(const wxString &message, const wxString &caption, int style, wxWindow *parent)
void OnCelesteButton(wxCommandEvent &e)
ImageRotation
image rotation. 
#define HUGIN_FT_ROTATION_SEARCH
HuginBase::SrcPanoImage GetImageRotatedTo(const HuginBase::SrcPanoImage &img, const vigra::Diff2D &point, int testWidth, double &neededHFOV)
void mirror()
swap (image1Nr,x1,y1) with (image2Nr,x2,y2) 
void panoramaImagesChanged(HuginBase::Panorama &pano, const HuginBase::UIntSet &imgNr)
notifies about changes to images 
unsigned int m_selectedPoint
void ApplyICCProfile(ImageType &image, const vigra::ImageImportInfo::ICCProfile &iccProfile, const cmsUInt32Number imageFormat)
converts given image with iccProfile to sRGB/gray space, need to give pixel type in lcms2 format work...
void SetRefImage(HuginBase::Panorama *pano, unsigned int newRefImg)
Set new reference image. 
void setWidth(unsigned int w, bool keepView=true)
set panorama width keep the HFOV, if keepView=true 
void UpdateDisplay(bool newImages)
updates the display after another image has been selected. 
void ShowLines(bool isShown)