Пример #1
0
double InterpolatingImage::operator()(double x, double y, uint z) const {
    double result;
#ifdef HAVE_INTERPOL_LIBRARY
    result=InterpolatedValue((coeff_[z]),sourceImage_.xsize(),sourceImage_.ysize(),x,y,splinedegree_);
#else

    int xx=int(x);
    int XX=(int(x)+1)%sourceImage_.xsize();
    int yy=int(y);
    int YY=(int(y)+1)%sourceImage_.ysize();

    double t=(x-xx)/(XX-xx);
    double u=(y-yy)/(YY-yy);

    result=
        (1-t)*(1-u)*sourceImage_(xx,yy,z)
        +t*(1-u)*sourceImage_(XX,yy,z)
        +t*u*sourceImage_(XX,YY,z)
        +(1-t)*u*sourceImage_(xx,YY,z);

#endif
    return result;
}
Пример #2
0
/* Actually no need to modify this function, since I will only use the float
 * type here, so the roundoff I added will never take effect.
 * What I need to modify is the MRIchangeType function!
 */
MRI *MRIlinearTransformInterpBSpline(MRI *mri_src, MRI *mri_dst, MATRIX *mA,
                                     int splinedegree)
{
  int    y1, y2, y3, width, height, depth ;
  VECTOR *v_X, *v_Y ;   /* original and transformed coordinate systems */
  MATRIX *mAinv ;     /* inverse of mA */
  double   val, x1, x2, x3 ;
  MRI *mri_Bcoeff;

  mAinv = MatrixInverse(mA, NULL) ;      /* will sample from dst back to src */
  if (!mAinv)
    ErrorReturn(NULL, (ERROR_BADPARM,
                       "MRIlinearTransformBSpline: xform is singular")) ;

  if (!mri_dst) mri_dst = MRIclone(mri_src, NULL) ;
  else          MRIclear(mri_dst) ; /* set all values to zero */

  if (mri_src->type != MRI_FLOAT)
    mri_Bcoeff = MRIchangeType(mri_src, MRI_FLOAT, 0, 1.0, 1);
  else
    mri_Bcoeff = MRIcopy(mri_src, NULL);

  /* convert between a representation based on image samples */
  /* and a representation based on image B-spline coefficients */
  if (SamplesToCoefficients(mri_Bcoeff, splinedegree))
  {
    ErrorReturn(NULL, (ERROR_BADPARM, "Change of basis failed\n"));
  }

  printf("Direct B-spline Transform Finished. \n");

  width = mri_src->width ;
  height = mri_src->height ;
  depth = mri_src->depth ;
  v_X = VectorAlloc(4, MATRIX_REAL) ;  /* input (src) coordinates */
  v_Y = VectorAlloc(4, MATRIX_REAL) ;  /* transformed (dst) coordinates */

  v_Y->rptr[4][1] = 1.0f ;
  for (y3 = 0 ; y3 < mri_dst->depth ; y3++)
  {
    V3_Z(v_Y) = y3 ;
    for (y2 = 0 ; y2 < mri_dst->height ; y2++)
    {
      V3_Y(v_Y) = y2 ;
      for (y1 = 0 ; y1 < mri_dst->width ; y1++)
      {
        V3_X(v_Y) = y1 ;
        MatrixMultiply(mAinv, v_Y, v_X) ;

        x1 = V3_X(v_X) ;
        x2 = V3_Y(v_X) ;
        x3 = V3_Z(v_X) ;

        if (x1 <= -0.5 || x1 >= (width - 0.5) || x2 <= -0.5 ||
            x2 >= (height - 0.5) || x3 <= -0.5 || x3 >= (depth-0.5))
          val = 0.0;
        else
          val = InterpolatedValue(mri_Bcoeff, x1, x2, x3, splinedegree);

        switch (mri_dst->type)
        {
        case MRI_UCHAR:
          if (val <-0.5) val = -0.5;
          if (val > 254.5) val = 254.5;
          MRIvox(mri_dst,y1,y2,y3) = (BUFTYPE)nint(val+0.5) ;
          break ;
        case MRI_SHORT:
          MRISvox(mri_dst,y1,y2,y3) = (short)nint(val+0.5) ;
          break ;
        case MRI_FLOAT:
          MRIFvox(mri_dst,y1,y2,y3) = (float)(val) ;
          break ;
        case MRI_INT:
          MRIIvox(mri_dst,y1,y2,y3) = nint(val+0.5) ;
          break ;
        default:
          ErrorReturn(NULL,
                      (ERROR_UNSUPPORTED,
                       "MRIlinearTransformBSpline: unsupported dst type %d",
                       mri_dst->type)) ;
          break ;
        }
      }
    }
  }

  MatrixFree(&v_X) ;
  MatrixFree(&mAinv) ;
  MatrixFree(&v_Y) ;

  MRIfree(&mri_Bcoeff);
  return(mri_dst) ;
}
/** 
 Image translation and rotation using B-Splines.

 @param dib Input 8-bit greyscale image
 @param angle Output image rotation in degree
 @param x_shift Output image horizontal shift
 @param y_shift Output image vertical shift
 @param x_origin Output origin of the x-axis
 @param y_origin Output origin of the y-axis
 @param spline_degree Output degree of the B-spline model
 @param use_mask Whether or not to mask the image
 @return Returns the translated & rotated dib if successful, returns NULL otherwise
*/
static FIBITMAP * 
Rotate8Bit(FIBITMAP *dib, double angle, double x_shift, double y_shift, double x_origin, double y_origin, long spline_degree, BOOL use_mask) {
	double	*ImageRasterArray;
	double	p;
	double	a11, a12, a21, a22;
	double	x0, y0, x1, y1;
	long	x, y;
	long	spline;
	bool	bResult;

	int bpp = FreeImage_GetBPP(dib);
	if(bpp != 8) {
		return NULL;
	}
	
	int width = FreeImage_GetWidth(dib);
	int height = FreeImage_GetHeight(dib);
	switch(spline_degree) {
		case ROTATE_QUADRATIC:
			spline = 2L;	// Use splines of degree 2 (quadratic interpolation)
			break;
		case ROTATE_CUBIC:
			spline = 3L;	// Use splines of degree 3 (cubic interpolation)
			break;
		case ROTATE_QUARTIC:
			spline = 4L;	// Use splines of degree 4 (quartic interpolation)
			break;
		case ROTATE_QUINTIC:
			spline = 5L;	// Use splines of degree 5 (quintic interpolation)
			break;
		default:
			spline = 3L;
	}

	// allocate output image
	FIBITMAP *dst = FreeImage_Allocate(width, height, bpp);
	if(!dst)
		return NULL;
	// buid a grey scale palette
	RGBQUAD *pal = FreeImage_GetPalette(dst);
	for(int i = 0; i < 256; i++) {
		pal[i].rgbRed = pal[i].rgbGreen = pal[i].rgbBlue = (BYTE)i;
	}

	// allocate a temporary array
	ImageRasterArray = (double*)malloc(width * height * sizeof(double));
	if(!ImageRasterArray) {
		FreeImage_Unload(dst);
		return NULL;
	}
	// copy data samples
	for(y = 0; y < height; y++) {
		double *pImage = &ImageRasterArray[y*width];
		BYTE *src_bits = FreeImage_GetScanLine(dib, height-1-y);

		for(x = 0; x < width; x++) {
			pImage[x] = (double)src_bits[x];
		}
	}

	// convert between a representation based on image samples
	// and a representation based on image B-spline coefficients
	bResult = SamplesToCoefficients(ImageRasterArray, width, height, spline);
	if(!bResult) {
		FreeImage_Unload(dst);
		free(ImageRasterArray);
		return NULL;
	}

	// prepare the geometry
	angle *= PI / 180.0;
	a11 = cos(angle);
	a12 = -sin(angle);
	a21 = sin(angle);
	a22 = cos(angle);
	x0 = a11 * (x_shift + x_origin) + a12 * (y_shift + y_origin);
	y0 = a21 * (x_shift + x_origin) + a22 * (y_shift + y_origin);
	x_shift = x_origin - x0;
	y_shift = y_origin - y0;

	// visit all pixels of the output image and assign their value
	for(y = 0; y < height; y++) {
		BYTE *dst_bits = FreeImage_GetScanLine(dst, height-1-y);
		
		x0 = a12 * (double)y + x_shift;
		y0 = a22 * (double)y + y_shift;

		for(x = 0; x < width; x++) {
			x1 = x0 + a11 * (double)x;
			y1 = y0 + a21 * (double)x;
			if(use_mask) {
				if((x1 <= -0.5) || (((double)width - 0.5) <= x1) || (y1 <= -0.5) || (((double)height - 0.5) <= y1)) {
					p = 0;
				}
				else {
					p = (double)InterpolatedValue(ImageRasterArray, width, height, x1, y1, spline);
				}
			}
			else {
				p = (double)InterpolatedValue(ImageRasterArray, width, height, x1, y1, spline);
			}
			// clamp and convert to BYTE
			dst_bits[x] = (BYTE)MIN(MAX((int)0, (int)(p + 0.5)), (int)255);
		}
	}

	// free working array and return
	free(ImageRasterArray);

	return dst;
}
Пример #4
0
/*--------------------------------------------------------------------------*/
extern int		main
				(
					int		argc,
					const char
							*argv[]
				)

