/******************* TO DO *********************
 * warpSphericalField:
 *	INPUT:
 *		srcSh: shape (width, height, number of channels) of source image
 *		dstSh: shape of destination image
 *		f: focal length in pixels (provided on the project web page, or measured by yourself)
 *		r: rotation matrix
 *	OUTPUT:
 *		Return an image containing (u,v) coordinates for mapping pixels from
 *		spherical coordinates to planar image coordinates.
 *			Note that this is inverse warping, i.e., this routine will be
 *		actually used to map from planar coordinates to spherical coordinates.
 *
 */
CImg<float> WarpSphericalField(CShape srcSh, CShape dstSh, float f, const CTransform3x3 &r)
{
    // Set up the pixel coordinate image
    dstSh.nBands = 2;
	CImg<float> uvImg(dstSh.width, dstSh.height, 1, dstSh.nBands);   // (u,v) coordinates

    // Fill in the values
    for (int y = 0; y < dstSh.height; y++)
    {
        //float *uv = &uvImg.Pixel(0, y, 0);
        for (int x = 0; x < dstSh.width; x++)
        {
			// (x,y) is the spherical image coordinates. 
            // (xf,yf) is the spherical coordinates, e.g., xf is the angle theta
			// and yf is the angle phi

			float xf = 2*M_PI * (x - 0.5f*dstSh.width) / dstSh.width;
			float yf = M_PI * (y - 0.5f*dstSh.height) / dstSh.height;

			// (xt,yt,zt) are intermediate coordinates to which you can
			// apply the spherical correction
            float xt=0, yt=0, zt=0;
			CVector3 p;
 
			// *** BEGIN TODO ***
			// add code to apply the spherical correction, i.e.,
			// compute the Euclidean coordinates, rotate according to
			// r, and project the point to the z=1 plane at
			// (xt/zt,yt/zt,1)
			//
			// don't forget to deal with points that have negative
			// z values appropriately, or you'll have each point on
			// the z=1 plane mapping to two opposite points on the
			// sphere


			// *** END TODO ***

            // Convert back to regular pixel coordinates and store
            float xn = 0.5f*srcSh.width  + xt*f;
            float yn = 0.5f*srcSh.height + yt*f;
            uvImg(x, y, 0, 0) = xn;
			uvImg(x, y, 0, 1) = yn;
        }
    }
    return uvImg;
}
/******************* TO DO *********************
 * warpRDField:
 *	INPUT:
 *		srcSh: shape (width, height, number of channels) of source image
 *		dstSh: shape of destination image
 *		f: focal length
 *		k1, k2: radial distortion parameters
 *	OUTPUT:
 *		Return an image containing (u,v) coordinates for applying
 *		radial distortion.
 *			Note that this is inverse warping, i.e., this routine will be
 *		actually used to map from planar coordinates with radial distortion
 *		to planar coordinates without radial distortion.
 *
 */
CImg<float> WarpRDField(CShape srcSh, CShape dstSh, float f, float k1, float k2)
{
    // Set up the pixel coordinate image
    dstSh.nBands = 2;
    CImg<float> uvImg(dstSh.width, dstSh.height, 1, dstSh.nBands);   // (u,v) coordinates

    // Fill in the values
    for (int y = 0; y < dstSh.height; y++)
    {
        //float *uv = &uvImg.Pixel(0, y, 0);
        //for (int x = 0; x < dstSh.width; x++, uv += 2)
		for (int x = 0; x < dstSh.width; x++)
        {
			// (x,y) is the planar image coordinates
            // (xf,yf) is the planar coordinates

            float xf = (x - 0.5f*dstSh.width) / f;
            float yf = (y - 0.5f*dstSh.height) / f;

			// (xt,yt) are intermediate coordinates to which you can
			// apply the radial distortion
            float xt = 0;
			float yt = 0;
 
			// *** BEGIN TODO ***
			// add code to distort with radial distortion coefficients
			// k1 and k2
			float r2 = xf*xf + yf*yf;
			xt = xf / (1.0 + k1*r2 + k2*r2*r2);
			yt = yf / (1.0 + k1*r2 + k2*r2*r2);

			// *** END TODO ***

            // Convert back to regular pixel coordinates and store
            float xn = 0.5f*srcSh.width  + xt*f;
            float yn = 0.5f*srcSh.height + yt*f;

			uvImg(x, y, 0, 0) = xn;
			uvImg(x, y, 0, 1) = yn;
            /*uv[0] = xn;
            uv[1] = yn;*/
        }
    }
    return uvImg;
}
Пример #3
0
/******************* TO DO *********************
 * warpSphericalField:
 *	INPUT:
 *		srcSh: shape (width, height, number of channels) of source image
 *		dstSh: shape of destination image
 *		f: focal length in pixels (provided on the project web page, or measured by yourself)
 *		k1, k2: radial distortion parameters (ditto)
 *		r: rotation matrix
 *	OUTPUT:
 *		Return an image containing (u,v) coordinates for mapping pixels from
 *		spherical coordinates to planar image coordinates and applying
 *		radial distortion.
 *			Note that this is inverse warping, i.e., this routine will be
 *		actually used to map from planar coordinates with radial distortion
 *		to spherical coordinates without radial distortion.
 *
 */
