// floating reference date, fixed market data
    SwaptionVolatilityHullWhite::SwaptionVolatilityHullWhite(const Real reversion, const Handle<YieldTermStructure>& yts, const boost::shared_ptr<SwapIndex> indexBase,
                        const Calendar& cal,
                        BusinessDayConvention bdc,
                        const std::vector<Period>& optionT,
                        const std::vector<Period>& swapT,
                        const Matrix& vols,
                        const DayCounter& dc)
    : reversion_(reversion),yts_(yts),indexBase_(indexBase),SwaptionVolatilityDiscrete(optionT, swapT, 0, cal, bdc, dc),
      volHandles_(vols.rows()),
      hwsigmas_(vols.rows(), vols.columns()),
	  volatilities_(vols.rows(), vols.columns()) {

        checkInputs(vols.rows(), vols.columns());

        // fill dummy handles to allow generic handle-based
        // computations later on
        for (Size i=0; i<vols.rows(); ++i) {
            volHandles_[i].resize(vols.columns());
            for (Size j=0; j<vols.columns(); ++j)
                volHandles_[i][j] = Handle<Quote>(boost::shared_ptr<Quote>(new
                    SimpleQuote(vols[i][j])));
        }
        interpolation_ =
            BilinearInterpolation(swapLengths_.begin(), swapLengths_.end(),
                                  optionTimes_.begin(), optionTimes_.end(),
                                  volatilities_);
		interpolationSigma_ =
			BilinearInterpolation(swapLengths_.begin(), swapLengths_.end(),
                                  optionTimes_.begin(), optionTimes_.end(),
                                  hwsigmas_);
    }
示例#2
0
 // fixed reference date, floating market data
 SwaptionVolatilityMatrix::SwaptionVolatilityMatrix(
                 const Date& refDate,
                 const Calendar& cal,
                 BusinessDayConvention bdc,
                 const std::vector<Period>& optionT,
                 const std::vector<Period>& swapT,
                 const std::vector<std::vector<Handle<Quote> > >& vols,
                 const DayCounter& dc,
                 const bool flatExtrapolation,
                 const std::vector<std::vector<Real> >& shifts)
 : SwaptionVolatilityDiscrete(optionT, swapT, refDate, cal, bdc, dc),
   volHandles_(vols), shiftValues_(shifts),
   volatilities_(vols.size(), vols.front().size()),
   shifts_(vols.size(), vols.front().size(), 0.0) {
     checkInputs(volatilities_.rows(), volatilities_.columns(),
                 shifts.size(), shifts.size() == 0 ? 0 : shifts.front().size());
     registerWithMarketData();
     if (flatExtrapolation) {
         interpolation_ =
             FlatExtrapolator2D(boost::make_shared<BilinearInterpolation>(
                 swapLengths_.begin(), swapLengths_.end(),
                 optionTimes_.begin(), optionTimes_.end(), volatilities_));
         interpolationShifts_ =
             FlatExtrapolator2D(boost::make_shared<BilinearInterpolation>(
                 swapLengths_.begin(), swapLengths_.end(),
                 optionTimes_.begin(), optionTimes_.end(), shifts_));
     } else {
         interpolation_ = BilinearInterpolation(
             swapLengths_.begin(), swapLengths_.end(), optionTimes_.begin(),
             optionTimes_.end(), volatilities_);
         interpolationShifts_ = BilinearInterpolation(
             swapLengths_.begin(), swapLengths_.end(), optionTimes_.begin(),
             optionTimes_.end(), shifts_);
     }
 }
