27 #include "hugin_config.h"
56 #include "vigra/cornerdetection.hxx"
57 #include "vigra/localminmax.hxx"
67 EVT_COMBOBOX(XRCID("cp_editor_left_choice"),
CPEditorPanel::OnLeftChoiceChange )
68 EVT_COMBOBOX(XRCID("cp_editor_right_choice"),
CPEditorPanel::OnRightChoiceChange )
69 EVT_LIST_ITEM_SELECTED(XRCID("cp_editor_cp_list"),
CPEditorPanel::OnCPListSelect)
70 EVT_LIST_ITEM_DESELECTED(XRCID("cp_editor_cp_list"),
CPEditorPanel::OnCPListDeselect)
71 EVT_LIST_COL_END_DRAG(XRCID("cp_editor_cp_list"),
CPEditorPanel::OnColumnWidthChange)
72 EVT_LIST_COL_CLICK(XRCID("cp_editor_cp_list"),
CPEditorPanel::OnColumnHeaderClick)
73 EVT_CHOICE(XRCID("cp_editor_choice_zoom"),
CPEditorPanel::OnZoom)
74 EVT_TEXT_ENTER(XRCID("cp_editor_x1"),
CPEditorPanel::OnTextPointChange )
75 EVT_TEXT_ENTER(XRCID("cp_editor_y1"),
CPEditorPanel::OnTextPointChange )
76 EVT_TEXT_ENTER(XRCID("cp_editor_x2"),
CPEditorPanel::OnTextPointChange )
77 EVT_TEXT_ENTER(XRCID("cp_editor_y2"),
CPEditorPanel::OnTextPointChange )
78 EVT_CHOICE(XRCID("cp_editor_mode"),
CPEditorPanel::OnTextPointChange )
80 EVT_BUTTON(XRCID("cp_editor_delete"),
CPEditorPanel::OnDeleteButton)
81 EVT_BUTTON(XRCID("cp_editor_add"),
CPEditorPanel::OnAddButton)
82 EVT_BUTTON(XRCID("cp_editor_previous_img"),
CPEditorPanel::OnPrevImg)
83 EVT_BUTTON(XRCID("cp_editor_next_img"),
CPEditorPanel::OnNextImg)
84 EVT_BUTTON(XRCID("cp_editor_finetune_button"),
CPEditorPanel::OnFineTuneButton)
85 EVT_BUTTON(XRCID("cp_editor_action_button"),
CPEditorPanel::OnActionButton)
86 EVT_MENU(XRCID("cp_menu_create_cp"),
CPEditorPanel::OnActionSelectCreate)
87 EVT_MENU(XRCID("cp_menu_celeste"),
CPEditorPanel::OnActionSelectCeleste)
88 EVT_MENU(XRCID("cp_menu_clean_cp"),
CPEditorPanel::OnActionSelectCleanCP)
89 EVT_CHECKBOX(XRCID("cp_editor_show_lines"),
CPEditorPanel::OnShowLinesCheckbox)
99 #if !wxCHECK_VERSION(3,1,6)
104 item.SetMask(wxLIST_MASK_IMAGE);
105 item.SetImage(image);
106 list->SetColumn(col, item);
114 const wxString& name)
117 if (! wxPanel::Create(parent,
id, pos, size, style, name) ) {
132 wxXmlResource::Get()->LoadPanel(
this, wxT(
"cp_editor_panel"));
133 wxPanel * panel = XRCCTRL(*
this,
"cp_editor_panel", wxPanel);
135 wxBoxSizer *topsizer =
new wxBoxSizer( wxVERTICAL );
136 topsizer->Add(panel, 1, wxEXPAND, 0);
154 m_cpList = XRCCTRL(*
this,
"cp_editor_cp_list", wxListCtrl);
156 m_cpList->InsertColumn( 0, _(
"#"), wxLIST_FORMAT_RIGHT, 35);
157 m_cpList->InsertColumn( 1, _(
"left x"), wxLIST_FORMAT_RIGHT, 65);
158 m_cpList->InsertColumn( 2, _(
"left y"), wxLIST_FORMAT_RIGHT, 65);
159 m_cpList->InsertColumn( 3, _(
"right x"), wxLIST_FORMAT_RIGHT, 65);
160 m_cpList->InsertColumn( 4, _(
"right y"), wxLIST_FORMAT_RIGHT, 65);
161 m_cpList->InsertColumn( 5, _(
"Alignment"), wxLIST_FORMAT_LEFT,110 );
162 m_cpList->InsertColumn( 6, _(
"Distance"), wxLIST_FORMAT_RIGHT, 110);
165 wxConfigBase* config = wxConfig::Get();
166 for (
int j=0; j <
m_cpList->GetColumnCount() ; j++ )
169 int width = config->Read(wxString::Format( wxT(
"/CPEditorPanel/ColumnWidth%d"), j ), -1);
173 m_sortCol = config->Read(wxT(
"/CPEditorPanel/SortColumn"), -1);
174 m_sortAscending = config->Read(wxT(
"/CPEditorPanel/SortAscending"), 1) == 1 ?
true :
false;
177 #if wxCHECK_VERSION(3,1,6)
184 #if !wxCHECK_VERSION(3,1,6)
187 memDC.SetFont(GetFont());
188 wxSize fontSize = memDC.GetTextExtent(wxT(
"\u25b3"));
189 wxCoord charSize =
std::max(fontSize.GetWidth(), fontSize.GetHeight());
190 wxImageList* sortIcons =
new wxImageList(charSize, charSize,
true, 0);
192 wxBitmap bmp(charSize, charSize);
194 dc.SetBackgroundMode(wxPENSTYLE_TRANSPARENT);
195 dc.SetBackground(GetBackgroundColour());
197 dc.SetFont(GetFont());
198 dc.DrawText(wxT(
"\u25b3"), (charSize - fontSize.GetWidth()) / 2, (charSize - fontSize.GetHeight()) / 2);
199 dc.SelectObject(wxNullBitmap);
200 sortIcons->Add(bmp, GetBackgroundColour());
203 wxBitmap bmp(charSize, charSize);
205 dc.SetBackgroundMode(wxPENSTYLE_TRANSPARENT);
206 dc.SetBackground(GetBackgroundColour());
208 dc.SetFont(GetFont());
209 dc.DrawText(wxT(
"\u25bd"), (charSize - fontSize.GetWidth()) / 2, (charSize - fontSize.GetHeight()) / 2);
210 dc.SelectObject(wxNullBitmap);
211 sortIcons->Add(bmp, GetBackgroundColour());
213 m_cpList->AssignImageList(sortIcons, wxIMAGE_LIST_SMALL);
217 m_x1Text = XRCCTRL(*
this,
"cp_editor_x1", wxTextCtrl);
219 m_y1Text = XRCCTRL(*
this,
"cp_editor_y1", wxTextCtrl);
221 m_x2Text = XRCCTRL(*
this,
"cp_editor_x2", wxTextCtrl);
223 m_y2Text = XRCCTRL(*
this,
"cp_editor_y2", wxTextCtrl);
227 m_addButton = XRCCTRL(*
this,
"cp_editor_add", wxButton);
228 m_delButton = XRCCTRL(*
this,
"cp_editor_delete", wxButton);
230 m_autoAddCB = XRCCTRL(*
this,
"cp_editor_auto_add", wxCheckBox);
232 m_fineTuneCB = XRCCTRL(*
this,
"cp_editor_fine_tune_check",wxCheckBox);
235 m_estimateCB = XRCCTRL(*
this,
"cp_editor_auto_estimate", wxCheckBox);
238 m_showLinesCB = XRCCTRL(*
this,
"cp_editor_show_lines", wxCheckBox);
241 m_actionButton = XRCCTRL(*
this,
"cp_editor_action_button", wxButton);
245 m_cp_ctrls = XRCCTRL(*
this,
"cp_controls_panel", wxPanel);
248 m_autoAddCB->SetValue(config->Read(wxT(
"/CPEditorPanel/autoAdd"),0l) != 0 );
249 m_fineTuneCB->SetValue(config->Read(wxT(
"/CPEditorPanel/autoFineTune"),1l) != 0 );
250 m_estimateCB->SetValue(config->Read(wxT(
"/CPEditorPanel/autoEstimate"),1l) != 0 );
251 m_showLinesCB->SetValue(config->Read(wxT(
"/CPEditorPanel/showLines"), 1l) != 0);
263 XRCCTRL(*
this,
"cp_editor_finetune_button", wxButton)->Disable();
265 XRCCTRL(*
this,
"cp_editor_choice_zoom", wxChoice)->Disable();
266 XRCCTRL(*
this,
"cp_editor_previous_img", wxButton)->Disable();
267 XRCCTRL(*
this,
"cp_editor_next_img", wxButton)->Disable();
272 wxCommandEvent dummy;
273 dummy.SetInt(XRCCTRL(*
this,
"cp_editor_choice_zoom",wxChoice)->GetSelection());
276 SetSizer( topsizer );
324 wxConfigBase* config = wxConfig::Get();
325 config->Write(wxT(
"/CPEditorPanel/autoAdd"),
m_autoAddCB->IsChecked() ? 1 : 0);
326 config->Write(wxT(
"/CPEditorPanel/autoFineTune"),
m_fineTuneCB->IsChecked() ? 1 : 0);
327 config->Write(wxT(
"/CPEditorPanel/autoEstimate"),
m_estimateCB->IsChecked() ? 1 : 0);
328 config->Write(wxT(
"/CPEditorPanel/showLines"),
m_showLinesCB->IsChecked() ? 1 : 0);
329 config->Write(wxT(
"/CPEditorPanel/SortColumn"),
m_sortCol);
330 config->Write(wxT(
"/CPEditorPanel/SortAscending"),
m_sortAscending ? 1 : 0);
340 if (imgNr == UINT_MAX) {
364 ImageCache::getInstance().softFlush();
372 if (imgNr == UINT_MAX) {
401 ImageCache::getInstance().softFlush();
413 if(m_leftImageNr<m_pano->getNrOfImages())
432 if(m_rightImageNr<m_pano->getNrOfImages())
472 #define SORTASCENDING(functionName, var) \
473 int wxCALLBACK functionName(wxIntPtr item1, wxIntPtr item2, wxIntPtr sortData)\
475 HuginBase::CPointVector* data = (HuginBase::CPointVector*)(sortData);\
476 if (data->at(item1).second.var > data->at(item2).second.var)\
478 if (data->at(item1).second.var < data->at(item2).second.var)\
483 #define SORTDESCENDING(functionName, var) \
484 int wxCALLBACK functionName(wxIntPtr item1, wxIntPtr item2, wxIntPtr sortData)\
486 HuginBase::CPointVector* data = (HuginBase::CPointVector*)(sortData); \
487 if (data->at(item1).second.var < data->at(item2).second.var)\
489 if (data->at(item1).second.var > data->at(item2).second.var)\
508 #undef SORTDESCENDING
599 }
else if (ev.GetEventObject() ==
m_rightImg){
630 const long selectedPoint =
m_cpList->FindItem(-1, nr);
633 m_cpList->SetItemState(selectedPoint, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
643 bool hor = std::abs(cp.
x1 - cp.
x2) > (std::abs(cp.
y1 - cp.
y2) * vertBias);
676 DEBUG_ERROR(
"invalid point number while moving point")
682 <<
" " << cp.
x2 <<
"," << cp.
y2);
751 if(!cpToRemove.empty())
783 bool hor = std::abs(p1.
x - p2.
x) > (std::abs(p1.
y - p2.
y) * vertBias);
847 if (selectedPoint != wxNOT_FOUND)
849 m_cpList->SetItemState(selectedPoint, 0, wxLIST_STATE_SELECTED);
861 DEBUG_TRACE(
"selectLocalPoint(" << LVpointNr <<
")");
872 m_x1Text->SetValue(wxString::Format(wxT(
"%.2f"),p.
x1));
873 m_y1Text->SetValue(wxString::Format(wxT(
"%.2f"),p.
y1));
874 m_x2Text->SetValue(wxString::Format(wxT(
"%.2f"),p.
x2));
875 m_y2Text->SetValue(wxString::Format(wxT(
"%.2f"),p.
y2));
879 const long selectedPoint =
m_cpList->FindItem(-1, LVpointNr);
880 if (scrollLeft && scrollRight)
884 m_cpList->SetItemState(selectedPoint, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
886 m_cpList->EnsureVisible(selectedPoint);
893 unsigned int localNr;
895 DEBUG_DEBUG(
"CPEditor::setGlobalPoint(" << globalNr <<
") found local point " << localNr);
898 DEBUG_ERROR(
"CPEditor::setGlobalPoint: point " << globalNr <<
" not found in currentPoints");
904 HuginBase::CPointVector::const_iterator it =
currentPoints.begin();
906 while(it !=
currentPoints.end() && (*it).first != globalNr) {
928 unsigned int thisImgNr,
932 unsigned int otherImgNr,
940 if (op.
x < (
int) pImg.getSize().width() && op.
x >= 0
941 && op.
y < (int) pImg.getSize().height() && op.
y >= 0)
947 MainFrame::Get()->SetStatusText(_(
"searching similar points..."),0);
965 }
catch (std::exception & e) {
966 wxMessageBox(wxString (e.what(), wxConvLocal), _(
"Error during Fine-tune"));
970 if (corrPoint.corrPos.x >= 0 && corrPoint.corrPos.y >= 0 && corrPoint.maxpos.x > 0 && corrPoint.maxpos.y > 0)
985 s1.Printf(_(
"Point fine-tuned, angle: %.0f deg, correlation coefficient: %0.3f, curvature: %0.3f %0.3f"),
986 corrPoint.maxAngle, corrPoint.maxi, corrPoint.curv.x, corrPoint.curv.y );
988 wxString s2 = s1 + wxT(
" -- ") + wxString(_(
"change points, or press right mouse button to add the pair"));
1009 MainFrame::Get()->SetStatusText(_(
"Estimated point outside image"),0);
1051 bool hasNormalCP =
false;
1056 if (estimate && (thisImgNr != otherImgNr) && hasNormalCP) {
1058 thisImg, thisImgNr, THIS_POINT, THIS_POINT_RETRY,
1059 otherImg, otherImgNr, OTHER_POINT, OTHER_POINT_RETRY);
1068 bool hasNormalCP =
false;
1073 if (estimate && (thisImgNr != otherImgNr) && hasNormalCP) {
1075 thisImg, thisImgNr, THIS_POINT, THIS_POINT_RETRY,
1076 otherImg, otherImgNr, OTHER_POINT, OTHER_POINT_RETRY);
1091 double sAreaPercent = wxConfigBase::Get()->Read(wxT(
"/Finetune/SearchAreaPercent"),
1094 bool corrOk =
false;
1096 vigra::Diff2D newPoint_round = newPoint.
toDiff2D();
1105 }
catch (std::exception & e) {
1106 wxMessageBox(wxString (e.what(), wxConvLocal), _(
"Error during Fine-tune"));
1130 s1.Printf(_(
"Point fine-tuned, angle: %.0f deg, correlation coefficient: %0.3f, curvature: %0.3f %0.3f"),
1133 corrMsg = s1 + wxT(
" -- ") + wxString(_(
"change points, or press right mouse button to add the pair"));
1166 if (corrMsg != wxT(
"")) {
1186 imgMod.
setSize(img.getSize());
1187 imgMod.setProjection(img.getProjection());
1188 imgMod.setHFOV(img.getHFOV());
1225 neededHFOV = 2.0 * (x1 - x2);
1230 neededHFOV = 2.0 * (360 - x2 + x1);
1233 if (neededHFOV > 90)
1245 neededHFOV = 2.0 * (x2 - x1);
1250 neededHFOV = 2.0 * (360 + x2 - x1);
1253 if (neededHFOV > 90)
1265 vigra::Diff2D templPos,
int templSize,
1267 vigra::Diff2D searchPos,
int sWidth)
1271 wxConfigBase *cfg = wxConfigBase::Get();
1281 if (templ.getProjection() == search.getProjection()
1282 && templ.getHFOV() < 65 && search.getHFOV() < 65
1283 && fabs(templ.getHFOV() - search.getHFOV()) < 5)
1286 if (rotatingFinetune)
1289 searchImg, searchPos, sWidth, startAngle, stopAngle, nSteps);
1293 res =
vigra_ext::PointFineTune(templImg, vigra::RGBToGrayAccessor<vigra::RGBValue<vigra::UInt8> >(), templPos, templSize,
1294 searchImg, vigra::RGBToGrayAccessor<vigra::RGBValue<vigra::UInt8> >(), searchPos, sWidth);
1302 double templHFOV = 0;
1303 double searchHFOV = 0;
1309 if (templHFOV < 0 || searchHFOV < 0)
1326 double templX, templY, searchX, searchY;
1334 vigra::UInt8RGBImage searchImgMod(opts.
getSize());
1335 vigra::BImage alpha(opts.
getSize());
1341 vigra::Rect2D rect(templPointInt.x - templSize - 2, templPointInt.y - templSize - 2,
1342 templPointInt.x + templSize + 2, templPointInt.y + templSize + 2);
1343 rect &= vigra::Rect2D(opts.
getSize());
1345 vigra::UInt8RGBImage templImgMod(opts.
getSize());
1348 #if defined DEBUG_EXPORT_FINE_TUNE_REMAPPING
1350 vigra::ImageExportInfo templExport(
"template_remapped.tif");
1351 vigra::exportImage(
srcImageRange(templImgMod), templExport.setPixelType(
"UINT8"));
1352 vigra::ImageExportInfo searchExport(
"search_remapped.tif");
1353 vigra::exportImage(
srcImageRange(searchImgMod), searchExport.setPixelType(
"UINT8"));
1371 const vigra::Diff2D & tmplPoint,
1373 unsigned int subjImgNr,
1378 DEBUG_TRACE(
"tmpl img nr: " << tmplImgNr <<
" corr src: "
1380 if (tmplImgNr == subjImgNr)
1385 const double distance = (tmplPoint - o_subjPoint.
toDiff2D()).magnitude();
1386 if (distance < sWidth)
1388 sWidth = 0.9 * distance;
1390 if (sWidth < 1.1 * templSize)
1392 MainFrame::Get()->SetStatusText(_(
"Distance between line control points too short, skipping fine-tune."));
1397 MainFrame::Get()->SetStatusText(_(
"searching similar points..."),0);
1400 wxConfigBase::Get()->Read(wxT(
"/Finetune/CorrThreshold"),&corrThresh,
1405 if (tmplImgNr != subjImgNr)
1423 MainFrame::Get()->SetStatusText(wxString::Format(_(
"Point fine-tuned, angle: %.0f deg, correlation coefficient: %0.3f, curvature: %0.3f %0.3f"),
1428 wxMessageDialog dlg(
this,
1429 _(
"No similar point found."),
1435 wxICON_ERROR | wxOK);
1436 dlg.SetExtendedMessage(_(
"An internal transformation went wrong.\nCheck that the point is inside the image."));
1440 if (res.
maxi < corrThresh || res.
curv.
x < curvThresh || res.
curv.
y < curvThresh )
1443 wxMessageDialog dlg(
this,
1444 _(
"No similar point found."),
1450 wxICON_ERROR | wxOK);
1451 dlg.SetExtendedMessage(wxString::Format(_(
"Check the similarity visually.\nCorrelation coefficient (%.3f) is lower than the threshold set in the preferences."),
1464 DEBUG_DEBUG(
"mode choice: " << nGui <<
" entries, required: " << nPano);
1470 for (
int i = nGui-1; i > nPano-1; --i) {
1477 }
else if (nGui < nPano) {
1480 m_cpModeChoice->SetString(nGui-1, wxString::Format(_(
"Line %d"), nGui-1));
1482 for (
int i = nGui; i < nPano-1; i++) {
1501 item.SetText(_(
"Correlation"));
1505 item.SetText(_(
"Distance"));
1517 DEBUG_TRACE(
"nrImages:" << nrImages <<
" nrTabs:" << nrTabs);
1534 XRCCTRL(*
this,
"cp_editor_finetune_button", wxButton)->Disable();
1536 XRCCTRL(*
this,
"cp_editor_choice_zoom", wxChoice)->Disable();
1537 XRCCTRL(*
this,
"cp_editor_previous_img", wxButton)->Disable();
1538 XRCCTRL(*
this,
"cp_editor_next_img", wxButton)->Disable();
1550 XRCCTRL(*
this,
"cp_editor_finetune_button", wxButton)->Enable();
1552 XRCCTRL(*
this,
"cp_editor_choice_zoom", wxChoice)->Enable();
1553 XRCCTRL(*
this,
"cp_editor_previous_img", wxButton)->Enable();
1554 XRCCTRL(*
this,
"cp_editor_next_img", wxButton)->Enable();
1558 ImageCache::getInstance().softFlush();
1562 for (
unsigned int i=0; i < ((nrTabs < nrImages)? nrTabs: nrImages); i++) {
1564 m_leftChoice->SetString(i, wxString::Format(wxT(
"%d"), i) + wxT(
". - ") + fileName.GetFullName());
1565 m_rightChoice->SetString(i, wxString::Format(wxT(
"%d"), i) + wxT(
". - ") + fileName.GetFullName());
1573 if (nrTabs < nrImages)
1575 for (
unsigned int i=nrTabs; i < nrImages; i++)
1578 m_leftChoice->Append(wxString::Format(wxT(
"%d"), i) + wxT(
". - ") + fileName.GetFullName());
1579 m_rightChoice->Append(wxString::Format(wxT(
"%d"), i) + wxT(
". - ") + fileName.GetFullName());
1585 if (nrTabs > nrImages)
1593 for (
int i=nrTabs-1; i >= (int)nrImages; i--) {
1622 for(HuginBase::UIntSet::const_iterator it = changed.begin(); it != changed.end(); ++it) {
1623 unsigned int imgNr = *it;
1677 if (update || nrImages == 0) {
1721 HuginBase::CPVector::size_type i = 0;
1724 for (HuginBase::CPVector::size_type index = 0; index < controlPoints.size(); ++index)
1745 unsigned int selectedItem = UINT_MAX;
1746 long selectedCP = -1;
1747 for (
int i = 0; i <
m_cpList->GetItemCount(); i++)
1749 if (
m_cpList->GetItemState( i, wxLIST_STATE_SELECTED))
1751 selectedItem = (
unsigned int) i;
1752 selectedCP =
m_cpList->GetItemData(i);
1762 long item =
m_cpList->InsertItem(i, wxString::Format(wxT(
"%d"), i), -1);
1765 m_cpList->SetItem(i,1,wxString::Format(wxT(
"%.2f"),p.
x1));
1766 m_cpList->SetItem(i,2,wxString::Format(wxT(
"%.2f"),p.
y1));
1767 m_cpList->SetItem(i,3,wxString::Format(wxT(
"%.2f"),p.
x2));
1768 m_cpList->SetItem(i,4,wxString::Format(wxT(
"%.2f"),p.
y2));
1775 mode = _(
"vert. Line");
1778 mode = _(
"horiz. Line");
1781 mode = wxString::Format(_(
"Line %d"), p.
mode);
1785 m_cpList->SetItem(i,6,wxString::Format(wxT(
"%.2f"),p.
error));
1789 if (selectedItem <= (
unsigned int)
m_cpList->GetItemCount() && !newPair &&
m_cpList->GetItemCount() > 0)
1796 long selected =
m_cpList->FindItem(-1, selectedCP);
1797 m_cpList->SetItemState(selected, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
1804 if (selectedItem == (
unsigned int)
m_cpList->GetItemCount())
1807 selectedItem =
m_cpList->GetItemCount() - 1;
1809 m_cpList->SetItemState(selectedItem, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
1810 m_cpList->EnsureVisible(selectedItem);
1816 m_x1Text->SetValue(wxString::Format(wxT(
"%.2f"),p.
x1));
1817 m_y1Text->SetValue(wxString::Format(wxT(
"%.2f"),p.
y1));
1818 m_x2Text->SetValue(wxString::Format(wxT(
"%.2f"),p.
x2));
1819 m_y2Text->SetValue(wxString::Format(wxT(
"%.2f"),p.
y2));
1829 for (
int j=0; j <
m_cpList->GetColumnCount() ; j++ )
1833 int width = wxConfigBase::Get()->Read(wxString::Format( wxT(
"/CPEditorPanel/ColumnWidth%d"), j ), -1);
1835 m_cpList->SetColumnWidth(j, width);
1844 XRCCTRL(*
this,
"cp_editor_finetune_button", wxButton)->Enable(state);
1859 wxLIST_STATE_SELECTED);
1864 const unsigned int nr =
m_cpList->GetItemData(item);
1869 double oldValue=cp.x1;
1919 DEBUG_TRACE(
"OnLeftChoiceChange() to " << e.GetSelection());
1927 DEBUG_TRACE(
"OnRightChoiceChange() to " << e.GetSelection());
1934 int t = ev.GetIndex();
1972 const wxSize leftSize =
m_leftImg->GetClientSize();
1973 const wxSize rightSize =
m_rightImg->GetClientSize();
1983 switch (e.GetSelection()) {
2024 m_leftImg->Scroll(leftX*factor - leftSize.GetWidth() / 2, leftY*factor - leftSize.GetHeight() / 2);
2025 m_rightImg->Scroll(rightX*factor - rightSize.GetWidth() / 2, rightY*factor - rightSize.GetHeight() / 2);
2033 <<
" origin: id:" << e.GetId() <<
" obj: "
2034 << e.GetEventObject());
2036 if (e.m_keyCode == WXK_DELETE){
2047 wxLIST_STATE_SELECTED);
2059 }
else if (e.m_keyCode ==
'0') {
2060 wxCommandEvent dummy;
2063 XRCCTRL(*
this,
"cp_editor_choice_zoom",wxChoice)->SetSelection(1);
2064 }
else if (e.m_keyCode ==
'1') {
2065 wxCommandEvent dummy;
2068 XRCCTRL(*
this,
"cp_editor_choice_zoom",wxChoice)->SetSelection(0);
2069 }
else if (e.m_keyCode ==
'2') {
2070 wxCommandEvent dummy;
2073 XRCCTRL(*
this,
"cp_editor_choice_zoom",wxChoice)->SetSelection(2);
2074 }
else if (e.CmdDown() && e.GetKeyCode() == WXK_LEFT) {
2076 wxCommandEvent dummy;
2078 }
else if (e.CmdDown() && e.GetKeyCode() == WXK_RIGHT) {
2080 wxCommandEvent dummy;
2082 }
else if (e.GetKeyCode() ==
'f') {
2083 bool left = e.GetEventObject() ==
m_leftImg;
2089 }
else if (e.GetKeyCode() ==
'g') {
2091 long th = wxGetNumberFromUser(_(
"Create control points.\nTo create less points,\nenter a higher number."), _(
"Corner Detection threshold"), _(
"Create control points"), 400, 0, 32000);
2095 long scale = wxGetNumberFromUser(_(
"Create control points"), _(
"Corner Detection scale"), _(
"Create control points"), 2);
2102 DEBUG_DEBUG(
"corner threshold: " << th <<
" scale: " << scale);
2106 }
catch (std::exception & e) {
2107 wxLogError(_(
"Error during control point creation:\n") + wxString(e.what(), wxConvLocal));
2133 wxLIST_STATE_SELECTED);
2183 wxCommandEvent tmpEvt;
2184 tmpEvt.SetInt(XRCCTRL(*
this,
"cp_editor_choice_zoom",wxChoice)->GetSelection());
2204 MainFrame::Get()->SetStatusText(_(
"Select point in right image"),0);
2216 MainFrame::Get()->SetStatusText(_(
"Select point in left image"),0);
2248 }
else if (left >= nImgs) {
2254 }
else if (right >= nImgs) {
2269 }
else if (left >= nImgs) {
2275 }
else if (right >= nImgs) {
2322 linefindSetting.
SetProg(wxT(
"linefind.exe"));
2324 linefindSetting.
SetProg(wxT(
"linefind"));
2326 linefindSetting.
SetArgs(wxT(
"-o %o %s"));
2344 wxMessageBox(_(
"Cannot run celeste without at least one control point connecting the two images"),_(
"Error"));
2345 std::cout <<
"Cannot run celeste without at least one control point connecting the two images" << std::endl;
2359 wxConfigBase *cfg = wxConfigBase::Get();
2366 int radius=(t)?10:20;
2375 vigra::UInt16RGBImage in;
2376 if(img->image16->width()>0)
2378 in.resize(img->image16->size());
2384 in.resize(im8->size());
2388 if (!img->iccProfile->empty())
2403 if(!cloudCP.empty())
2411 wxMessageBox(wxString::Format(_(
"Removed %lu control points"), static_cast<unsigned long int>(cloudCP.size())), _(
"Celeste result"), wxOK | wxICON_INFORMATION,
this);
2430 double x = it->second.error;
2431 double delta = x - mean;
2433 var += delta*(x - mean);
2435 var = var / (n - 1);
2436 const double limit = (sqrt(var) > mean) ? mean : (mean + sqrt(var));
2440 if (it->second.error > limit)
2442 removedCPs.insert(it->first);
2445 if (!removedCPs.empty())
2447 wxMessageBox(wxString::Format(_(
"Removed %lu control points"), (
unsigned long int)removedCPs.size()), _(
"Cleaning"), wxOK | wxICON_INFORMATION,
this);
2459 wxString s(_(
"Create cp"));
2460 s.Append(wxT(
"\u25bc"));
2462 m_actionButton->SetToolTip(_(
"Create control points for image pair with currently selected control point detector on photos tab."));
2464 wxConfig::Get()->Write(wxT(
"/CPEditorPanel/ActionMode"), static_cast<long>(
m_cpActionButtonMode));
2470 wxString s(_(
"Celeste"));
2471 s.Append(wxT(
"\u25bc"));
2473 m_actionButton->SetToolTip(_(
"Tries to remove control points from clouds"));
2475 wxConfig::Get()->Write(wxT(
"/CPEditorPanel/ActionMode"), static_cast<long>(
m_cpActionButtonMode));
2481 wxString s(_(
"Clean cp"));
2482 s.Append(wxT(
"\u25bc"));
2484 m_actionButton->SetToolTip(_(
"Remove outlying control points by statistical method"));
2486 wxConfig::Get()->Write(wxT(
"/CPEditorPanel/ActionMode"), static_cast<long>(
m_cpActionButtonMode));
2490 const vigra::Diff2D & srcPnt,
2492 unsigned int moveNr,
2498 if (!
PointFineTune(srcNr, srcPnt, templWidth, moveNr, movePnt, sWidth, result))
2518 unsigned int srcNr = cp.image1Nr;
2519 unsigned int moveNr = cp.image2Nr;
2523 srcNr = cp.image2Nr;
2524 moveNr = cp.image1Nr;
2532 if (result.
x < 0 || result.
y < 0)
2541 cp.x2 = movedSrcPnt.
x;
2542 cp.y2 = movedSrcPnt.
y;
2546 cp.x1 = movedSrcPnt.
x;
2547 cp.y1 = movedSrcPnt.
y;
2573 vigra::Diff2D srcPnt(leftP.
toDiff2D());
2575 vigra::Diff2D movePnt(rightP.
toDiff2D());
2586 if (result.
x < 0 || result.
y < 0)
2607 size_t nrNormalCp = 0;
2617 DEBUG_WARN(
"Cannot estimate position without at least one point");
2624 leftImg.setPitch(0);
2631 rightImg.setPitch(0);
2632 rightImg.setRoll(0);
2642 std::set<std::string> opt;
2643 optVec.push_back(opt);
2650 optVec.push_back(opt);
2680 if (t.
x < 0) t.
x = 0;
2681 if (t.
y < 0) t.
y = 0;
2694 int colNum = e.GetColumn();
2695 wxConfigBase::Get()->Write( wxString::Format(wxT(
"/CPEditorPanel/ColumnWidth%d"),colNum),
m_cpList->GetColumnWidth(colNum) );
2700 const int newCol = e.GetColumn();
2701 #if wxCHECK_VERSION(3,1,6)
2744 while (roll > 360) roll-= 360;
2745 while (roll < 0) roll += 360;
2747 while (pitch > 180) pitch -= 360;
2748 while (pitch < -180) pitch += 360;
2749 bool headOver = (pitch > 90 || pitch < -90);
2751 if (wxConfig::Get()->Read(wxT(
"/CPEditorPanel/AutoRot"),1L)) {
2752 if (roll >= 315 || roll < 45) {
2754 }
else if (roll >= 45 && roll < 135) {
2756 }
else if (roll >= 135 && roll < 225) {
2768 : wxXmlResourceHandler()
2777 cp->Create(m_parentAsWindow,
2779 GetPosition(), GetSize(),
2780 GetStyle(wxT(
"style")),
2790 return IsOfClass(node, wxT(
"CPEditorPanel"));
void CalcCPDistance(HuginBase::Panorama *pano)
Get maximum CP distance for all images pairs containing the reference image.
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 ...
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)
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)
#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) ...
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)
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
void SetColumnImage(wxListCtrl *list, int col, int image)
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
void update()
initiate redraw
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
#define EVT_CPEVENT(func)
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
bool Create(wxWindow *parent, wxWindowID id=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxTAB_TRAVERSAL, const wxString &name=wxT("panel"))
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
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)