Hugin trunk 0.1
Loading...
Searching...
No Matches
PreviewPanel.cpp
Go to the documentation of this file.
1// -*- c-basic-offset: 4 -*-
2
27#include "hugin_config.h"
28#include "panoinc_WX.h"
29#include "panoinc.h"
30
31#include <vigra/basicimageview.hxx>
32#include "nona/Stitcher.h"
33
35#include "base_wx/wxutils.h"
36#include "hugin/PreviewPanel.h"
37#include "hugin/PreviewFrame.h"
38#include "hugin/MainFrame.h"
40#include "base_wx/PanoCommand.h"
41#include "base_wx/wxcms.h"
43#include "hugin/huginApp.h"
44
45#include <math.h>
46
47typedef vigra::RGBValue<unsigned char> BRGBValue;
48
50 : pano(0), m_autoPreview(false),m_panoImgSize(1,1),
51 m_panoBitmap(0),
52 m_pano2erect(0), m_blendMode(BLEND_COPY),
53 m_state_rendering(false), m_rerender(false), m_imgsDirty(true)
54{
55}
56
58 const wxPoint& pos,
59 const wxSize& size,
60 long style,
61 const wxString& name)
62{
63 DEBUG_TRACE(" Create called *************");
64 if (! wxPanel::Create(parent, id, pos, size, style, name) ) {
65 return false;
66 }
67 DEBUG_TRACE("");
68 DEBUG_DEBUG("m_state_rendering = " << m_state_rendering);
69
70#if defined(__WXMSW__)
71 wxString cursorPath = huginApp::Get()->GetXRCPath() + "/data/cursor_cp_pick.cur";
73#else
75#endif
82
83 return true;
84}
85
86
93
94
96{
97 DEBUG_TRACE("dtor");
98 delete m_cursor;
99 pano->removeObserver(this);
100 if (m_panoBitmap) {
101 delete m_panoBitmap;
102 }
103 if (m_pano2erect) {
104 delete m_pano2erect;
105 }
106 DEBUG_TRACE("dtor end");
107}
108
110{
111 // avoid recursive calls.. don't know if they can happen at all,
112 // but they might lead to crashes.
113 bool dirty = false;
114
116
117 // check if an important options has been changed
118 if (newOpts.getHFOV() != opts.getHFOV()) {
119 DEBUG_DEBUG("HFOV changed");
120 dirty = true;
121 }
122 if (newOpts.getVFOV() != opts.getVFOV()) {
123 DEBUG_DEBUG("VFOV changed");
124 dirty = true;
125 }
126 if (newOpts.getProjection() != opts.getProjection()) {
127 DEBUG_DEBUG("projection changed");
128 dirty = true;
129 }
130
131 if (newOpts.getProjectionParameters() != opts.getProjectionParameters() ) {
132 DEBUG_DEBUG("projection parameters changed");
133 dirty = true;
134 }
135 if (newOpts.outputExposureValue != opts.outputExposureValue )
136 {
137 DEBUG_DEBUG("output exposure value changed");
138 dirty = true;
139 };
140 if (newOpts.outputRangeCompression != opts.outputRangeCompression)
141 {
142 DEBUG_DEBUG("output range compression changed");
143 dirty = true;
144 };
145
146 opts = newOpts;
147 if (dirty) {
148 // have to remap all images
150 }
151
152 if (m_autoPreview && dirty) {
153 DEBUG_DEBUG("forcing preview update");
154 ForceUpdate();
155 // resize
156 } else if(m_autoPreview && m_imgsDirty ) {
157 DEBUG_DEBUG("updating preview after image change");
159 m_imgsDirty=false;
160 }
161}
162
168
174
179
181{
182 m_autoPreview = enabled;
183 if (enabled) {
185 }
186}
187
190template <class OP>
192{
193 ExposureResponseFunctor2(double exposure, const OP & operation)
194 : op(operation), e(exposure)
195 {
196 }
197 const OP & op;
198 double e;
199
200 template <class VT>
201 typename vigra::NumericTraits<VT>::RealPromote
203 {
204 return op(v*e);
205 }
206};
207
209{
210public:
216
217 vigra::RGBValue<float> operator()(vigra::RGBValue<float> const& v) const
218 {
219 return vigra::RGBValue<float>(std::log2(m_rangeCompression * v.red() + 1) / m_logM1,
220 std::log2(m_rangeCompression * v.green() + 1) / m_logM1,
221 std::log2(m_rangeCompression * v.blue() + 1) / m_logM1
222 );
223 }
224private:
226 double m_logM1;
227};
228
230{
231 DEBUG_TRACE("");
232
233 // we can accidentally end up here recursively, because wxWidgets
234 // allows user input during redraw of the progress in the bottom
235 if (m_state_rendering) {
236 DEBUG_DEBUG("m_state_rendering == true, aborting rendering");
237 m_rerender = true;
238 return;
239 }
240
241 DEBUG_DEBUG("m_state_rendering = true");
242 m_state_rendering = true;
243 m_rerender = false;
244
245 {
246 // Even though the frame is hidden, the panel is not
247 // so check the parent instead
248 if (parentWindow) {
249 if (parentWindow->IsShown() && (! parentWindow->IsIconized())) {
250 DEBUG_INFO("Parent window shown - updating");
251 } else {
252 DEBUG_INFO("Parent window hidden - not updating");
253 m_state_rendering = false;
254 return;
255 }
256 }
257 }
259 double finalWidth = pano->getOptions().getWidth();
260 double finalHeight = pano->getOptions().getHeight();
261
262 m_panoImgSize = vigra::Diff2D(GetClientSize().GetWidth(), GetClientSize().GetHeight());
263
265 double ratioPanel = (double)m_panoImgSize.x / (double)m_panoImgSize.y;
266
267 DEBUG_DEBUG("panorama ratio: " << ratioPano << " panel ratio: " << ratioPanel);
268
269 if (ratioPano < ratioPanel) {
270 // panel is wider than pano
272 DEBUG_DEBUG("portrait: " << m_panoImgSize);
273 } else {
274 // panel is taller than pano
276 DEBUG_DEBUG("landscape: " << m_panoImgSize);
277 }
278
280 //don't use GPU for preview
281 opts.remapUsingGPU = false;
282 opts.setWidth(m_panoImgSize.x, false);
284 // always use bilinear for preview.
285
286 // reset ROI. The preview needs to draw the parts outside the ROI, too!
287 opts.setROI(vigra::Rect2D(opts.getSize()));
289
290 // create images
292 try {
293 vigra::BasicImageView<vigra::RGBValue<unsigned char> > panoImg8((vigra::RGBValue<unsigned char> *)panoImage.GetData(), panoImage.GetWidth(), panoImage.GetHeight());
294 vigra::FRGBImage panoImg(m_panoImgSize);
295 vigra::BImage alpha(m_panoImgSize);
296
297 DEBUG_DEBUG("about to stitch images, pano size: " << m_panoImgSize);
299 if (!displayedImages.empty()) {
301 DEBUG_DEBUG("HDR output merge");
302
306 destImageRange(panoImg), destImage(alpha),
308 hdrmerge);
309#ifdef DEBUG_REMAP
310{
311 vigra::ImageExportInfo exi( DEBUG_FILE_PREFIX "hugin04_preview_HDR_Reduce.tif"); \
312 vigra::exportImage(vigra::srcImageRange(panoImg), exi); \
313}
314{
315 vigra::ImageExportInfo exi(DEBUG_FILE_PREFIX "hugin04_preview_HDR_Reduce_Alpha.tif"); \
316 vigra::exportImage(vigra::srcImageRange(alpha), exi); \
317}
318#endif
319
320 // find min and max
321 vigra::FindAverageAndVariance<float> mean; // init functor
322 vigra::inspectImageIf(vigra::srcImageRange(panoImg, vigra::RGBToGrayAccessor<vigra::RGBValue<float>>()), vigra::srcImage(alpha), mean);
323 double min = std::max(mean.average()-3*sqrt(mean.variance()), 1e-6f);
324 double max = mean.average() + 3 * sqrt(mean.variance());
325
326 int mapping = wxConfigBase::Get()->Read("/ImageCache/Mapping", HUGIN_IMGCACHE_MAPPING_FLOAT);
327 vigra_ext::applyMapping(vigra::srcImageRange(panoImg), vigra::destImage(panoImg8), min, max, mapping);
328
329 } else {
330 // LDR output
331 vigra::ImageImportInfo::ICCProfile iccProfile;
332 switch (m_blendMode) {
333 case BLEND_COPY:
334 {
338 destImageRange(panoImg), destImage(alpha),
340 blender);
341 iccProfile = stitcher.iccProfile;
342 break;
343 }
344 case BLEND_DIFFERENCE:
345 {
349 destImageRange(panoImg), destImage(alpha),
351 func);
352 iccProfile = stitcher.iccProfile;
353 break;
354 }
355 }
356
357#ifdef DEBUG_REMAP
358{
359 vigra::ImageExportInfo exi( DEBUG_FILE_PREFIX "hugin04_preview_AfterRemap.tif"); \
360 vigra::exportImage(vigra::srcImageRange(panoImg), exi); \
361}
362{
363 vigra::ImageExportInfo exi(DEBUG_FILE_PREFIX "hugin04_preview_AfterRemapAlpha.tif"); \
364 vigra::exportImage(vigra::srcImageRange(alpha), exi); \
365}
366#endif
367
368 // apply default exposure and convert to 8 bit
370
371 // apply the exposure
372 double scale = 1.0/pow(2.0,opts.outputExposureValue);
373
374 vigra::omp::transformImage(srcImageRange(panoImg), destImage(panoImg),
375 vigra::functor::Arg1()*vigra::functor::Param(scale));
376
377 DEBUG_DEBUG("LDR output, with response: " << src.getResponseType());
378 if (src.getResponseType() == HuginBase::SrcPanoImage::RESPONSE_LINEAR) {
379 vigra::omp::transformImage(srcImageRange(panoImg), destImage(panoImg8),
380 vigra::functor::Arg1()*vigra::functor::Param(255));
381 } else {
383 {
385 vigra::omp::transformImage(srcImageRange(panoImg), destImage(panoImg), rangeCompression);
386 }
387 // create suitable lut for response
388 typedef std::vector<double> LUT;
389 LUT lut;
390 switch(src.getResponseType())
391 {
393 vigra_ext::EMoR::createEMoRLUT(src.getEMoRParams(), lut);
394 break;
396 lut.resize(256);
397 vigra_ext::createGammaLUT(1/src.getGamma(), lut);
398 break;
399 default:
400 vigra_fail("Unknown or unsupported response function type");
401 break;
402 }
403 // scale lut
404 for (size_t i=0; i < lut.size(); i++)
405 lut[i] = lut[i]*255;
406 typedef vigra::RGBValue<float> FRGB;
408
409 vigra::omp::transformImage(srcImageRange(panoImg), destImage(panoImg8),
410 lutf);
411 }
412 // apply color profiles
413 if (!iccProfile.empty() || huginApp::Get()->HasMonitorProfile())
414 {
415 HuginBase::Color::CorrectImage(panoImage, iccProfile, huginApp::Get()->GetMonitorProfile());
416 };
417 }
418 }
419
420#ifdef DEBUG_REMAP
421{
422 vigra::ImageExportInfo exi( DEBUG_FILE_PREFIX "hugin05_preview_final.tif"); \
423 vigra::exportImage(vigra::srcImageRange(panoImg8), exi); \
424}
425#endif
426
427
428 } catch (std::exception & e) {
429 m_state_rendering = false;
430 DEBUG_ERROR("error during stitching: " << e.what());
431 hugin_utils::HuginMessageBox(wxString::Format(_("Could not stitch preview.\nError: %s\nOne cause could be an invalid or missing image file."), wxString(e.what(), wxConvLocal)),
432 _("Hugin"), wxOK | wxICON_INFORMATION, this);
433 }
434
435
436 // update the transform for pano -> erect coordinates
437 if (m_pano2erect) delete m_pano2erect;
440 src.setHFOV(360);
441 src.setSize(vigra::Size2D(360,180));
444
445 if (m_panoBitmap) {
446 delete m_panoBitmap;
447 }
449
450
451 // always redraw
452 Refresh();
453
454 m_state_rendering = false;
455 DEBUG_DEBUG("m_state_rendering = false");
456 m_rerender = false;
457}
458
459
461{
462 if (!IsShown()){
463 return;
464 }
465 DEBUG_TRACE("");
466
467 int offsetX = 0;
468 int offsetY = 0;
469
471 if (sz.GetWidth() > m_panoImgSize.x) {
472 offsetX = (sz.GetWidth() - m_panoImgSize.x) / 2;
473 }
474 if (sz.GetHeight() > m_panoImgSize.y) {
475 offsetY = (sz.GetHeight() - m_panoImgSize.y) / 2;
476 }
477
480 dc.DrawRectangle(0, 0, offsetX, sz.GetHeight());
481 dc.DrawRectangle(offsetX, 0, sz.GetWidth(), offsetY);
482 dc.DrawRectangle(offsetX, sz.GetHeight() - offsetY,
483 sz.GetWidth(), sz.GetHeight());
484 dc.DrawRectangle(sz.GetWidth() - offsetX, offsetY,
485 sz.GetWidth(), sz.GetHeight() - offsetY);
486
487 // set a clip region to draw stuff accordingly
488 dc.DestroyClippingRegion();
489 dc.SetClippingRegion(offsetX, offsetY,
491
492 dc.SetPen(wxPen("BLACK", 1, wxPENSTYLE_SOLID));
493 dc.SetBrush(wxBrush("BLACK", wxBRUSHSTYLE_SOLID));
494 dc.DrawRectangle(offsetX, offsetY, m_panoImgSize.x, m_panoImgSize.y);
495
496
499
500
501 // draw panorama image
502 if (m_panoBitmap) {
503
504 dc.DrawBitmap(*m_panoBitmap, offsetX, offsetY);
505
506 // draw ROI
507 vigra::Size2D panoSize = pano->getOptions().getSize();
508 vigra::Rect2D panoROI = pano->getOptions().getROI();
509 if (panoROI != vigra::Rect2D(panoSize)) {
510
511 double scale = std::min(w/(double)panoSize.x, h/(double)panoSize.y);
512 vigra::Rect2D previewROI = vigra::Rect2D(panoROI.upperLeft()* scale, panoROI.lowerRight() * scale);
513 vigra::Rect2D screenROI = previewROI;
514 screenROI.moveBy(offsetX, offsetY);
515
516
517 // TODO: make areas outside ROI darker than the rest of the image
518 // overdraw areas outside the ROI with some black half transparent
519 // bitmap
520 // it seems to be quite complicated to create a half transparent black image...
521 wxImage blackImg(w,h);
522 // init alpha channel
523 if (!blackImg.HasAlpha()) {
524 blackImg.InitAlpha();
525 }
526 unsigned char * aptr = blackImg.GetAlpha();
527 unsigned char * aend = aptr + w*h;
528 for (; aptr != aend; ++aptr)
529 *aptr = 128;
531
532 // left
533 if (screenROI.left() > offsetX) {
534 dc.DestroyClippingRegion();
535 dc.SetClippingRegion(offsetX, offsetY,
536 previewROI.left(), h);
537 dc.DrawBitmap(blackBitmap, offsetX, offsetY);
538 }
539 // top
540 if (screenROI.top() > offsetY ) {
541 dc.DestroyClippingRegion();
542 dc.SetClippingRegion(screenROI.left(), offsetY,
543 previewROI.width(), previewROI.top());
544 dc.DrawBitmap(blackBitmap, offsetX, offsetY);
545 }
546 // right
547 if (screenROI.right() < offsetX + w) {
548 dc.DestroyClippingRegion();
549 dc.SetClippingRegion(screenROI.right(), offsetY,
550 w - previewROI.right(), h);
551 dc.DrawBitmap(blackBitmap, offsetX, offsetY);
552 }
553 // bottom
554 if (screenROI.bottom() < offsetY + h ) {
555 dc.DestroyClippingRegion();
556 dc.SetClippingRegion(screenROI.left(), screenROI.bottom(),
557 screenROI.width(), h - previewROI.bottom());
558 dc.DrawBitmap(blackBitmap, offsetX, offsetY);
559 }
560
561
562 // reset clipping region
563 dc.DestroyClippingRegion();
564 dc.SetClippingRegion(offsetX, offsetY,
566
567 // draw boundaries
568 dc.SetPen(wxPen("WHITE", 1, wxPENSTYLE_SOLID));
569 dc.SetLogicalFunction(wxINVERT);
570
571 DEBUG_DEBUG("ROI scale factor: " << scale << " screen ROI: " << screenROI);
572
573 dc.DrawLine(screenROI.left(),screenROI.top(),
574 screenROI.right(),screenROI.top());
575 dc.DrawLine(screenROI.right(),screenROI.top(),
576 screenROI.right(),screenROI.bottom());
577 dc.DrawLine(screenROI.right(),screenROI.bottom(),
578 screenROI.left(),screenROI.bottom());
579 dc.DrawLine(screenROI.left(),screenROI.bottom(),
580 screenROI.left(),screenROI.top());
581
582
583 }
584 }
585
586 dc.DestroyClippingRegion();
587 dc.SetClippingRegion(offsetX, offsetY,
589
590 // draw center lines over display
591 dc.SetPen(wxPen("WHITE", 1, wxPENSTYLE_SOLID));
592 dc.SetLogicalFunction(wxINVERT);
593 dc.DrawLine(offsetX + w/2, offsetY,
594 offsetX + w/2, offsetY + h);
595 dc.DrawLine(offsetX, offsetY + h/2,
596 offsetX + w, offsetY+ h/2);
597
598}
599
605
607{
608 DEBUG_TRACE("");
610 if (sz.GetWidth() != m_panoImgSize.x && sz.GetHeight() != m_panoImgSize.y) {
612 if (m_autoPreview) {
613 ForceUpdate();
614 }
615 }
616}
617
618
620{
621 DEBUG_DEBUG("mousePressLMBEvent: " << e.m_x << "x" << e.m_y);
622 double yaw, pitch;
623 mouse2erect(e.m_x, e.m_y, yaw, pitch);
624 // calculate new rotation angles.
626 rotY.SetRotationPT(DEG_TO_RAD(-yaw), 0, 0);
628 rotP.SetRotationPT(0, DEG_TO_RAD(pitch), 0);
629
630 double y,p,r;
631 Matrix3 rot = rotP * rotY;
632 rot.GetRotationPT(y,p,r);
633 y = RAD_TO_DEG(y);
634 p = RAD_TO_DEG(p);
635 r = RAD_TO_DEG(r);
636 DEBUG_DEBUG("rotation angles pitch*yaw: " << y << " " << p << " " << r);
637
639 new PanoCommand::RotatePanoCmd(*pano, y, p, r)
640 );
641 if (!m_autoPreview) {
642 ForceUpdate();
643 }
644}
645
646
648{
649 DEBUG_DEBUG("mousePressRMBEvent: " << e.m_x << "x" << e.m_y);
650 double yaw, pitch;
651 mouse2erect(e.m_x, e.m_y, yaw, pitch);
652 // theta, phi: spherical coordinates in mathworld notation.
653 double theta = DEG_TO_RAD(yaw);
654 double phi = DEG_TO_RAD(90+pitch);
655 // convert to cartesian coordinates.
656#ifdef DEBUG
657 double x = cos(theta)* sin(phi);
658#endif
659 double y = sin(theta)* sin(phi);
660 double z = cos(phi);
661 DEBUG_DEBUG("theta: " << theta << " phi: " << phi << " x y z:" << x << " " << y << " " << z);
662 double roll = RAD_TO_DEG(atan(z/y));
663
664 DEBUG_DEBUG("roll correction: " << roll);
665
667 new PanoCommand::RotatePanoCmd(*pano, 0, 0, roll)
668 );
669 if (!m_autoPreview) {
670 ForceUpdate();
671 }
672}
673
674
676{
677 double yaw, pitch;
678 mouse2erect(e.m_x, e.m_y, yaw, pitch);
679
680 parentWindow->SetStatusText(_("Left click to define new center point, right click to move point to horizon."),0);
681 parentWindow->SetStatusText(wxString::Format("%.1f %.1f", yaw, pitch), 1);
682}
683
684void PreviewPanel::mouse2erect(int xm, int ym, double &xd, double & yd)
685{
686 if (m_pano2erect) {
687 int offsetX=0, offsetY=0;
689 if (sz.GetWidth() > m_panoImgSize.x) {
690 offsetX = (sz.GetWidth() - m_panoImgSize.x) / 2;
691 }
692 if (sz.GetHeight() > m_panoImgSize.y) {
693 offsetY = (sz.GetHeight() - m_panoImgSize.y) / 2;
694 }
695 double x = xm - offsetX - m_panoImgSize.x/2;
696 double y = ym - offsetY - m_panoImgSize.y/2;
697 m_pano2erect->transform(xd, yd, x, y);
698 //DEBUG_DEBUG("pano: " << x << " " << y << " erect: " << xd << "° " << yd << "°");
699 }
700}
701
702void PreviewPanel::DrawOutline(const std::vector<hugin_utils::FDiff2D> & points, wxDC & dc, int offX, int offY)
703{
704 for (std::vector<hugin_utils::FDiff2D>::const_iterator pnt = points.begin();
705 pnt != points.end() ;
706 ++pnt)
707 {
708 vigra::Diff2D point = pnt->toDiff2D();
709 if (point.x < 0) point.x = 0;
710 if (point.y < 0) point.y = 0;
711 if (point.x >= m_panoImgSize.x)
712 point.x = m_panoImgSize.y-1;
713 if (point.y >= m_panoImgSize.y)
714 point.y = m_panoImgSize.y -1;
715 dc.DrawPoint(hugin_utils::roundi(offX + point.x), hugin_utils::roundi(offY + point.y));
716 }
717}
718
719
720IMPLEMENT_DYNAMIC_CLASS(PreviewPanel, wxPanel)
721
723 : wxXmlResourceHandler()
724{
726}
727
729{
731
732 cp->Create(m_parentAsWindow,
733 GetID(),
734 GetPosition(), GetSize(),
735 GetStyle("style"),
736 GetName());
737
738 SetupWindow( cp);
739
740 return cp;
741}
742
744{
745 return IsOfClass(node, "PreviewPanel");
746}
747
748IMPLEMENT_DYNAMIC_CLASS(PreviewPanelXmlHandler, wxXmlResourceHandler)
749
vigra::RGBValue< unsigned char > BRGBValue
Contains various routines used for stitching panoramas.
@ RESPONSE_GAMMA
a simple gamma response curve
@ RESPONSE_LINEAR
linear response
@ RESPONSE_EMOR
empirical model of response
create a panorama using the reduce operation on all overlapping pixels.
Definition Stitcher.h:690
A stitcher without seaming, just copies the images over each other.
Definition Stitcher.h:838
Holds transformations for Image -> Pano and the other way.
void createTransform(const vigra::Diff2D &srcSize, VariableMap srcVars, Lens::LensProjectionFormat srcProj, const vigra::Diff2D &destSize, PanoramaOptions::ProjectionFormat destProj, const std::vector< double > &destProjParam, double destHFOV, const vigra::Diff2D &origSrcSize)
initialize pano->image transformation
bool transform(double &x_dest, double &y_dest, double x_src, double y_src) const
excecute transform
Panorama image options.
vigra_ext::Interpolator interpolator
void setHeight(unsigned int h)
set panorama height
const std::vector< double > & getProjectionParameters() const
Get the optional projection parameters.
const vigra::Rect2D & getROI() const
void setWidth(unsigned int w, bool keepView=true)
set panorama width keep the HFOV, if keepView=true
void setROI(const vigra::Rect2D &val)
unsigned int getWidth() const
PanoramaOptions::ProjectionFormat getProjection() const
unsigned int getHeight() const
get panorama height
vigra::Size2D getSize() const
get size of output image
Model for a panorama.
Definition Panorama.h:153
const PanoramaOptions & getOptions() const
returns the options for this panorama
Definition Panorama.h:481
void addObserver(PanoramaObserver *o)
add a panorama observer.
SrcPanoImage getSrcImage(unsigned imgNr) const
get a description of a source image
bool removeObserver(PanoramaObserver *observer)
remove a panorama observer.
UIntSet getActiveImages() const
get active images
void invalidate()
invalidates all images
All variables of a source image.
void setSize(vigra::Size2D val)
Set the image size in pixels.
general : Matrix3 is a class for handling 3x3 Matrix manipulation.
Definition Matrix3.h:38
void SetRotationPT(double yaw, double pitch, double roll)
set rotation in panotools style, code adapted from Panotools-Script by Bruno Postle
Definition Matrix3.cpp:110
void GetRotationPT(double &Yaw, double &Pitch, double &Roll)
GetRotation in panotools style.
Definition Matrix3.cpp:157
void addCommand(PanoCommand *command, bool execute=true)
Adds a command to the history.
static GlobalCmdHist & getInstance()
Rotate the panorama.
The image preview frame.
virtual wxObject * DoCreateResource()
virtual bool CanHandle(wxXmlNode *node)
A preview panel that renders the pictures using the panotools library.
HuginBase::Panorama * pano
the model
SmallRemappedImageCache m_remapCache
void mouse2erect(int xm, int ym, double &xd, double &yd)
void panoramaImagesChanged(HuginBase::Panorama &pano, const HuginBase::UIntSet &imgNr)
notifies about changes to images
void Init(PreviewFrame *parent, HuginBase::Panorama *pano)
virtual ~PreviewPanel()
dtor.
BlendMode m_blendMode
PreviewPanel()
ctor.
PreviewFrame * parentWindow
wxBitmap * m_panoBitmap
void OnMouse(wxMouseEvent &e)
vigra::Diff2D m_panoImgSize
void DrawOutline(const std::vector< hugin_utils::FDiff2D > &points, wxDC &dc, int offX, int offY)
wxCursor * m_cursor
HuginBase::PTools::Transform * m_pano2erect
void panoramaChanged(HuginBase::Panorama &pano)
Notification about a Panorama change.
void DrawPreview(wxDC &dc)
void mousePressRMBEvent(wxMouseEvent &e)
void OnPaint(wxPaintEvent &event)
void OnResize(wxSizeEvent &e)
recalculate panorama to fit the panel
void SetAutoUpdate(bool enabled)
bool m_state_rendering
bool Create(wxWindow *parent, wxWindowID id=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxTAB_TRAVERSAL, const wxString &name="panel")
void SetBlendMode(BlendMode b)
HuginBase::PanoramaOptions opts
void mousePressLMBEvent(wxMouseEvent &e)
bool HasMonitorProfile() const
return true if we found a suitable monitor profile and could loading it
Definition huginApp.h:120
const wxString & GetXRCPath()
return the current xrc path
Definition huginApp.h:98
static huginApp * Get()
hack.. kind of a pseudo singleton...
Definition huginApp.cpp:651
#define HUGIN_IMGCACHE_MAPPING_FLOAT
#define RAD_TO_DEG(x)
Definition hugin_math.h:45
#define DEG_TO_RAD(x)
Definition hugin_math.h:44
#define DEBUG_ERROR(msg)
Definition utils.h:76
#define DEBUG_DEBUG(msg)
Definition utils.h:68
#define DEBUG_TRACE(msg)
Definition utils.h:67
#define DEBUG_INFO(msg)
Definition utils.h:69
void CorrectImage(wxImage &image, const vigra::ImageImportInfo::ICCProfile &iccProfile, const cmsHPROFILE &monitorProfile)
apply color correction to given image using input iccProfile and monitor profile
Definition wxcms.cpp:218
std::set< unsigned int > UIntSet
int HuginMessageBox(const wxString &message, const wxString &caption, int style, wxWindow *parent)
Definition wxutils.cpp:176
int roundi(T x)
Definition hugin_math.h:73
double round(double x)
Definition hugin_math.h:50
void transformImage(SrcImageIterator src_upperleft, SrcImageIterator src_lowerright, SrcAccessor src_acc, DestImageIterator dest_upperleft, DestAccessor dest_acc, const Functor &func)
void createEMoRLUT(const std::vector< float > &params, VECTOR &lut)
Definition emor.h:44
void createGammaLUT(double gamma, VECTOR &lut)
Definition lut.h:50
void applyMapping(vigra::triple< SrcIterator, SrcIterator, SrcAccessor > img, vigra::pair< DestIterator, DestAccessor > dest, T min, T max, int mapping)
Definition utils.h:685
include file for the hugin project
include file for the hugin project
just apply exposure and response to linear data
vigra::NumericTraits< VT >::RealPromote operator()(VT v) const
ExposureResponseFunctor2(double exposure, const OP &operation)
blend images, by simply stacking them, without soft blending or boundary calculation
Definition Stitcher.h:957
vigra::RGBValue< float > operator()(vigra::RGBValue< float > const &v) const
RangeCompression(double rangeCompression)
functor to apply a LUT to gray and color images.
Definition lut.h:119
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.
Definition threshold.h:41