示例#3
0
void Canny(Mat src, Mat& dst, int thres)
{
    Mat mdx, mdy;

    printf("Canny thresheold %d\n", thres);

    Sobel(src, mdx, CV_64F, 1, 0);
    Sobel(src, mdy, CV_64F, 0, 1);

    dst.create(src.rows, src.cols, CV_64F);

    int x, y;
    double dx, dy;
    double mag, orien;

    //
    // Compute edge response
    //
    for(x = 0; x < src.cols; x++)
        for(y = 0; y < src.rows; y++) {
            dx = mdx.at<double>(y, x);
            dy = mdy.at<double>(y, x);
            dst.at<double>(y, x) = hypot(dx, dy);                    // Gradient magnitude
        }

    //
    // Max supression
    //
    for(x = 0; x < src.cols; x++)
        for(y = 0; y < src.rows; y++) {
            dx = mdx.at<double>(y, x);
            dy = mdy.at<double>(y, x);
            mag = dst.at<double>(y,x);
            orien = atan2(dx, dy);                                  // Gradient direction in radians

            if(mag > thres) {
                double delta_x = cos(orien);
                double delta_y = sin(orien);
                double pixel;

                pixel = BilinearInterpolation(dst, x + delta_x, y + delta_y);           // e0 is one pixel away in the gradient direction
                if(mag > pixel) {
                   pixel = BilinearInterpolation(dst, x - delta_x, y - delta_y);        // e1 is one pixel away in the opposite direction to the gradient
                   if(mag > pixel)
                        continue;
                }
            }

            dst.at<double>(y, x) = 0;                               // Supress
        }
}
void SegmentListVIIRSM::SmoothVIIRSImage()
{

    qDebug() << "start SegmentListVIIRSM::SmoothVIIRSImage()";

    int lineimage = 0;

    QList<Segment *>::iterator segsel;
    segsel = segsselected.begin();

    SegmentVIIRSM *segmsave;

    while ( segsel != segsselected.end() )
    {
        SegmentVIIRSM *segm = (SegmentVIIRSM *)(*segsel);
        if(segsel != segsselected.begin())
            BilinearBetweenSegments(segmsave, segm);
        segmsave = segm;
        BilinearInterpolation(segm);
        //printData(segm);
        ++segsel;
        lineimage += segm->NbrOfLines;
    }

}
示例#5
0
    // fixed reference date, fixed market data
    SwaptionVolatilityMatrix::SwaptionVolatilityMatrix(
                        const Date& refDate,
                        const Calendar& cal,
                        BusinessDayConvention bdc,
                        const std::vector<Period>& optionT,
                        const std::vector<Period>& swapT,
                        const Matrix& vols,
                        const DayCounter& dc)
    : SwaptionVolatilityDiscrete(optionT, swapT, refDate, cal, bdc, dc),
      volHandles_(vols.rows()),
      volatilities_(vols.rows(), vols.columns()) {

        checkInputs(vols.rows(), vols.columns());

        // fill dummy handles to allow generic handle-based
        // computations later on
        for (Size i=0; i<vols.rows(); ++i) {
            volHandles_[i].resize(vols.columns());
            for (Size j=0; j<vols.columns(); ++j)
                volHandles_[i][j] = Handle<Quote>(boost::shared_ptr<Quote>(new
                    SimpleQuote(vols[i][j])));
        }
        interpolation_ =
            BilinearInterpolation(swapLengths_.begin(), swapLengths_.end(),
                                  optionTimes_.begin(), optionTimes_.end(),
                                  volatilities_);
    }
