Пример #1
0
int shomwarp(float *X, int W, int H, double M[9], float *x,
		int w, int h, int o)
{
	// if low order-interpolation, evaluate right away
	if (o == 0 || o == 1 || o == 2 || o == -3)
		return homwarp(X, W, H, M, x, w, h, o);

	// otherwise, pre-filtering is required
	bool r = prepare_spline(x, w, h, 1, o);
	if (!r) return 2;

	// warp the points
	for (int j = 0; j < H; j++)
	for (int i = 0; i < W; i++)
	{
		double p[2] = {i, j};
		apply_homography(p, M, p);
		p[0] += 0.5; // solve a mis-alignement convention
		p[1] += 0.5;
		float *out = X + (j*W + i);
		evaluate_spline_at(out, x, w, h, 1, o, p[0], p[1]);
	}

	return 0;
}
Пример #2
0
static void naive_affine_map_using_spline(float *y, int out_w, int out_h,
		float *x, int w, int h, int pd, double A[6], int order)
{
	float *fx = malloc(w * h * pd * sizeof*fx);
	for (int i = 0; i < w * h * pd; i++)
		fx[i] = x[i];
	bool r = prepare_spline(fx, w, h, pd, order);
	if (!r) exit(fprintf(stderr,"prepare spline failed (ord=%d)\n",order));
	//if (1) {
	//	char buf[FILENAME_MAX];
	//	snprintf(buf,FILENAME_MAX,"/tmp/prepared_spline_%d.tiff",order);
	//	iio_save_image_float_vec(buf, fx, w, h, pd);
	//}
	double invA[6]; invert_affinity(invA, A);
	for (int j = 0; j < out_h; j++)
	for (int i = 0; i < out_w; i++)
	{
		double p[2] = {i, j};
		apply_affinity(p, A, p);
		float *out = y + (j * out_w + i) * pd;
		evaluate_spline_at(out, fx, w, h, pd, order, p[0], p[1]);
	}
	free(fx);
}
Пример #3
0
/// Apply geometric transform to image.
///
/// The transformation \a map is applied to the image \a in and the result
/// stored in \a im. If \a adjustSize is \c true, \a im will be sized so that
/// it contains all the transformed rectangle, otherwise it stays at original
/// size.
///
/// The returned pair of integers is the offset of the returned image \a im
/// with respect to original image \a in. If \a adjustSize is \c false, this is
/// (0,0), otherwise the location of upper-left corner of \a im in pixel
/// coordinates of \a in.
///
/// Interpolation is done by spline. Anti-aliasing filter is optional.
///
/// \a vOut is the background value to put at pixels outside image.
std::pair<int,int> map_image(LWImage<float> in,
                             libNumerics::Homography map,
                             LWImage<float>& im,
                             int order, bool adjustSize,
                             bool antiAlias, float vOut)
{
    int w = in.w, h = in.h;
    float zoomOut = antiAlias?
        static_cast<float>( minZoomOut(map.mat(), w, h) ): 1.0f;
    const libNumerics::Homography oriMap(map);
    const int oriW=w, oriH=h;
    std::pair<int,int> offset(0,0);
    if(adjustSize) {
        offset = boundingBox(map, w, h);
        free(im.data);
        im = alloc_image<float>(w, h, in.comps);
    }
    if(zoomOut < 1.0f) {
        float zoomIn = 1.0f / zoomOut;
        // GF: added some extra space
        int wZoom=(int)std::ceil(w*zoomIn*1.5), hZoom=(int)std::ceil(h*zoomIn*1.5);
        LWImage<float> imZoom = alloc_image<float>(wZoom,hZoom,in.comps);
        libNumerics::matrix<double> mapZ(3,3);
        mapZ = 0.0;
        mapZ(0,0) = zoomIn;
        mapZ(1,1) = zoomIn;
        mapZ(2,2) = 1.0;
        map.mat() = mapZ*map.mat();
        map_image(in, map, imZoom, order, false, false, vOut);
        float sigma = 0.8f*sqrt(zoomIn*zoomIn-1.0f);
        gauss_convol(imZoom, sigma);
        map.mat() = 0.0;
        map.mat()(0,0)=zoomOut;
        map.mat()(1,1)=zoomOut;
        map.mat()(2,2)=1.0;
        in = imZoom;
    }
    LWImage<float> tmp = alloc_image(in);
    if( prepare_spline(tmp,order) ) {
        libNumerics::Homography inv = map.inverse();
        const int stepComp = im.stepComp();
        float* out = new float[im.comps];
        float* pixOut = im.data;
        for(int i = 0; i < im.h; i++)
            for(int j = 0; j < im.w; j++) {
                double x=j+offset.first, y=i+offset.second;
                inv(x,y);
                for(int k=0; k < im.comps; k++)
                    out[k] = vOut;
                interpolate_spline(tmp, order,
                                   static_cast<float>(x+.5),
								   static_cast<float>(y+.5), out);
                for(int k=0; k < im.comps; k++)
                    pixOut[k*stepComp] = out[k];
                pixOut += im.step();
            }
        delete [] out;
    }
    free(tmp.data);
    if(zoomOut < 1.0f) {
        free(in.data); // Was allocated above
        if(! is_number(vOut)) { // Put back mask
            libNumerics::Homography inv = oriMap.inverse();
            const int stepComp = im.stepComp();
            float* pixOut = im.data;
            for(int i = 0; i < im.h; i++)
                for(int j = 0; j < im.w; j++) {
                    double x=j+offset.first, y=i+offset.second;
                    inv(x,y);
                    if(x<0 || x>=oriW || y<0 || y>=oriH)
                        for(int k=0; k < im.comps; k++)
                            pixOut[k*stepComp] = NaN;
                    pixOut += im.step();
                }
        }
    }
    return offset;
}