27 #include "hugin_config.h"
31 #include <vigra/basicimageview.hxx>
50 : pano(0), m_autoPreview(false),m_panoImgSize(1,1),
52 m_pano2erect(0), m_blendMode(BLEND_COPY),
53 m_state_rendering(false), m_rerender(false), m_imgsDirty(true)
64 if (! wxPanel::Create(parent,
id, pos, size, style, name) ) {
70 #if defined(__WXMSW__)
72 m_cursor =
new wxCursor(cursorPath, wxBITMAP_TYPE_CUR);
74 m_cursor =
new wxCursor(wxCURSOR_CROSS);
157 DEBUG_DEBUG(
"updating preview after image change");
194 :
op(operation),
e(exposure)
201 typename vigra::NumericTraits<VT>::RealPromote
217 vigra::RGBValue<float>
operator()(vigra::RGBValue<float>
const& v)
const
236 DEBUG_DEBUG(
"m_state_rendering == true, aborting rendering");
252 DEBUG_INFO(
"Parent window hidden - not updating");
262 m_panoImgSize = vigra::Diff2D(GetClientSize().GetWidth(), GetClientSize().GetHeight());
264 double ratioPano = finalWidth / finalHeight;
267 DEBUG_DEBUG(
"panorama ratio: " << ratioPano <<
" panel ratio: " << ratioPanel);
269 if (ratioPano < ratioPanel) {
293 vigra::BasicImageView<vigra::RGBValue<unsigned char> > panoImg8((vigra::RGBValue<unsigned char> *)panoImage.GetData(), panoImage.GetWidth(), panoImage.GetHeight());
299 if (!displayedImages.empty()) {
305 stitcher.
stitch(opts, displayedImages,
311 vigra::ImageExportInfo exi( DEBUG_FILE_PREFIX
"hugin04_preview_HDR_Reduce.tif"); \
315 vigra::ImageExportInfo exi(DEBUG_FILE_PREFIX
"hugin04_preview_HDR_Reduce_Alpha.tif"); \
321 vigra::FindAverageAndVariance<float> mean;
323 double min =
std::max(mean.average()-3*sqrt(mean.variance()), 1e-6f);
324 double max = mean.average() + 3 * sqrt(mean.variance());
331 vigra::ImageImportInfo::ICCProfile iccProfile;
337 stitcher.
stitch(opts, displayedImages,
348 stitcher.
stitch(opts, displayedImages,
359 vigra::ImageExportInfo exi( DEBUG_FILE_PREFIX
"hugin04_preview_AfterRemap.tif"); \
363 vigra::ImageExportInfo exi(DEBUG_FILE_PREFIX
"hugin04_preview_AfterRemapAlpha.tif"); \
375 vigra::functor::Arg1()*vigra::functor::Param(scale));
377 DEBUG_DEBUG(
"LDR output, with response: " << src.getResponseType());
380 vigra::functor::Arg1()*vigra::functor::Param(255));
388 typedef std::vector<double> LUT;
390 switch(src.getResponseType())
400 vigra_fail(
"Unknown or unsupported response function type");
404 for (
size_t i=0; i < lut.size(); i++)
406 typedef vigra::RGBValue<float> FRGB;
422 vigra::ImageExportInfo exi( DEBUG_FILE_PREFIX
"hugin05_preview_final.tif"); \
428 }
catch (std::exception & e) {
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);
441 src.
setSize(vigra::Size2D(360,180));
470 wxSize sz = GetClientSize();
478 dc.SetPen(wxPen(GetBackgroundColour(), 1, wxPENSTYLE_SOLID));
479 dc.SetBrush(wxBrush(GetBackgroundColour(), wxBRUSHSTYLE_SOLID));
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);
488 dc.DestroyClippingRegion();
489 dc.SetClippingRegion(offsetX, offsetY,
492 dc.SetPen(wxPen(
"BLACK", 1, wxPENSTYLE_SOLID));
493 dc.SetBrush(wxBrush(
"BLACK", wxBRUSHSTYLE_SOLID));
509 if (panoROI != vigra::Rect2D(panoSize)) {
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);
521 wxImage blackImg(w,h);
523 if (!blackImg.HasAlpha()) {
524 blackImg.InitAlpha();
526 unsigned char * aptr = blackImg.GetAlpha();
527 unsigned char * aend = aptr + w*
h;
528 for (; aptr != aend; ++aptr)
530 wxBitmap blackBitmap(blackImg);
533 if (screenROI.left() > offsetX) {
534 dc.DestroyClippingRegion();
535 dc.SetClippingRegion(offsetX, offsetY,
536 previewROI.left(),
h);
537 dc.DrawBitmap(blackBitmap, offsetX, offsetY);
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);
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);
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);
563 dc.DestroyClippingRegion();
564 dc.SetClippingRegion(offsetX, offsetY,
568 dc.SetPen(wxPen(
"WHITE", 1, wxPENSTYLE_SOLID));
569 dc.SetLogicalFunction(wxINVERT);
571 DEBUG_DEBUG(
"ROI scale factor: " << scale <<
" screen ROI: " << screenROI);
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());
586 dc.DestroyClippingRegion();
587 dc.SetClippingRegion(offsetX, offsetY,
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);
609 wxSize sz = GetClientSize();
621 DEBUG_DEBUG(
"mousePressLMBEvent: " << e.m_x <<
"x" << e.m_y);
636 DEBUG_DEBUG(
"rotation angles pitch*yaw: " << y <<
" " << p <<
" " << r);
649 DEBUG_DEBUG(
"mousePressRMBEvent: " << e.m_x <<
"x" << e.m_y);
657 double x = cos(theta)* sin(phi);
659 double y = sin(theta)* sin(phi);
661 DEBUG_DEBUG(
"theta: " << theta <<
" phi: " << phi <<
" x y z:" << x <<
" " << y <<
" " << z);
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);
687 int offsetX=0, offsetY=0;
688 wxSize sz = GetClientSize();
704 for (std::vector<hugin_utils::FDiff2D>::const_iterator pnt = points.begin();
705 pnt != points.end() ;
708 vigra::Diff2D point = pnt->toDiff2D();
709 if (point.x < 0) point.x = 0;
710 if (point.y < 0) point.y = 0;
723 : wxXmlResourceHandler()
732 cp->Create(m_parentAsWindow,
734 GetPosition(), GetSize(),
745 return IsOfClass(node,
"PreviewPanel");
PreviewFrame * parentWindow
PanoramaOptions::ProjectionFormat getProjection() const
HuginBase::PanoramaOptions opts
double outputRangeCompression
void setHeight(unsigned int h)
set panorama height
SrcPanoImage getSrcImage(unsigned imgNr) const
get a description of a source image
bool removeObserver(PanoramaObserver *observer)
remove a panorama observer.
blend images, by simply stacking them, without soft blending or boundary calculation ...
unsigned int getHeight() const
get panorama height
create a panorama using the reduce operation on all overlapping pixels.
general : Matrix3 is a class for handling 3x3 Matrix manipulation.
virtual ~PreviewPanel()
dtor.
include file for the hugin project
Difference reduce functor.
void GetRotationPT(double &Yaw, double &Pitch, double &Roll)
GetRotation in panotools style.
vigra::pair< typename ROIImage< Image, Mask >::image_const_traverser, typename ROIImage< Image, Mask >::ImageConstAccessor > srcImage(const ROIImage< Image, Mask > &img)
void applyMapping(vigra::triple< SrcIterator, SrcIterator, SrcAccessor > img, vigra::pair< DestIterator, DestAccessor > dest, T min, T max, int mapping)
functor to apply a LUT to gray and color images.
void SetRotationPT(double yaw, double pitch, double roll)
set rotation in panotools style, code adapted from Panotools-Script by Bruno Postle ...
void GetMonitorProfile(wxString &profileName, cmsHPROFILE &profile)
static huginApp * Get()
hack.. kind of a pseudo singleton...
void panoramaImagesChanged(HuginBase::Panorama &pano, const HuginBase::UIntSet &imgNr)
notifies about changes to images
std::set< unsigned int > UIntSet
void mouse2erect(int xm, int ym, double &xd, double &yd)
void Init(PreviewFrame *parent, HuginBase::Panorama *pano)
const vigra::Rect2D & getROI() const
void mousePressLMBEvent(wxMouseEvent &e)
empirical model of response
just apply exposure and response to linear data
virtual wxObject * DoCreateResource()
void stitch(const PanoramaOptions &opts, const UIntSet &imgSet, const std::string &filename, SingleImageRemapper< ImageType, AlphaType > &remapper, FUNCTOR &reduce, const AdvancedOptions &advOptions)
void mousePressRMBEvent(wxMouseEvent &e)
HuginBase::Panorama * pano
the model
void CorrectImage(wxImage &image, const vigra::ImageImportInfo::ICCProfile &iccProfile, const cmsHPROFILE &monitorProfile)
apply color correction to given image using input iccProfile and monitor profile
void SetAutoUpdate(bool enabled)
vigra_ext::Interpolator interpolator
float pow(float a, double b)
void DrawOutline(const std::vector< hugin_utils::FDiff2D > &points, wxDC &dc, int offX, int offY)
IMPLEMENT_DYNAMIC_CLASS(wxTreeListHeaderWindow, wxWindow)
vigra::ImageExportInfo::ICCProfile iccProfile
void OnResize(wxSizeEvent &e)
recalculate panorama to fit the panel
void SetBlendMode(BlendMode b)
bool HasMonitorProfile() const
return true if we found a suitable monitor profile and could loading it
void OnMouse(wxMouseEvent &e)
static GlobalCmdHist & getInstance()
ExposureResponseFunctor2(double exposure, const OP &operation)
SmallRemappedImageCache m_remapCache
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 setROI(const vigra::Rect2D &val)
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
UIntSet getActiveImages() const
get active images
void createGammaLUT(double gamma, VECTOR &lut)
void createEMoRLUT(const std::vector< float > ¶ms, VECTOR &lut)
Contains various routines used for stitching panoramas.
void addObserver(PanoramaObserver *o)
add a panorama observer.
unsigned int getWidth() const
HuginBase::PTools::Transform * m_pano2erect
include file for the hugin project
A stitcher without seaming, just copies the images over each other.
const PanoramaOptions & getOptions() const
returns the options for this panorama
bool Create(wxWindow *parent, wxWindowID id=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxTAB_TRAVERSAL, const wxString &name="panel")
const std::vector< double > & getProjectionParameters() const
Get the optional projection parameters.
vigra::RGBValue< unsigned char > BRGBValue
a simple gamma response curve
void setSize(vigra::Size2D val)
Set the image size in pixels.
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)
#define HUGIN_IMGCACHE_MAPPING_FLOAT
virtual bool CanHandle(wxXmlNode *node)
void stitch(const PanoramaOptions &opts, const UIntSet &imgSet, vigra::triple< ImgIter, ImgIter, ImgAccessor > pano, std::pair< AlphaIter, AlphaAccessor > alpha, SingleImageRemapper< ImageType, AlphaType > &remapper, BlendFunctor &blend)
vigra::ImageImportInfo::ICCProfile iccProfile
A preview panel that renders the pictures using the panotools library.
vigra::RGBValue< float > operator()(vigra::RGBValue< float > const &v) const
void invalidate()
invalidates all images
const wxString & GetXRCPath()
return the current xrc path
All variables of a source image.
vigra::Size2D getSize() const
get size of output image
RangeCompression(double rangeCompression)
void panoramaChanged(HuginBase::Panorama &pano)
Notification about a Panorama change.
int HuginMessageBox(const wxString &message, const wxString &caption, int style, wxWindow *parent)
vigra::NumericTraits< VT >::RealPromote operator()(VT v) const
double m_rangeCompression
void DrawPreview(wxDC &dc)
void setWidth(unsigned int w, bool keepView=true)
set panorama width keep the HFOV, if keepView=true
vigra::Diff2D m_panoImgSize
double outputExposureValue
void OnPaint(wxPaintEvent &event)