示例#6
0
    // fixed reference date, fixed market data
    SwaptionVolatilityMatrix::SwaptionVolatilityMatrix(
                        const Date& refDate,
                        const Calendar& cal,
                        BusinessDayConvention bdc,
                        const std::vector<Period>& optionT,
                        const std::vector<Period>& swapT,
                        const Matrix& vols,
                        const DayCounter& dc,
                        const bool flatExtrapolation,
                        const VolatilityType type,
                        const Matrix& shifts)
    : SwaptionVolatilityDiscrete(optionT, swapT, refDate, cal, bdc, dc),
      volHandles_(vols.rows()), shiftValues_(vols.rows()),
      volatilities_(vols.rows(), vols.columns()),
      shifts_(shifts.rows(), shifts.columns(), 0.0), volatilityType_(type) {

        checkInputs(vols.rows(), vols.columns(), shifts.rows(), shifts.columns());

        // fill dummy handles to allow generic handle-based
        // computations later on
        for (Size i=0; i<vols.rows(); ++i) {
            volHandles_[i].resize(vols.columns());
            shiftValues_[i].resize(vols.columns());
            for (Size j=0; j<vols.columns(); ++j) {
                volHandles_[i][j] = Handle<Quote>(boost::shared_ptr<Quote>(new
                    SimpleQuote(vols[i][j])));
                shiftValues_[i][j] = shifts.rows() > 0 ? shifts[i][j] : 0.0;
            }
        }
        if (flatExtrapolation) {
            interpolation_ =
                FlatExtrapolator2D(boost::make_shared<BilinearInterpolation>(
                    swapLengths_.begin(), swapLengths_.end(),
                    optionTimes_.begin(), optionTimes_.end(), volatilities_));
            interpolationShifts_ =
                FlatExtrapolator2D(boost::make_shared<BilinearInterpolation>(
                    swapLengths_.begin(), swapLengths_.end(),
                    optionTimes_.begin(), optionTimes_.end(), shifts_));
        } else {
            interpolation_ = BilinearInterpolation(
                swapLengths_.begin(), swapLengths_.end(), optionTimes_.begin(),
                optionTimes_.end(), volatilities_);
            interpolationShifts_ = BilinearInterpolation(
                swapLengths_.begin(), swapLengths_.end(), optionTimes_.begin(),
                optionTimes_.end(), shifts_);
        }
    }
    // floating reference date, floating market data
    SwaptionVolatilityHullWhite::SwaptionVolatilityHullWhite(const Real reversion, const Handle<YieldTermStructure>& yts, const boost::shared_ptr<SwapIndex> indexBase,
                    const Calendar& cal,
                    BusinessDayConvention bdc,
                    const std::vector<Period>& optionT,
                    const std::vector<Period>& swapT,
                    const std::vector<std::vector<Handle<Quote> > >& vols,
                    const DayCounter& dc)
    : reversion_(reversion),yts_(yts),indexBase_(indexBase),SwaptionVolatilityDiscrete(optionT, swapT, 0, cal, bdc, dc),
      volHandles_(vols),
	  hwsigmas_(vols.size(), vols.front().size()),
      volatilities_(vols.size(), vols.front().size()) {
        checkInputs(volatilities_.rows(), volatilities_.columns());
        registerWithMarketData();
        interpolation_ =
            BilinearInterpolation(swapLengths_.begin(), swapLengths_.end(),
                                  optionTimes_.begin(), optionTimes_.end(),
                                  volatilities_);
		interpolationSigma_ =
			BilinearInterpolation(swapLengths_.begin(), swapLengths_.end(),
                                  optionTimes_.begin(), optionTimes_.end(),
                                  hwsigmas_);
   }
示例#8
0
  // floating reference date, floating market data
  SwaptionVolatilityMatrix::SwaptionVolatilityMatrix(
                  const Calendar& cal,
                  BusinessDayConvention bdc,
                  const std::vector<Period>& optionT,
                  const std::vector<Period>& swapT,
                  const std::vector<std::vector<Handle<Quote> > >& vols,
                  const DayCounter& dc)
  : SwaptionVolatilityDiscrete(optionT, swapT, 0, cal, bdc, dc),
    volHandles_(vols),
    volatilities_(vols.size(), vols.front().size()) {
      checkInputs(volatilities_.rows(), volatilities_.columns());
      registerWithMarketData();
      interpolation_ =
          BilinearInterpolation(swapLengths_.begin(), swapLengths_.end(),
                                optionTimes_.begin(), optionTimes_.end(),
                                volatilities_);
 }
示例#9
0
    void SwaptionVolCube2::performCalculations() const{

        SwaptionVolatilityCube::performCalculations();
        //! set volSpreadsMatrix_ by volSpreads_ quotes
        for (Size i=0; i<nStrikes_; i++) 
            for (Size j=0; j<nOptionTenors_; j++)
                for (Size k=0; k<nSwapTenors_; k++) {
                    volSpreadsMatrix_[i][j][k] =
                        volSpreads_[j*nSwapTenors_+k][i]->value();
                }
        //! create volSpreadsInterpolator_ 
        for (Size i=0; i<nStrikes_; i++) {
            volSpreadsInterpolator_[i] = BilinearInterpolation(
                swapLengths_.begin(), swapLengths_.end(),
                optionTimes_.begin(), optionTimes_.end(),
                volSpreadsMatrix_[i]);
            volSpreadsInterpolator_[i].enableExtrapolation();
        }
    }
