Пример #1
0
  //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();
  }
Пример #2
0
  //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();
  }