CFloatImage WarpSphericalField(CShape srcSh, CShape dstSh, float f,
                                 float k1, float k2, const CTransform3x3 &r)
{
    // Set up the pixel coordinate image
    dstSh.nBands = 2;
    CFloatImage uvImg(dstSh);   // (u,v) coordinates

    // Fill in the values
    for (int y = 0; y < dstSh.height; y++)
    {
        float *uv = &uvImg.Pixel(0, y, 0);
        for (int x = 0; x < dstSh.width; x++, uv += 2)
        {
			// (x,y) is the spherical image coordinates. 
            // (xf,yf) is the spherical coordinates, e.g., xf is the angle theta
			// and yf is the angle phi

            float xf = (x - 0.5f*dstSh.width ) / f;
            float yf = (y - 0.5f*dstSh.height) / f;

			// (xt,yt,zt) are intermediate coordinates to which you can
			// apply the spherical correction and radial distortion
            float xt, yt, zt;
			CVector3 p;
 
			// *** BEGIN TODO ***
			// add code to apply the spherical correction, i.e.,
			// compute the Euclidean coordinates, rotate according to
			// r, and project the point to the z=1 plane at
			// (xt/zt,yt/zt,1), then distort with radial distortion
			// coefficients k1 and k2

			//Spherical warping
			float xbar = sin(xf) * cos(yf);
			float ybar = sin(yf);
			float zbar = cos(xf) * sin(yf);

			//Do radial distortion
			float rbar_power2 = xbar * xbar + ybar * ybar;
			xt = xbar / (1 + k1 * rbar_power2 + k2 * rbar_power2 * rbar_power2);
			yt = ybar / (1 + k1 * rbar_power2 + k2 * rbar_power2 * rbar_power2);
			zt = zbar;


			// *** END TODO ***

            // Convert back to regular pixel coordinates and store
            float xn = 0.5f*srcSh.width  + xt*f;
            float yn = 0.5f*srcSh.height + yt*f;
            uv[0] = xn;
            uv[1] = yn;
        }
    }
    return uvImg;
}
/******************* TO DO *********************
 * warpRDField:
 *	INPUT:
 *		srcSh: shape (width, height, number of channels) of source image
 *		dstSh: shape of destination image
 *		f: focal length
 *		k1, k2: radial distortion parameters
 *	OUTPUT:
 *		Return an image containing (u,v) coordinates for applying
 *		radial distortion.
 *			Note that this is inverse warping, i.e., this routine will be
 *		actually used to map from planar coordinates with radial distortion
 *		to planar coordinates without radial distortion.
 *
 */