示例#10
0
void MainWindow::RotateImage(QImage *image, double orien)
{
    int r, c;
    QRgb pixel;
    QImage buffer;
    int w = image->width();
    int h = image->height();
    double radians = -2.0*3.141*orien/360.0;

    buffer = image->copy();

    pixel = qRgb(0, 0, 0);
    image->fill(pixel);

    for(r=0;r<h;r++)
    {
        for(c=0;c<w;c++)
        {
            double rgb[3];
            double x0, y0;
            double x1, y1;

            // Rotate around the center of the image.
            x0 = (double) (c - w/2);
            y0 = (double) (r - h/2);

            // Rotate using rotation matrix
            x1 = x0*cos(radians) - y0*sin(radians);
            y1 = x0*sin(radians) + y0*cos(radians);

            x1 += (double) (w/2);
            y1 += (double) (h/2);

            BilinearInterpolation(&buffer, x1, y1, rgb);

            image->setPixel(c, r, qRgb((int) floor(rgb[0] + 0.5), (int) floor(rgb[1] + 0.5), (int) floor(rgb[2] + 0.5)));
        }
    }

}
示例#11
0
void SegmentListOLCI::SmoothOLCIImage(bool combine)
{

    qDebug() << "start SegmentListOLCI::SmoothOLCIImage()";

    int lineimage = 0;

    QList<Segment *>::iterator segsel;
    segsel = segsselected.begin();

    SegmentOLCI *segmsave;

    while ( segsel != segsselected.end() )
    {
        SegmentOLCI *segm = (SegmentOLCI *)(*segsel);
        if(segsel != segsselected.begin())
            BilinearBetweenSegments(segmsave, segm, combine);
        segmsave = segm;
        BilinearInterpolation(segm, combine);
        ++segsel;
        lineimage += segm->NbrOfLines;
    }
}
示例#12
0
void MainWindow::FindPeaksImage(QImage *image, double thres)
{
    // First compute edge magnitude and orientation for the image with sobel operator

    int r, c, rd, cd;

    QRgb pixel;

    // Graytones first
    BlackWhiteImage(image);

    QImage buffer;

    // store pixel magnitude
    QImage magnitude = image->copy();

    // store pixel orientation
    QImage orientation = image->copy();

    int w = image->width();
    int h = image->height();

    double gx[9] = {1, 0, -1, 2, 0, -2, 1, 0, -1};
    double gy[9] = {-1, -2, -1, 0, 0, 0, 1, 2, 1};

    buffer = image->copy(-1, -1, w + 2, h + 2);

    for(r = 0; r < h; r++) {
        for(c = 0; c < w; c++) {
            double magX = 0.0;
            double magY = 0.0;

            for(rd = -1; rd <= 1; rd++) {
                for(cd = -1; cd <= 1; cd++) {
                    pixel = buffer.pixel(c + cd + 1, r + rd + 1);

                    // Get the value of the kernel
                    double weightX = gx[(rd + 1) * 3 + cd + 1];
                    double weightY = gy[(rd + 1) * 3 + cd + 1];

                    magX += weightX * (double) qRed(pixel);
                    magY += weightY * (double) qRed(pixel);
                }
            }

            magX /= 8.0;
            magY /= 8.0;

            double mag = sqrt(magX * magX + magY * magY); // magnitude
            magnitude.setPixel(c, r, qRgb(0, (int)mag, 0));

            double orien = atan2(magY, magX); // orientation

            double red = sin(orien);
            double green = cos(orien);

            orientation.setPixel(c, r, qRgb((int)red, (int)green, 0));

        }
    }

    pixel = qRgb(0, 0, 0);
    // zero out the image
    image->fill(pixel);


    // Compare edge magnitude
    for(r = 0; r < h; r++) {
        for(c = 0; c < w; c++) {
            pixel = magnitude.pixel(c, r);
            double mag0 = (double)qGreen(pixel);

            if(mag0 > thres) {
                pixel = orientation.pixel(c, r);
                double dsin = (double)qRed(pixel);
                double dcos = (double)qGreen(pixel);

                // pixel perpendicular
                double x1, y1;

                double e0[3];

                x1 = dcos + c;
                y1 = dsin + r;

                BilinearInterpolation(&magnitude, x1, y1, e0);

                // pixel perpendicular
                double x2, y2;

                double e1[3];

                x2 = -dcos + c;
                y2 = -dsin + r;

                BilinearInterpolation(&magnitude, x2, y2, e1);

                if(mag0 >= e0[1] && mag0 >= e1[1]) {
                    image->setPixel(c, r, qRgb(255, 255, 255));
                }

            }

        }
    }

}
示例#13
0
    RGBColor ImageTexture::getColor(const Point& coord)
	{
		if (i==NEAREST)
		{
			switch(bh)
			{
				float x1,y1;
				case REPEAT:
					x1 = coord.x;
					y1 = coord.y;
					if(coord.x>1)
						x1 = coord.x - (int)coord.x;
					if(coord.y>1)
						y1 = coord.y - (int)coord.y;
					if(coord.x<0)
						x1 = coord.x - floor(coord.x);
					if(coord.y<0)
						y1 = coord.y - floor(coord.y);
					x1 = x1*(image.width()-1);
					y1 = y1*(image.height()-1);
					return RGBColor(image(floor(x1+0.5),floor(y1+0.5)));

				case MIRROR:
					x1 = coord.x;
					y1 = coord.y;
					if((int)(floor(coord.x))%2==0)
						x1 = coord.x - floor(coord.x);
					else
						x1 = 1 - (coord.x - floor(coord.x));

					if((int)(floor(coord.y))%2==0)
						y1 = coord.y - floor(coord.y);
					else
						y1 = 1 - (coord.y - floor(coord.y));
					x1 = x1*(image.width()-1);
					y1 = y1*(image.height()-1);
					return RGBColor(image(floor(x1+0.5),floor(y1+0.5)));
					

				case CLAMP:
					x1 = coord.x;
					y1 = coord.y;
					if(coord.x>1)
						x1 = 1;
					if(coord.y>1)
						y1 = 1;
					if(coord.x<0)
						x1 = 0;
					if(coord.y<0)
						y1 = 0;
					x1 = x1*(image.width()-1);
					y1 = y1*(image.height()-1);
					return RGBColor(image(floor(x1+0.5),floor(y1+0.5)));

			}
		}

		if (i==BILINEAR)
		{
			Point q1,q2,q3,q4;
			float x1,y1,r_,g_,b_;
			switch(bh)
			{
				
				case REPEAT:
					
					x1 = coord.x;
					y1 = coord.y;
					if(coord.x>1)
						x1 = coord.x - (int)coord.x;
					if(coord.y>1)
						y1 = coord.y - (int)coord.y;
					if(coord.x<0)
						x1 = coord.x - floor(coord.x);
					if(coord.y<0)
						y1 = coord.y - floor(coord.y);
					x1 = x1*(image.width()-1);
					y1 = y1*(image.height()-1);

					return BilinearInterpolation(x1,y1,image, bh);

					case MIRROR:
					x1 = coord.x;
					y1 = coord.y;
					if((int)(floor(coord.x))%2==0)
						x1 = coord.x - floor(coord.x);
					else
						x1 = 1 - (coord.x - floor(coord.x));

					if((int)(floor(coord.y))%2==0)
						y1 = coord.y - floor(coord.y);
					else
						y1 = 1 - (coord.y - floor(coord.y));

					x1 = x1*(image.width()-1);
					y1 = y1*(image.height()-1);

					return BilinearInterpolation(x1,y1,image, bh);
					

				case CLAMP:
					x1 = coord.x;
					y1 = coord.y;
					if(coord.x>1)
						x1 = 1;
					if(coord.y>1)
						y1 = 1;
					if(coord.x<0)
						x1 = 0;
					if(coord.y<0)
						y1 = 0;
					x1 = x1*(image.width()-1);
					y1 = y1*(image.height()-1);
					
					return BilinearInterpolation(x1,y1,image, bh);
			}
		}

	}
