00001
00002
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <hugin/PreviewColorPickerTool.h>
00027 #include <wx/platform.h>
00028 #include "GLPreviewFrame.h"
00029 #include <huginapp/ImageCache.h>
00030 #include <photometric/ResponseTransform.h>
00031 #include <vigra_ext/ImageTransforms.h>
00032 #include <vigra/copyimage.hxx>
00033 #include <vigra/inspectimage.hxx>
00034
00036 #define ColorPickerSize 10
00037
00038 using namespace HuginBase;
00039
00040
00041 void PreviewColorPickerTool::Activate()
00042 {
00043 helper->NotifyMe(PreviewToolHelper::MOUSE_PRESS, this);
00044 helper->SetStatusMessage(_("Click on a area which should be neutral gray / white in the final panorama."));
00045 };
00046
00047
00048 void PreviewColorPickerTool::MouseButtonEvent(wxMouseEvent &e)
00049 {
00050 if ( e.LeftDown() && helper->IsMouseOverPano())
00051 {
00052 CalcCorrection(helper->GetMousePanoPosition());
00053 if(m_count>0 && m_red!=0 && m_blue!=0)
00054 {
00055 helper->GetPreviewFrame()->UpdateGlobalWhiteBalance(m_red,m_blue);
00056 }
00057 else
00058 {
00059 wxBell();
00060 };
00061 };
00062 };
00063
00064 void PreviewColorPickerTool::CalcCorrection(hugin_utils::FDiff2D pos)
00065 {
00066 m_red=0;
00067 m_blue=0;
00068 m_count=0;
00069 PT::Panorama* pano=helper->GetPanoramaPtr();
00070 UIntSet activeImages=pano->getActiveImages();
00071 if(activeImages.size()>0)
00072 {
00073 for(UIntSet::iterator it=activeImages.begin();it!=activeImages.end();it++)
00074 {
00075
00076 HuginBase::PTools::Transform trans;
00077 trans.createTransform(pano->getImage(*it),pano->getOptions());
00078 double x;
00079 double y;
00080 if(trans.transformImgCoord(x,y,pos.x,pos.y))
00081 {
00082 vigra::Point2D imagePos(x,y);
00083 if(pano->getImage(*it).isInside(imagePos) &&
00084 pano->getImage(*it).isInside(imagePos + vigra::Point2D(-ColorPickerSize,-ColorPickerSize)) &&
00085 pano->getImage(*it).isInside(imagePos + vigra::Point2D(-ColorPickerSize, ColorPickerSize)) &&
00086 pano->getImage(*it).isInside(imagePos + vigra::Point2D( ColorPickerSize,-ColorPickerSize)) &&
00087 pano->getImage(*it).isInside(imagePos + vigra::Point2D( ColorPickerSize, ColorPickerSize))
00088 )
00089 {
00090 CalcCorrectionForImage(*it,imagePos);
00091 };
00092 };
00093 };
00094 };
00095 if(m_count>0)
00096 {
00097 m_red=m_red/m_count;
00098 m_blue=m_blue/m_count;
00099 };
00100 };
00101
00102 void PreviewColorPickerTool::CalcCorrectionForImage(unsigned int i,vigra::Point2D pos)
00103 {
00104 const SrcPanoImage & img = helper->GetPanoramaPtr()->getImage(i);
00105 ImageCache::ImageCacheRGB8Ptr cacheImage8 = ImageCache::getInstance().getImage(img.getFilename())->get8BitImage();
00106
00107
00108 vigra::BRGBImage tempImage(2*ColorPickerSize,2*ColorPickerSize);
00109 vigra::copyImage(vigra::make_triple((*cacheImage8).upperLeft() + pos + vigra::Point2D(-ColorPickerSize,-ColorPickerSize),
00110 (*cacheImage8).upperLeft() + pos + vigra::Point2D( ColorPickerSize, ColorPickerSize),
00111 vigra::BRGBImage::Accessor()),
00112 destImage(tempImage) );
00113
00114
00115 Photometric::InvResponseTransform<vigra::UInt8,double> invResponse(img);
00116 if (helper->GetPanoramaPtr()->getOptions().outputMode == PanoramaOptions::OUTPUT_LDR)
00117 {
00118
00119 std::vector<double> outLut;
00120 vigra_ext::EMoR::createEMoRLUT(helper->GetPanoramaPtr()->getImage(0).getEMoRParams(), outLut);
00121 vigra_ext::enforceMonotonicity(outLut);
00122 invResponse.setOutput(1.0/pow(2.0,helper->GetPanoramaPtr()->getOptions().outputExposureValue), outLut,
00123 255.0);
00124 }
00125 else
00126 {
00127 invResponse.setHDROutput(true,1.0/pow(2.0,helper->GetPanoramaPtr()->getOptions().outputExposureValue));
00128 }
00129 vigra::DRGBImage floatTemp(tempImage.size());
00130 vigra_ext::transformImageSpatial(srcImageRange(tempImage), destImage(floatTemp), invResponse, vigra::Diff2D(pos.x-ColorPickerSize,pos.y-ColorPickerSize));
00131
00132
00133 vigra::FindAverage<vigra::DRGBImage::PixelType> average;
00134 vigra::inspectImage(srcImageRange(floatTemp), average);
00135
00136 vigra::RGBValue<double> RGBaverage=average.average();
00137 if(RGBaverage[0]>2 && RGBaverage[0]<253 &&
00138 RGBaverage[1]>2 && RGBaverage[1]<253 &&
00139 RGBaverage[2]>2 && RGBaverage[2]<253)
00140 {
00141 m_red+=RGBaverage[0]/RGBaverage[1];
00142 m_blue+=RGBaverage[2]/RGBaverage[1];
00143 m_count++;
00144 };
00145 };