{ /* begin main */

	float	*ImageRasterArray, *OutputImage;
	float	*p;
	double	a11, a12, a21, a22;
	double	x0, y0, x1, y1;
	double	xOrigin, yOrigin;
	double	Angle, xShift, yShift;
	long	Width, Height;
	long	SplineDegree;
	long	x, y;
	int		Masking;
	int		Error;

	/* access data samples */
	Error = ReadByteImageRawData(&ImageRasterArray, &Width, &Height);
	if (Error) {
		printf("Failure to import image data\n");
		return(1);
	}

	/* ask for transformation parameters */
	RigidBody(&Angle, &xShift, &yShift, &xOrigin, &yOrigin, &SplineDegree, &Masking);

	/* allocate output image */
	OutputImage = (float *)malloc((size_t)(Width * Height * (long)sizeof(float)));
	if (OutputImage == (float *)NULL) {
		free(ImageRasterArray);
		printf("Allocation of output image failed\n");
		return(1);
	}

	/* convert between a representation based on image samples */
	/* and a representation based on image B-spline coefficients */
	Error = SamplesToCoefficients(ImageRasterArray, Width, Height, SplineDegree);
	if (Error) {
		free(OutputImage);
		free(ImageRasterArray);
		printf("Change of basis failed\n");
		return(1);
	}

	/* prepare the geometry */
	Angle *= PI / 180.0;
	a11 = cos(Angle);
	a12 = -sin(Angle);
	a21 = sin(Angle);
	a22 = cos(Angle);
	x0 = a11 * (xShift + xOrigin) + a12 * (yShift + yOrigin);
	y0 = a21 * (xShift + xOrigin) + a22 * (yShift + yOrigin);
	xShift = xOrigin - x0;
	yShift = yOrigin - y0;

	/* visit all pixels of the output image and assign their value */
	p = OutputImage;
	for (y = 0L; y < Height; y++) {
		x0 = a12 * (double)y + xShift;
		y0 = a22 * (double)y + yShift;
		for (x = 0L; x < Width; x++) {
			x1 = x0 + a11 * (double)x;
			y1 = y0 + a21 * (double)x;
			if (Masking) {
				if ((x1 <= -0.5) || (((double)Width - 0.5) <= x1)
					|| (y1 <= -0.5) || (((double)Height - 0.5) <= y1)) {
					*p++ = 0.0F;
				}
				else {
					*p++ = (float)InterpolatedValue(ImageRasterArray, Width, Height,
						x1, y1, SplineDegree);
				}
			}
			else {
				*p++ = (float)InterpolatedValue(ImageRasterArray, Width, Height,
					x1, y1, SplineDegree);
			}
		}
	}

	/* save output */
	Error = WriteByteImageRawData(OutputImage, Width, Height);
	if (Error) {
		free(OutputImage);
		free(ImageRasterArray);
		printf("Failure to export image data\n");
		return(1);
	}

	free(OutputImage);
	free(ImageRasterArray);
	printf("Done\n");
	return(0);
} /* end main */