示例#14
0
    RGBColor ImageTexture::getColorDY(const Point& coord)
	{
		if (i==NEAREST)
		{
			switch(bh)
			{
				float y1a, y1b ,x1;
				case REPEAT:
					y1a = coord.y - floor(coord.y);
					y1a = y1a*(image.height()-1);
					y1b = floor(y1a+0.5);
					if(y1a < y1b){
						y1a = y1b - 1;
						y1a = y1a < 0? image.height() - 1:y1a;
					} else {
						y1a = y1b;
						y1b = y1a + 1;
						y1b = y1b > image.height() - 1? y1b - image.height():y1b;
					}
					x1 = coord.x - floor(coord.x);
					x1 = x1*(image.width()-1);
					return RGBColor(image(floor(x1+0.5),y1b)) - RGBColor(image(floor(x1+0.5), y1a));

				case MIRROR:
					if((int)(floor(coord.y))%2==0){
						y1a = coord.y - floor(coord.y);
						y1a = y1a*(image.height()-1);
						y1b = floor(y1a+0.5);
						if(y1a < y1b){
							y1a = y1b - 1;
							y1a = y1a < 0? image.height() - 1:y1a;
						} else {
							y1a = y1b;
							y1b = y1a + 1;
							y1b = y1b > image.height() - 1? y1b - image.height():y1b;
						}
					}else{
						y1a = 1 - (coord.y - floor(coord.y));
						y1a = y1a*(image.height()-1);
						y1b = floor(y1a+0.5);
						if(y1a <= y1b){
							y1a = y1b;
							y1b = y1a - 1;
							y1b = y1b < 0? -y1b : y1b;
						} else {
							y1a = y1b + 1;
							y1a = y1a > image.height() - 1? image.height() - 1 : y1a;
						}
					}
					if((int)(floor(coord.x))%2==0)
						x1 = coord.x - floor(coord.x);
					else
						x1 = 1 - (coord.x - floor(coord.x));
					x1 = x1*(image.width()-1);
					return RGBColor(image(floor(x1+0.5),y1b)) - RGBColor(image(floor(x1+0.5), y1a));
					

				case CLAMP:
					if(coord.x>1)
						y1a = 1;
					if(coord.y>1)
						x1 = 1;
					if(coord.x<0)
						y1a = 0;
					if(coord.y<0)
						x1 = 0;
					y1a = y1a*(image.height()-1);
					y1b = floor(y1a+0.5);
					if(y1a < y1b){
						y1a = y1b - 1;
						y1a = y1a < 0? 0:y1a;
					} else {
						y1a = y1b;
						y1b = y1a + 1;
						y1b = y1b > image.height() - 1? image.height() - 1:y1b;
					}
					x1 = x1*(image.height()-1);
					return RGBColor(image(floor(x1+0.5),y1b)) - RGBColor(image(floor(x1+0.5),y1a));

			}
		}

		if (i==BILINEAR)
		{
			Point q1,q2,q3,q4;
			float x1,y1,r_,g_,b_,y1_f,y1_c;
			switch(bh)
			{
				
				case REPEAT:
					x1 = coord.x;
					y1 = coord.y;
					if(coord.x>1)
						x1 = coord.x - (int)coord.x;
					if(coord.y>1)
						y1 = coord.y - (int)coord.y;
					if(coord.x<0)
						x1 = coord.x - floor(coord.x);
					if(coord.y<0)
						y1 = coord.y - floor(coord.y);
					x1 = x1*(image.width()-1);
					y1 = y1*(image.height()-1);
					y1_f = floor(y1);
					y1_c = ceil(y1);
					return BilinearInterpolation(x1,y1_c,image, bh) - BilinearInterpolation(x1,y1_f,image, bh);

				case MIRROR:
					x1 = coord.x;
					y1 = coord.y;
					if((int)(floor(coord.x))%2==0)
						x1 = coord.x - floor(coord.x);
					else
						x1 = 1 - (coord.x - floor(coord.x));

					if((int)(floor(coord.y))%2==0)
						y1 = coord.y - floor(coord.y);
					else
						y1 = 1 - (coord.y - floor(coord.y));

					x1 = x1*(image.width()-1);
					y1 = y1*(image.height()-1);

					y1_f = floor(y1);
					y1_c = ceil(y1);
					return BilinearInterpolation(x1,y1_c,image, bh) - BilinearInterpolation(x1,y1_f,image, bh);

				case CLAMP:
					x1 = coord.x;
					y1 = coord.y;
					if(coord.x>1)
						x1 = 1;
					if(coord.y>1)
						y1 = 1;
					if(coord.x<0)
						x1 = 0;
					if(coord.y<0)
						y1 = 0;
					x1 = x1*(image.width()-1);
					y1 = y1*(image.height()-1);
					
					y1_f = floor(y1);
					y1_c = ceil(y1);
					return BilinearInterpolation(x1,y1_c,image, bh) - BilinearInterpolation(x1,y1_f,image, bh);
			}
		}
	}