CImg<float> WarpRDField(CShape srcSh, CShape dstSh, float f, float k1, float k2)
{
    // Set up the pixel coordinate image
    dstSh.nBands = 2;
    CImg<float> uvImg(dstSh.width, dstSh.height, 1, dstSh.nBands);   // (u,v) coordinates

    // Fill in the values
    for (int y = 0; y < dstSh.height; y++)
    {
        //float *uv = &uvImg.Pixel(0, y, 0);
        //for (int x = 0; x < dstSh.width; x++, uv += 2)
		for (int x = 0; x < dstSh.width; x++)
        {
			// (x,y) is the planar image coordinates
            // (xf,yf) is the planar coordinates

            float xt = (x - 0.5f*dstSh.width) / f;
            float yt = (y - 0.5f*dstSh.height) / f;
 
			// *** BEGIN TODO ***
			// add code to distort with radial distortion coefficients
			// k1 and k2
			float r = xt * xt + yt * yt;
			xt = xt * (1 + k1 * r + k2 * r * r);
			yt = yt * (1 + k1 * r + k2 * r * r);

			// *** END TODO ***

            // Convert back to regular pixel coordinates and store
            float xn = 0.5f*srcSh.width  + xt*f;
            float yn = 0.5f*srcSh.height + yt*f;
			uvImg(x, y, 0, 0) = xn;
			uvImg(x, y, 0, 1) = yn;
        }
    }
    return uvImg;
}
Пример #5
0
/******************* TO DO *********************
 * warpSphericalField:
 *	INPUT:
 *		srcSh: shape (width, height, number of channels) of source image
 *		dstSh: shape of destination image
 *		f: focal length in pixels (provided on the project web page, or measured by yourself)
 *		k1, k2: radial distortion parameters (ditto)
 *		r: rotation matrix
 *	OUTPUT:
 *		Return an image containing (u,v) coordinates for mapping pixels from
 *		spherical coordinates to planar image coordinates and applying
 *		radial distortion.
 *			Note that this is inverse warping, i.e., this routine will be
 *		actually used to map from planar coordinates with radial distortion
 *		to spherical coordinates without radial distortion.
 *
 */
CFloatImage WarpSphericalField(CShape srcSh, CShape dstSh, float f,
			       float k1, float k2, const CTransform3x3 &r)
{
    // Set up the pixel coordinate image
    dstSh.nBands = 2;
    CFloatImage uvImg(dstSh);   // (u,v) coordinates

    CVector3 p;

    p[0] = sin(0.0) * cos(0.0);
    p[1] = sin(0.0);
    p[2] = cos(0.0) * cos(0.0);

    p = r * p;

    double min_y = p[1];

    // Fill in the values
    for (int y = 0; y < dstSh.height; y++) {
		float *uv = &uvImg.Pixel(0, y, 0);
		for (int x = 0; x < dstSh.width; x++, uv += 2) {
			// (x,y) is the spherical image coordinates. 
			// (xf,yf) is the spherical coordinates, e.g., xf is the angle theta
			// and yf is the angle phi

			float xf = (float) ((x - 0.5f*dstSh.width ) / f);
			float yf = (float) ((y - 0.5f*dstSh.height) / f - min_y);

			// (xt,yt,zt) are intermediate coordinates to which you can
			// apply the spherical correction and radial distortion
			float xt, yt, zt;
			CVector3 p;

			// BEGIN TODO
			// add code to apply the spherical correction, i.e.,
			// compute the Euclidean coordinates, rotate according to
			// r, and project the point to the z=1 plane at
			// (xt/zt,yt/zt,1), then distort with radial distortion
			// coefficients k1 and k2

			//change to spherical coordinates
			p[0] = sin(xf)*cos(yf);
			p[1] = sin(yf);
			p[2] = cos(xf)*cos(yf); 

			//rotate by r
			p = r * p;
			
			//normalize to z = 1 plane
			xt = p[0]/p[2];
			yt = p[1]/p[2];

			//apply distortion
			float r = xt*xt + yt*yt;
			xt = xt*(1 + k1*r + k2*r*r);
			yt = yt*(1 + k1*r + k2*r*r);

			// END TODO
	    
			// Convert back to regular pixel coordinates and store
			float xn = 0.5f*srcSh.width  + xt*f;
			float yn = 0.5f*srcSh.height + yt*f;
			uv[0] = xn;
			uv[1] = yn;
		}
    }
    return uvImg;
}