//static void GradientsMergeMosaic::addToImage(imageType_t const & rImage_p,pcl_enum eType_p, weightImageType_t const & rMask_p, imageType_t &rSumImageDx_p,imageType_t &rSumImageDy_p, weightImageType_t &rCountImageDx_p, weightImageType_t &rCountImageDy_p) { int const nCols=rImage_p.Width(); int const nRows=rImage_p.Height(); int const nChannels=rImage_p.NumberOfChannels(); imageType_t dxImage, dyImage; const double zeroLimit=0.0; /// limit for weight that is considered zero TimeMessage startDx("Creating Dx"); createDxImage(rImage_p,dxImage); startDx.Stop(); TimeMessage startAddDx("Adding Dx"); // transfer useful dx pixels // FIXME this is a relatively slow loop. Think about making it faster for(int row=0;row<nRows;++row){ for(int col=0;col<nCols-1;++col){ if(rMask_p.Pixel(col,row)>zeroLimit && rMask_p.Pixel(col+1,row)>zeroLimit) { // we are inside of image realType_t weight=(rMask_p.Pixel(col,row)+rMask_p.Pixel(col+1,row))/2.0; if(eType_p==GradientsMergeMosaicType::Average){ if(rCountImageDx_p.Pixel(col,row)<=0.0){ // first foreground pixel on this location for(int channel=0;channel<nChannels;++channel){ rSumImageDx_p.Pixel(col,row,channel)=dxImage.Pixel(col,row,channel)*weight; } } else { // there have been other pixels. Create average for(int channel=0;channel<nChannels;++channel){ rSumImageDx_p.Pixel(col,row,channel)+=dxImage.Pixel(col,row,channel)*weight; } } rCountImageDx_p.Pixel(col,row)+=weight; } else { // type overlay, last gradient wins if(rCountImageDx_p.Pixel(col,row)<=0.0){ // first foreground pixel on this location for(int channel=0;channel<nChannels;++channel){ rSumImageDx_p.Pixel(col,row,channel)=dxImage.Pixel(col,row,channel); } rCountImageDx_p.Pixel(col,row)=1.0; //mark as used } else { // there have been other pixels. Blend for(int channel=0;channel<nChannels;++channel){ rSumImageDx_p.Pixel(col,row,channel)=dxImage.Pixel(col,row,channel)*weight+rSumImageDx_p.Pixel(col,row,channel)*(1.0-weight); } } } //if type } else if(rCountImageDx_p.Pixel(col,row)==0.0 && (rMask_p.Pixel(col,row)<0.0 || rMask_p.Pixel(col+1,row)<0.0)) { // we are at border of image and dont have values there. Just copy in gradient so if nothing else comes in, we have at least the border for(int channel=0;channel<nChannels;++channel){ rSumImageDx_p.Pixel(col,row,channel)=dxImage.Pixel(col,row,channel); } // add if first should win. Otherwise last will win //rCountImageDx_p.Pixel(col,row)=-1.0; // mark as background already occupied } } //for col } //for row dxImage.AllocateData(0,0); //save some memory startAddDx.Stop(); TimeMessage startDy("Creating Dy"); // transfer useful dy pixels createDyImage(rImage_p,dyImage); startDy.Stop(); TimeMessage startAddDy("Adding Dy"); for(int row=0;row<nRows-1;++row){ for(int col=0;col<nCols;++col){ if(rMask_p.Pixel(col,row)>zeroLimit && rMask_p.Pixel(col,row+1)>zeroLimit) { realType_t weight=(rMask_p.Pixel(col,row)+rMask_p.Pixel(col,row+1))/2.0; if(eType_p==GradientsMergeMosaicType::Average){ // type average and inside if(rCountImageDy_p.Pixel(col,row)<=0.0){ // first foreground pixel on this location for(int channel=0;channel<nChannels;++channel){ rSumImageDy_p.Pixel(col,row,channel)=dyImage.Pixel(col,row,channel)*weight; } } else { // we already were there. Blend for(int channel=0;channel<nChannels;++channel){ rSumImageDy_p.Pixel(col,row,channel)+=dyImage.Pixel(col,row,channel)*weight; } } rCountImageDy_p.Pixel(col,row)+=weight; } else { // type overlay and inside, last gradient wins if(rCountImageDy_p.Pixel(col,row)<=0.0){ // first foreground pixel on this location for(int channel=0;channel<nChannels;++channel){ rSumImageDy_p.Pixel(col,row,channel)=dyImage.Pixel(col,row,channel); } rCountImageDy_p.Pixel(col,row)=1.0; //mark as used } else { // we have been there, merge for(int channel=0;channel<nChannels;++channel){ rSumImageDy_p.Pixel(col,row,channel)=dyImage.Pixel(col,row,channel)*weight+rSumImageDy_p.Pixel(col,row,channel)*(1.0-weight); } } } //if type } else if(rCountImageDy_p.Pixel(col,row)==0.0 && (rMask_p.Pixel(col,row)<0.0 || rMask_p.Pixel(col,row+1)<0.0)){ // we are outside of image and dont have values there. Just copy in gradient for(int channel=0;channel<nChannels;++channel){ rSumImageDy_p.Pixel(col,row,channel)=dyImage.Pixel(col,row,channel); } // add if first should win. Otherwise last will win //rCountImageDy_p.Pixel(col,row)=-1.0; } } //for col } //for row startAddDy.Stop(); }
//static void GradientsHdrComposition::addToImage(imageType_t const & rImage_p, int imageNum_p, weightImageType_t const & rMask_p, imageType_t &rSumImageDx_p,imageType_t &rSumImageDy_p, numImageType_t &rDxImage_p, numImageType_t &rDyImage_p) { int const nCols=rImage_p.Width(); int const nRows=rImage_p.Height(); int const nChannels=rImage_p.NumberOfChannels(); Assert(nCols==rSumImageDx_p.Width()+1); Assert(nRows==rSumImageDx_p.Height()); Assert(nChannels==rSumImageDx_p.NumberOfChannels()); Assert(nCols==rSumImageDy_p.Width()); Assert(nRows==rSumImageDy_p.Height()+1); Assert(nChannels==rSumImageDy_p.NumberOfChannels()); Assert(nCols==rDxImage_p.Width()); Assert(nRows==rDxImage_p.Height()); Assert(nChannels==rDxImage_p.NumberOfChannels()); Assert(nCols==rDyImage_p.Width()); Assert(nRows==rDyImage_p.Height()); Assert(nChannels==rDyImage_p.NumberOfChannels()); imageType_t dxImage, dyImage; const double zeroLimit=0.0; /// limit for weight that is considered zero // handle Dx TimeMessage startDx("Creating Dx"); createDxImage(rImage_p,dxImage); startDx.Stop(); TimeMessage startAddDx("Adding Dx to gradients"); // transfer useful dx pixels for(int row=0;row<nRows;++row){ for(int col=0;col<nCols-1;++col){ if(rMask_p.Pixel(col,row)>zeroLimit && rMask_p.Pixel(col+1,row)>zeroLimit) { // we are inside of image, and have useful gradient there for(int channel=0;channel<nChannels;++channel){ realType_t currentVal=dxImage.Pixel(col,row,channel); realType_t sumVal=rSumImageDx_p.Pixel(col,row,channel); if(std::abs(currentVal)>std::abs(sumVal)){ rSumImageDx_p.Pixel(col,row,channel)=currentVal; rDxImage_p.Pixel(col,row,channel)=imageNum_p; } //if abs } // for chan // FIXME may need to add border handling } //if inside } //for col } //for row dxImage.AllocateData(0,0); //save some memory startAddDx.Stop(); // handle Dy just as dx TimeMessage startDy("Creating Dy"); createDyImage(rImage_p,dyImage); startDy.Stop(); TimeMessage startAddDy("Adding Dxy to gradients"); // transfer useful dy pixels for(int row=0;row<nRows-1;++row){ for(int col=0;col<nCols;++col){ if(rMask_p.Pixel(col,row)>zeroLimit && rMask_p.Pixel(col,row+1)>zeroLimit) { for(int channel=0;channel<nChannels;++channel){ // we are inside of image, and have useful gradient there realType_t currentVal=dyImage.Pixel(col,row,channel); realType_t sumVal=rSumImageDy_p.Pixel(col,row,channel); if(std::abs(currentVal)>std::abs(sumVal)){ rSumImageDy_p.Pixel(col,row,channel)=currentVal; rDyImage_p.Pixel(col,row,channel)=imageNum_p; } //if abs() } // for chan // FIXME may need to add border handling } // if inside } //for col } //for row startAddDy.Stop(); }