/*******************************************************************************
Stitch together two images using the homography transformation

    image1: first input image
    image2: second input image
    hom: homography transformation (image1 -> image2)
    homInv: inverse homography transformation (image2 -> image1)
    stitchedImage: returned stitched image
*******************************************************************************/
void MainWindow::Stitch(QImage image1, QImage image2, double hom[3][3], double homInv[3][3], QImage &stitchedImage)
{
    // Width and height of stitchedImage
    int sWidth, sHeight;

	// To compute the width and height of stitchedImage, let's first get the corners of image2
	
	// Corners are like so (image2):
	//
	//    A           B
	//
	//
	//
	//    C           D
	//
	// (x, y) is for the original coordinates in image2's corners, while
	// (x_proj, y_proj) is the projected coordinates of image2's corners projected into image1

	double image2CornerA_x = 0.0;
	double image2CornerA_y = 0.0;
	double image2CornerB_x = image2.width();
	double image2CornerB_y = 0.0;
	double image2CornerC_x = 0.0;
	double image2CornerC_y = image2.height();
	double image2CornerD_x = image2.width();
	double image2CornerD_y = image2.height();

	double image2CornerA_x_proj, image2CornerA_y_proj,
		image2CornerB_x_proj, image2CornerB_y_proj,
		image2CornerC_x_proj, image2CornerC_y_proj,
		image2CornerD_x_proj, image2CornerD_y_proj;

	// Project points into image1
	Project(image2CornerA_x, image2CornerA_y, image2CornerA_x_proj, image2CornerA_y_proj, homInv);
	Project(image2CornerB_x, image2CornerB_y, image2CornerB_x_proj, image2CornerB_y_proj, homInv);
	Project(image2CornerC_x, image2CornerC_y, image2CornerC_x_proj, image2CornerC_y_proj, homInv);
	Project(image2CornerD_x, image2CornerD_y, image2CornerD_x_proj, image2CornerD_y_proj, homInv);

	// See how large we'll need to make the combined image
	sWidth = (int) ceil(max((double) image1.width(), max(image2CornerB_x_proj, image2CornerD_x_proj))
		- min(0.0, min(image2CornerA_x_proj, image2CornerC_x_proj)));
	sHeight = (int) ceil(max((double) image1.height(), max(image2CornerC_y_proj, image2CornerD_y_proj))
		- min(0.0, min(image2CornerA_y_proj, image2CornerB_y_proj)));

    stitchedImage = QImage(sWidth, sHeight, QImage::Format_RGB32);
    stitchedImage.fill(qRgb(0,0,0));

    // Copy image 1 into stitched image at offset determined by difference of dimensions
	// between it and the stitched image if image1 is to the right/below image2;
	// if image1 is to the left/above image2, then place it at 0 for the x-/y-axis
	
	int x_offset, y_offset;

	// If image2's farthest left corner is to the left of image1, give image1 an x offset
	if(min(image2CornerA_x_proj, image2CornerC_x_proj) < 0.0)
	{
		x_offset = stitchedImage.width() - image1.width();
	}
	else
	{
		x_offset = 0;
	}

	// If image2's farthest top corner is above image1, give image1 a y offset
	if(min(image2CornerA_y_proj, image2CornerB_y_proj) < 0.0)
	{
		y_offset = stitchedImage.height() - image1.height();
	}
	else
	{
		y_offset = 0;
	}
	
	for(int row = y_offset; row < image1.height() + y_offset; row++)
	{
		for(int col = x_offset; col < image1.width() + x_offset; col++)
		{
			stitchedImage.setPixel(col, row, image1.pixel(col - x_offset, row - y_offset));
		}
	}

	double stitchedImage_x_proj, stitchedImage_y_proj;

	// Place image 2 into stitched image
	for(int row = 0; row < stitchedImage.height(); row++)
	{
		for(int col = 0; col < stitchedImage.width(); col++)
		{
			// Project this point onto image2
			Project(col - x_offset, row - y_offset, stitchedImage_x_proj, stitchedImage_y_proj, hom);
			
			// If the projected point is within image2's boundaries,
			// add the pixel value to the stitched image
			if( (0.0 < stitchedImage_x_proj) &&
				(stitchedImage_x_proj < image2.width()) &&
				(0.0 < stitchedImage_y_proj) &&
				(stitchedImage_y_proj < image2.height()))
			{
				double color[3];
				BilinearInterpolation(&image2, stitchedImage_x_proj, stitchedImage_y_proj, color);
				// Modify colors to blend edges, if image1 is already drawn here
				if(stitchedImage.pixel(col, row) != qRgb(0, 0, 0))
				{
					// Weight each image equally
					color[0] = 0.5 * color[0] + 0.5 * qRed(stitchedImage.pixel(col, row));
					color[1] = 0.5 * color[1] + 0.5 * qGreen(stitchedImage.pixel(col, row));
					color[2] = 0.5 * color[2] + 0.5 * qBlue(stitchedImage.pixel(col, row));
				}
				else
				{
					// Just use the image2 colors as-is
				}
				stitchedImage.setPixel(col, row, qRgb((int) color[0], (int) color[1], (int) color[2]));
			}
		}
	}
}
示例#16
0
/*******************************************************************************
Stitch together two images using the homography transformation
    image1 - first input image
    image2 - second input image
    hom - homography transformation (image1 -> image2)
    homInv - inverse homography transformation (image2 -> image1)
    stitchedImage - returned stitched image
*******************************************************************************/
void MainWindow::Stitch(QImage image1, QImage image2, double hom[3][3], double homInv[3][3], QImage &stitchedImage)
{
    int r, c, i;
    QRgb pixel;
    int ws, hs;
    int w1 = image1.width();
    int h1 = image1.height();
    int w2 = image2.width();
    int h2 = image2.height();
    int cmin = 0;
    int cmax = w1;
    int rmin = 0;
    int rmax = h1;
    double corners[8];

    corners[0] = corners[1] = corners[3] = corners[4] = 0.0;
    corners[2] = corners[6] = (double) w2;
    corners[5] = corners[7] = (double) h2;

    // Compute ws and has by projecting four corners of image2 to image1
    for(i = 0; i < 4; i++) {
        double x, y;
        Project(corners[i * 2], corners[i * 2 + 1], x, y, homInv);
        int r = floor(y + 0.5);
        int c = floor(x + 0.5);
        cmin = cmin > c ? c : cmin;
        cmax = cmax < c ? c : cmax;
        rmin = rmin > r ? r : rmin;
        rmax = rmax < r ? r : rmax;
    }

    ws = cmax - cmin;
    hs = rmax - rmin;

    // Initialize the stitchedImage
    stitchedImage = QImage(ws, hs, QImage::Format_RGB32);
    stitchedImage.fill(qRgb(0,0,0));

    // Warp image1 and image2 to stitchedImage.
    // Copy image1 to stitchedImage
    for(r = 0; r < h1; r++) {
        for(c = 0; c < w1; c++) {
            pixel = image1.pixel(c, r);
            stitchedImage.setPixel(c - cmin, r - rmin, pixel);
        }
    }

    // Project each pixel of stitchedImage onto image2
    // bilinearInterpolate the value
    for(r = 0; r < hs; r++) {
        for(c = 0; c < ws; c++) {
            double x, y; 
            double rgb[3];
            pixel = stitchedImage.pixel(c, r);
            Project((double)(c + cmin), (double)(r + rmin), x, y, hom);
            if(BilinearInterpolation(&image2, x, y, rgb)) {
                stitchedImage.setPixel(c, r, qRgb((int) rgb[0], (int) rgb[1], (int) rgb[2]));
            }

        }
    }

}