27 #include "hugin_config.h"
31 #include <vigra/basicimageview.hxx>
57 : pano(0), m_autoPreview(false),m_panoImgSize(1,1),
59 m_pano2erect(0), m_blendMode(BLEND_COPY),
60 m_state_rendering(false), m_rerender(false), m_imgsDirty(true)
71 if (! wxPanel::Create(parent,
id, pos, size, style, name) ) {
77 #if defined(__WXMSW__)
79 m_cursor =
new wxCursor(cursorPath, wxBITMAP_TYPE_CUR);
81 m_cursor =
new wxCursor(wxCURSOR_CROSS);
158 DEBUG_DEBUG(
"updating preview after image change");
195 :
op(operation),
e(exposure)
202 typename vigra::NumericTraits<VT>::RealPromote
218 vigra::RGBValue<float>
operator()(vigra::RGBValue<float>
const& v)
const
237 DEBUG_DEBUG(
"m_state_rendering == true, aborting rendering");
253 DEBUG_INFO(
"Parent window hidden - not updating");
263 m_panoImgSize = vigra::Diff2D(GetClientSize().GetWidth(), GetClientSize().GetHeight());
265 double ratioPano = finalWidth / finalHeight;
268 DEBUG_DEBUG(
"panorama ratio: " << ratioPano <<
" panel ratio: " << ratioPanel);
270 if (ratioPano < ratioPanel) {
294 vigra::BasicImageView<vigra::RGBValue<unsigned char> > panoImg8((vigra::RGBValue<unsigned char> *)panoImage.GetData(), panoImage.GetWidth(), panoImage.GetHeight());
300 if (!displayedImages.empty()) {
306 stitcher.
stitch(opts, displayedImages,
312 vigra::ImageExportInfo exi( DEBUG_FILE_PREFIX
"hugin04_preview_HDR_Reduce.tif"); \
316 vigra::ImageExportInfo exi(DEBUG_FILE_PREFIX
"hugin04_preview_HDR_Reduce_Alpha.tif"); \
322 vigra::FindMinMax<float> minmax;
326 double max = minmax.max;
333 vigra::ImageImportInfo::ICCProfile iccProfile;
339 stitcher.
stitch(opts, displayedImages,
350 stitcher.
stitch(opts, displayedImages,
361 vigra::ImageExportInfo exi( DEBUG_FILE_PREFIX
"hugin04_preview_AfterRemap.tif"); \
365 vigra::ImageExportInfo exi(DEBUG_FILE_PREFIX
"hugin04_preview_AfterRemapAlpha.tif"); \
377 vigra::functor::Arg1()*vigra::functor::Param(scale));
379 DEBUG_DEBUG(
"LDR output, with response: " << src.getResponseType());
382 vigra::functor::Arg1()*vigra::functor::Param(255));
390 typedef std::vector<double> LUT;
392 switch(src.getResponseType())
402 vigra_fail(
"Unknown or unsupported response function type");
406 for (
size_t i=0; i < lut.size(); i++)
408 typedef vigra::RGBValue<float> FRGB;
424 vigra::ImageExportInfo exi( DEBUG_FILE_PREFIX
"hugin05_preview_final.tif"); \
430 }
catch (std::exception & e) {
432 DEBUG_ERROR(
"error during stitching: " << e.what());
433 wxMessageBox(wxString::Format(_(
"Could not stitch preview.\nError: %s\nOne cause could be an invalid or missing image file."), wxString(e.what(), wxConvLocal)),
439 wxOK | wxICON_INFORMATION);
448 src.
setSize(vigra::Size2D(360,180));
478 wxSize sz = GetClientSize();
486 dc.SetPen(wxPen(GetBackgroundColour(), 1, wxPENSTYLE_SOLID));
487 dc.SetBrush(wxBrush(GetBackgroundColour(), wxBRUSHSTYLE_SOLID));
488 dc.DrawRectangle(0, 0, offsetX, sz.GetHeight());
489 dc.DrawRectangle(offsetX, 0, sz.GetWidth(), offsetY);
490 dc.DrawRectangle(offsetX, sz.GetHeight() - offsetY,
491 sz.GetWidth(), sz.GetHeight());
492 dc.DrawRectangle(sz.GetWidth() - offsetX, offsetY,
493 sz.GetWidth(), sz.GetHeight() - offsetY);
496 dc.DestroyClippingRegion();
497 dc.SetClippingRegion(offsetX, offsetY,
500 dc.SetPen(wxPen(wxT(
"BLACK"), 1, wxPENSTYLE_SOLID));
501 dc.SetBrush(wxBrush(wxT(
"BLACK"), wxBRUSHSTYLE_SOLID));
517 if (panoROI != vigra::Rect2D(panoSize)) {
519 double scale =
std::min(w/(
double)panoSize.x, h/(
double)panoSize.y);
520 vigra::Rect2D previewROI = vigra::Rect2D(panoROI.upperLeft()* scale, panoROI.lowerRight() * scale);
521 vigra::Rect2D screenROI = previewROI;
522 screenROI.moveBy(offsetX, offsetY);
529 wxImage blackImg(w,h);
531 if (!blackImg.HasAlpha()) {
532 blackImg.InitAlpha();
534 unsigned char * aptr = blackImg.GetAlpha();
535 unsigned char * aend = aptr + w*
h;
536 for (; aptr != aend; ++aptr)
538 wxBitmap blackBitmap(blackImg);
541 if (screenROI.left() > offsetX) {
542 dc.DestroyClippingRegion();
543 dc.SetClippingRegion(offsetX, offsetY,
544 previewROI.left(),
h);
545 dc.DrawBitmap(blackBitmap, offsetX, offsetY);
548 if (screenROI.top() > offsetY ) {
549 dc.DestroyClippingRegion();
550 dc.SetClippingRegion(screenROI.left(), offsetY,
551 previewROI.width(), previewROI.top());
552 dc.DrawBitmap(blackBitmap, offsetX, offsetY);
555 if (screenROI.right() < offsetX + w) {
556 dc.DestroyClippingRegion();
557 dc.SetClippingRegion(screenROI.right(), offsetY,
558 w - previewROI.right(),
h);
559 dc.DrawBitmap(blackBitmap, offsetX, offsetY);
562 if (screenROI.bottom() < offsetY +
h ) {
563 dc.DestroyClippingRegion();
564 dc.SetClippingRegion(screenROI.left(), screenROI.bottom(),
565 screenROI.width(), h - previewROI.bottom());
566 dc.DrawBitmap(blackBitmap, offsetX, offsetY);
571 dc.DestroyClippingRegion();
572 dc.SetClippingRegion(offsetX, offsetY,
576 dc.SetPen(wxPen(wxT(
"WHITE"), 1, wxPENSTYLE_SOLID));
577 dc.SetLogicalFunction(wxINVERT);
579 DEBUG_DEBUG(
"ROI scale factor: " << scale <<
" screen ROI: " << screenROI);
581 dc.DrawLine(screenROI.left(),screenROI.top(),
582 screenROI.right(),screenROI.top());
583 dc.DrawLine(screenROI.right(),screenROI.top(),
584 screenROI.right(),screenROI.bottom());
585 dc.DrawLine(screenROI.right(),screenROI.bottom(),
586 screenROI.left(),screenROI.bottom());
587 dc.DrawLine(screenROI.left(),screenROI.bottom(),
588 screenROI.left(),screenROI.top());
594 dc.DestroyClippingRegion();
595 dc.SetClippingRegion(offsetX, offsetY,
599 dc.SetPen(wxPen(wxT(
"WHITE"), 1, wxPENSTYLE_SOLID));
600 dc.SetLogicalFunction(wxINVERT);
601 dc.DrawLine(offsetX + w/2, offsetY,
602 offsetX + w/2, offsetY + h);
603 dc.DrawLine(offsetX, offsetY + h/2,
604 offsetX + w, offsetY+ h/2);
617 wxSize sz = GetClientSize();
629 DEBUG_DEBUG(
"mousePressLMBEvent: " << e.m_x <<
"x" << e.m_y);
644 DEBUG_DEBUG(
"rotation angles pitch*yaw: " << y <<
" " << p <<
" " << r);
657 DEBUG_DEBUG(
"mousePressRMBEvent: " << e.m_x <<
"x" << e.m_y);
665 double x = cos(theta)* sin(phi);
667 double y = sin(theta)* sin(phi);
669 DEBUG_DEBUG(
"theta: " << theta <<
" phi: " << phi <<
" x y z:" << x <<
" " << y <<
" " << z);
688 parentWindow->SetStatusText(_(
"Left click to define new center point, right click to move point to horizon."),0);
689 parentWindow->SetStatusText(wxString::Format(wxT(
"%.1f %.1f"), yaw, pitch), 1);
695 int offsetX=0, offsetY=0;
696 wxSize sz = GetClientSize();
712 for (std::vector<hugin_utils::FDiff2D>::const_iterator pnt = points.begin();
713 pnt != points.end() ;
716 vigra::Diff2D point = pnt->toDiff2D();
717 if (point.x < 0) point.x = 0;
718 if (point.y < 0) point.y = 0;
731 : wxXmlResourceHandler()
740 cp->Create(m_parentAsWindow,
742 GetPosition(), GetSize(),
743 GetStyle(wxT(
"style")),
753 return IsOfClass(node, wxT(
"PreviewPanel"));
PreviewFrame * parentWindow
PanoramaOptions::ProjectionFormat getProjection() const
HuginBase::PanoramaOptions opts
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"))
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
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
void OnDraw(wxPaintEvent &event)
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.
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