Пример #1
0
/******************* TO DO 5 *********************
 * BlendImages:
 *	INPUT:
 *		ipv: list of input images and their relative positions in the mosaic
 *		blendWidth: width of the blending function
 *	OUTPUT:
 *		create & return final mosaic by blending all images
 *		and correcting for any vertical drift
 */
CByteImage BlendImages(CImagePositionV& ipv, float blendWidth)
{
    // Assume all the images are of the same shape (for now)
    CByteImage& img0 = ipv[0].img;
    CShape sh        = img0.Shape();
    int width        = sh.width;
    int height       = sh.height;
    int nBands       = sh.nBands;
    int dim[2]       = {width, height};

    // Compute the bounding box for the mosaic
    int n = ipv.size();
    float min_x = 0, min_y = 0;
    float max_x = 0, max_y = 0;
    int i;
	float dy = 0;
    for (i = 0; i < n; i++)
    {
		
		CTransform3x3 &pos = ipv[i].position;

        CVector3 corners[4];//表示图片的4个角的坐标,分别为左下,右下,左上,右上

        corners[0][0] = 0.0;
        corners[0][1] = 0.0;
        corners[0][2] = 1.0;

        corners[1][0] = width - 1;
        corners[1][1] = 0.0;
        corners[1][2] = 1.0;

        corners[2][0] = 0.0;
        corners[2][1] = height - 1;
        corners[2][2] = 1.0;

        corners[3][0] = width - 1;
        corners[3][1] = height - 1;
        corners[3][2] = 1.0;

        corners[0] = pos * corners[0];
        corners[1] = pos * corners[1];
        corners[2] = pos * corners[2];
        corners[3] = pos * corners[3];

        corners[0][0] /= corners[0][2];
        corners[0][1] /= corners[0][2];

        corners[1][0] /= corners[0][2];
        corners[1][1] /= corners[0][2];

        corners[2][0] /= corners[0][2];
        corners[2][1] /= corners[0][2];

        corners[3][0] /= corners[0][2];
        corners[3][1] /= corners[0][2];
        
		// *** BEGIN TODO #1 ***
		// add some code here to update min_x, ..., max_y
		//Use c0 and c3 to get the range of x and y.
		int iminx, iminy, imaxx, imaxy;
        ImageBoundingBox(img0, pos, iminx, iminy, imaxx, imaxy);

        if (i == 0) 
		{ 
			dy += imaxy; 
		}
        if (i == n - 1) 
		{ 
			dy -= imaxy; 
		}
		/*if (min_x > corners[0][0])
		{
			min_x = corners[0][0];
		}
		if (max_x < corners[3][0])
		{
			max_x = corners[3][0];
		}
		if (min_y > corners[0][1])
		{
			min_y = corners[0][1];
		}
		if (max_y < corners[3][1])
		{
			max_y = corners[3][1];
		}
		*/
		min_x = min(min_x, float(iminx));
        min_y = min(min_y, float(iminy));
        max_x = max(max_x, float(imaxx));
        max_y = max(max_y, float(imaxy));

		// *** END TODO #1 ***
    }

    // Create a floating point accumulation image
    CShape mShape((int)(ceil(max_x) - floor(min_x)),
                  (int)(ceil(max_y) - floor(min_y)), nBands);
    CFloatImage accumulator(mShape);
    accumulator.ClearPixels();

	double x_init, x_final;
    double y_init, y_final;

	// Add in all of the images
    for (i = 0; i < n; i++) {
        
        CTransform3x3 &M = ipv[i].position;

        CTransform3x3 M_t = CTransform3x3::Translation(-min_x, -min_y) * M;

        CByteImage& img = ipv[i].img;

        // Perform the accumulation
		AccumulateBlend(img, accumulator, M_t, blendWidth);

        if (i == 0) {
            CVector3 p;
            p[0] = 0.5 * width;
            p[1] = 0.0;
            p[2] = 1.0;

            p = M_t * p;
            x_init = p[0];
            y_init = p[1];
        } else if (i == n - 1) {
            CVector3 p;
            p[0] = 0.5 * width;
            p[1] = 0.0;
            p[2] = 1.0;

            p = M_t * p;
            x_final = p[0];
            y_final = p[1];
        }
    }



    // Normalize the results
    CByteImage compImage(mShape);
    NormalizeBlend(accumulator, compImage);
    bool debug_comp = false;
    if (debug_comp)
        WriteFile(compImage, "tmp_comp.tga");

    // Allocate the final image shape
    CShape cShape(mShape.width - width, height, nBands);
    CByteImage croppedImage(cShape);

    // Compute the affine deformation
    CTransform3x3 A = CTransform3x3();
    
	// *** BEGIN TODO #2 ***
    // fill in the right entries in A to trim the left edge and
    // to take out the vertical drift
	A[0][2] = width /2;
	A[1][0] = dy / (mShape.width - width);


	// *** END TODO #2 ***

    // Warp and crop the composite
    WarpGlobal(compImage, croppedImage, A, eWarpInterpLinear);
//	WarpGlobal(compImage, croppedImage, A, eWarpInterpNearest); //similar as linear
//	WarpGlobal(compImage, croppedImage, A, eWarpInterpCubic); //all pixels are black

    return croppedImage;
}
Пример #2
0
void
BeamContact2Dp::ComputeB(void)
// this function computes the finite element equation vectors Bn and Bs
{
    double Ka1n;
	double Kb1n;
	double Ka1g;
	double Kb1g;
	Vector a1(BC2D_NUM_DIM);
	Vector b1(BC2D_NUM_DIM);

	// initialize Bn and Bs
	mBn.Zero();
	mBs.Zero();

	// get tangent vectors
	a1 = Geta1();
	b1 = Getb1();

	// compute terms for vector Bn
    Ka1n = (mEyeS*a1)^mNormal;
	Kb1n = (mEyeS*b1)^mNormal;
	
	mBn(0) = -mShape(0)*mNormal(0);
	mBn(1) = -mShape(0)*mNormal(1);
	mBn(2) = -mShape(1)*mLength*Ka1n;
	mBn(3) = -mShape(2)*mNormal(0);
	mBn(4) = -mShape(2)*mNormal(1);
	mBn(5) = -mShape(3)*mLength*Kb1n;
	mBn(6) = mNormal(0);
	mBn(7) = mNormal(1);

	// compute terms for vector Bs
	Ka1g = (mEyeS*a1)^mg_xi;
	Kb1g = (mEyeS*b1)^mg_xi;

	mBs(0) = -mg_xi(0)*(mShape(0) + mRadius*mDshape(0));
	mBs(1) = -mg_xi(1)*(mShape(0) + mRadius*mDshape(0));
	mBs(2) = -Ka1g*mLength*(mShape(1) + mRadius*mDshape(1));
	mBs(3) = -mg_xi(0)*(mShape(2) + mRadius*mDshape(2));
	mBs(4) = -mg_xi(1)*(mShape(2) + mRadius*mDshape(2));
	mBs(5) = -Kb1g*mLength*(mShape(3) + mRadius*mDshape(3));
    mBs(6) = mg_xi(0);
	mBs(7) = mg_xi(1);

	return;
}
Пример #3
0
double
BeamContact2Dp::Project(double xi)
// this function computes the centerline projection for the current step
{
    double xi_p;
	double H1;
	double H2;
	double H3;
	double H4;
    double dH1;
	double dH2;
	double dH3;
	double dH4;
	double R;
	double DR;
	double dxi;
	Vector a1(BC2D_NUM_DIM);
    Vector b1(BC2D_NUM_DIM);
	Vector x_c_p(BC2D_NUM_DIM);
	Vector t_c(BC2D_NUM_DIM);
	Vector ddx_c(BC2D_NUM_DIM);

	// initialize to previous projection location
	xi_p = xi;

	// update end point tangents
	UpdateEndFrames();

	// set tangent vectors
	a1 = Geta1();
	b1 = Getb1();

	// Hermitian basis functions and first derivatives
	H1 = 1.0 - 3.0*xi_p*xi_p + 2.0*xi_p*xi_p*xi_p;
	H2 = xi_p - 2.0*xi_p*xi_p + xi_p*xi_p*xi_p;
	H3 = 3.0*xi_p*xi_p - 2*xi_p*xi_p*xi_p;
	H4 = -xi_p*xi_p + xi_p*xi_p*xi_p;
	dH1 = -6.0*xi_p + 6.0*xi_p*xi_p;
	dH2 = 1.0 - 4.0*xi_p + 3.0*xi_p*xi_p;
	dH3 = 6.0*xi_p - 6.0*xi_p*xi_p;
	dH4 = -2.0*xi_p + 3.0*xi_p*xi_p;

    // compute current projection coordinate and tangent
	x_c_p = mDcrd_a*H1 + a1*mLength*H2 + mDcrd_b*H3 + b1*mLength*H4;
	t_c   = mDcrd_a*dH1 + a1*mLength*dH2 + mDcrd_b*dH3 + b1*mLength*dH4;
	
	// compute initial value of residual
	R = (mDcrd_s - x_c_p)^t_c;

	// iterate to determine new value of xi
	int Gapcount = 0;
	while (fabs(R/mLength) > 1.0e-10 && Gapcount < 50) {
	
		// compute current curvature vector
		ddx_c = Get_dxc_xixi(xi_p);

		// increment projection location
		DR   = ((mDcrd_s - x_c_p)^ddx_c) - (t_c^t_c);
		dxi  = -R/DR;
		xi_p = xi_p + dxi;

		// Hermitian basis functions and first derivatives
	    H1 = 1.0 - 3.0*xi_p*xi_p + 2.0*xi_p*xi_p*xi_p;
    	H2 = xi_p - 2.0*xi_p*xi_p + xi_p*xi_p*xi_p;
    	H3 = 3.0*xi_p*xi_p - 2*xi_p*xi_p*xi_p;
    	H4 = -xi_p*xi_p + xi_p*xi_p*xi_p;
    	dH1 = -6.0*xi_p + 6.0*xi_p*xi_p;
    	dH2 = 1.0 - 4.0*xi_p + 3.0*xi_p*xi_p;
    	dH3 = 6.0*xi_p - 6.0*xi_p*xi_p;
    	dH4 = -2.0*xi_p + 3.0*xi_p*xi_p;

		// update projection coordinate and tangent
		x_c_p = mDcrd_a*H1 + a1*mLength*H2 + mDcrd_b*H3 + b1*mLength*H4;
	    t_c   = mDcrd_a*dH1 + a1*mLength*dH2 + mDcrd_b*dH3 + b1*mLength*dH4;

		// compute residual
    	R = (mDcrd_s - x_c_p)^t_c;

		Gapcount += 1;
	}

	// update normal vector for current projection
	mNormal = (mDcrd_s - x_c_p)/((mDcrd_s - x_c_p).Norm());

	// update Hermitian basis functions and derivatives
	mShape(0)  = H1;
	mShape(1)  = H2;
	mShape(2)  = H3;
	mShape(3)  = H4;
	mDshape(0) = dH1;
	mDshape(1) = dH2;
	mDshape(2) = dH3;
	mDshape(3) = dH4;

	return xi_p;
}
Пример #4
0
int
BeamContact2Dp::update(void)
// this function updates variables for an incremental step n to n+1
{
    double tensileStrength;
	Vector a1(BC2D_NUM_DIM);
    Vector b1(BC2D_NUM_DIM);
	Vector a1_n(BC2D_NUM_DIM);
    Vector b1_n(BC2D_NUM_DIM);
    Vector disp_a(3);
    Vector disp_b(3);
    Vector disp_L(BC2D_NUM_DIM);
    double rot_a;
    double rot_b;
    Vector x_c(BC2D_NUM_DIM);

	// update slave node coordinates
	mDcrd_s = mIcrd_s + theNodes[2]->getTrialDisp();

	// update nodal coordinates
	disp_a = theNodes[0]->getTrialDisp();
	disp_b = theNodes[1]->getTrialDisp();

	for (int i = 0; i < 2; i++) {
	    mDcrd_a(i) = mIcrd_a(i) + disp_a(i);
		mDcrd_b(i) = mIcrd_b(i) + disp_b(i);
	}

	// compute incremental rotation from step n to step n+1
	rot_a = disp_a(2) - mDisp_a_n(2);
	rot_b = disp_b(2) - mDisp_b_n(2);

	// get tangent vectors from last converged step
	a1_n = Geta1();
	b1_n = Getb1();

	// linear update of tangent vectors
	a1 = a1_n + rot_a*mEyeS*a1_n;
	b1 = b1_n + rot_b*mEyeS*b1_n;

	// update centerline projection coordinate
	x_c = mDcrd_a*mShape(0) + a1*mLength*mShape(1) + mDcrd_b*mShape(2) + b1*mLength*mShape(3);

	// update penetration function
	mGap = (mNormal^(mDcrd_s - x_c)) - mRadius;
	if (mGap < 0.0 && in_bounds) {
		inContact = true;
	} else {
		mGap = 0.0;
		inContact = false;
	}

	// update normal contact force
	if (was_inContact) {
		mLambda = mPenalty*mGap;
	} else {
		mLambda = 0.0;
	}

	// get tensile strength from contact material
	tensileStrength = theMaterial->getTensileStrength();

    // determine trial strain vector based on contact state
	if (inContact) {
	    Vector strain(3);
		double slip;
		Vector c1n1(2);
		Vector c2n1(2);

        // tangent at the centerline projection in step n+1
		c1n1 = mDshape(0)*mDcrd_a + mDshape(1)*mLength*ma_1 + mDshape(2)*mDcrd_b + mDshape(3)*mLength*mb_1;

		// update vector c2 for step n+1
		c2n1 = (mDcrd_s - x_c)/((mDcrd_s - x_c).Norm());
		
		// update vector c2 for step n+1
		c2n1(0) = -c1n1(1);
		c2n1(1) = c1n1(0);

		// compute the slip
		slip = mg_xi^(mDcrd_s - x_c - mrho*c2n1);

		// set the strain vector
		strain(0) = mGap;
		strain(1) = slip;
		strain(2) = -mLambda;
		
		theMaterial->setTrialStrain(strain);
	} else {
	    Vector strain(3);

        // set the strain vector
		strain(0) = mGap;
		strain(1) = 0.0;
		strain(2) = -mLambda;
		
		theMaterial->setTrialStrain(strain);
	}

	return 0;
}
Пример #5
0
void
BeamContact2Dp::setDomain(Domain *theDomain)
{
	Vector x_c(BC2D_NUM_DIM);
	
	mEye1.Zero();
	mEye1(0,0) = 1.0;
	mEye1(1,1) = 1.0;

	mEyeS.Zero();
	mEyeS(0,1) = -1.0;
	mEyeS(1,0) = 1.0;

	theNodes[0] = theDomain->getNode(mExternalNodes(0));
	theNodes[1] = theDomain->getNode(mExternalNodes(1));
	theNodes[2] = theDomain->getNode(mExternalNodes(2));

	for (int i = 0; i < 3; i++) {
        if (theNodes[i] == 0)
            return;  // don't go any further - otherwise segmentation fault
    }

	// initialize coordinate vectors
	mIcrd_a = theNodes[0]->getCrds();
	mIcrd_b = theNodes[1]->getCrds();
	mIcrd_s = theNodes[2]->getCrds();
	mDcrd_a = mIcrd_a;
	mDcrd_b = mIcrd_b;
	mDcrd_s = mIcrd_s;
	mDisp_a_n.Zero();
	mDisp_b_n.Zero();

    // length of beam element
	mLength = (mDcrd_b - mDcrd_a).Norm();

	// initialize tangent vectors at beam nodes
	ma_1 = (mDcrd_b - mDcrd_a)/mLength;
	mb_1 = ma_1;

	// perform projection of slave node to beam centerline
	mXi = ((mDcrd_b - mDcrd_s)^(mDcrd_b - mDcrd_a))/mLength;  // initial assumption
	mXi = Project(mXi);                                       // actual location

	// update contact state based on projection
	in_bounds = ((mXi > 0.000) && (mXi < 1.000));
	inContact = (was_inContact && in_bounds);

	// centerline projection coordinate
	x_c = mDcrd_a*mShape(0) + ma_1*mLength*mShape(1) + mDcrd_b*mShape(2) + mb_1*mLength*mShape(3);

	// update surface tangent vector, g_xi
	UpdateBase(mXi);

	// adjust cohesion force
	theMaterial->ScaleCohesion(mLength);
	theMaterial->ScaleTensileStrength(mLength);

	// compute vectors Bn and Bs
	ComputeB();

	// call the base class method
	this->DomainComponent::setDomain(theDomain);
}
Пример #6
0
/******************* TO DO 5 *********************
* BlendImages:
*	INPUT:
*		ipv: list of input images and their relative positions in the mosaic
*		blendWidth: width of the blending function
*	OUTPUT:
*		create & return final mosaic by blending all images
*		and correcting for any vertical drift
*/
CByteImage BlendImages(CImagePositionV& ipv, float blendWidth)
{
    // Assume all the images are of the same shape (for now)
    CByteImage& img0 = ipv[0].img;
    CShape sh        = img0.Shape();
    int width        = sh.width;
    int height       = sh.height;
    int nBands       = sh.nBands;
    // int dim[2]       = {width, height};

    int n = ipv.size();
    if (n == 0) return CByteImage(0,0,1);

    bool is360 = false;

    // Hack to detect if this is a 360 panorama
    if (ipv[0].imgName == ipv[n-1].imgName)
        is360 = true;

    // Compute the bounding box for the mosaic
    float min_x = FLT_MAX, min_y = FLT_MAX;
    float max_x = 0, max_y = 0;
    int i;
    for (i = 0; i < n; i++)
    {
        CTransform3x3 &T = ipv[i].position;

        // BEGIN TODO
        // add some code here to update min_x, ..., max_y
printf("TODO: %s:%d\n", __FILE__, __LINE__); 

        // END TODO
    }

    // Create a floating point accumulation image
    CShape mShape((int)(ceil(max_x) - floor(min_x)),
        (int)(ceil(max_y) - floor(min_y)), nBands + 1);
    CFloatImage accumulator(mShape);
    accumulator.ClearPixels();

    double x_init, x_final;
    double y_init, y_final;

    // Add in all of the images
    for (i = 0; i < n; i++) {
        // Compute the sub-image involved
        CTransform3x3 &M = ipv[i].position;
        CTransform3x3 M_t = CTransform3x3::Translation(-min_x, -min_y) * M;
        CByteImage& img = ipv[i].img;

        // Perform the accumulation
        AccumulateBlend(img, accumulator, M_t, blendWidth);

        if (i == 0) {
            CVector3 p;
            p[0] = 0.5 * width;
            p[1] = 0.0;
            p[2] = 1.0;

            p = M_t * p;
            x_init = p[0];
            y_init = p[1];
        } else if (i == n - 1) {
            CVector3 p;
            p[0] = 0.5 * width;
            p[1] = 0.0;
            p[2] = 1.0;

            p = M_t * p;
            x_final = p[0];
            y_final = p[1];
        }
    }

    // Normalize the results
    mShape = CShape((int)(ceil(max_x) - floor(min_x)),
        (int)(ceil(max_y) - floor(min_y)), nBands);

    CByteImage compImage(mShape);
    NormalizeBlend(accumulator, compImage);
    bool debug_comp = false;
    if (debug_comp)
        WriteFile(compImage, "tmp_comp.tga");

    // Allocate the final image shape
    int outputWidth = 0;
    if (is360) {
        outputWidth = mShape.width - width;
    } else {
        outputWidth = mShape.width;
    }

    CShape cShape(outputWidth, mShape.height, nBands);

    CByteImage croppedImage(cShape);

    // Compute the affine transformation
    CTransform3x3 A = CTransform3x3(); // identify transform to initialize

    // BEGIN TODO
    // fill in appropriate entries in A to trim the left edge and
    // to take out the vertical drift if this is a 360 panorama
    // (i.e. is360 is true)
printf("TODO: %s:%d\n", __FILE__, __LINE__); 

    // END TODO

    // Warp and crop the composite
    WarpGlobal(compImage, croppedImage, A, eWarpInterpLinear);

    return croppedImage;
}