#endif
break;
case ShepardsDistortion:
- number_coeff=1; /* not used, but provide some type of return */
+ number_coeff=1; /* The power factor to use */
break;
case ArcDistortion:
number_coeff=5;
if ( number_arguments%cp_size != 0 ||
number_arguments < cp_size ) {
(void) ThrowMagickException(exception,GetMagickModule(),OptionError,
- "InvalidArgument", "%s : 'require at least %.20g CPs'",
- CommandOptionToMnemonic(MagickDistortOptions, *method), 1.0);
+ "InvalidArgument", "%s : 'requires CP's (4 numbers each)'",
+ CommandOptionToMnemonic(MagickDistortOptions, *method));
coeff=(double *) RelinquishMagickMemory(coeff);
return((double *) NULL);
}
+ /* User defined weighting power for Shepard's Method */
+ { const char *artifact=GetImageArtifact(image,"shepards:power");
+ if ( artifact != (const char *) NULL ) {
+ coeff[0]=StringToDouble(artifact,(char **) NULL) / 2.0;
+ if ( coeff[0] < MagickEpsilon ) {
+ (void) ThrowMagickException(exception,GetMagickModule(),
+ OptionError,"InvalidArgument","%s", "-define shepards:power" );
+ coeff=(double *) RelinquishMagickMemory(coeff);
+ return((double *) NULL);
+ }
+ }
+ else
+ coeff[0]=1.0; /* Default power of 2 (Inverse Squared) */
+ }
return(coeff);
}
default:
{
#define DistortResizeImageTag "Distort/Image"
- double
- distort_args[12];
-
Image
*resize_image,
*tmp_image;
RectangleInfo
crop_area;
+ double
+ distort_args[12];
+
VirtualPixelMethod
vp_save;
}
case ShepardsDistortion:
{ /* Shepards Method, or Inverse Weighted Distance for
- displacement around the destination image control points
- The input arguments are the coefficents to the function.
- This is more of a 'displacement' function rather than an
- absolute distortion function.
+ displacement around the destination image control points
+ The input arguments are the coefficents to the function.
+ This is more of a 'displacement' function rather than an
+ absolute distortion function.
+
+ Note: We can not determine derivatives using shepards method
+ so only a point sample interpolatation can be used.
*/
size_t
i;
double weight =
((double)d.x-arguments[i+2])*((double)d.x-arguments[i+2])
+ ((double)d.y-arguments[i+3])*((double)d.y-arguments[i+3]);
- if ( weight != 0 )
- weight = 1/weight;
- else
- weight = 1;
+ weight = pow(weight,coeff[0]); /* shepards power factor */
+ weight = ( weight < 1.0 ) ? 1.0 : 1.0/weight;
s.x += (arguments[ i ]-arguments[i+2])*weight;
s.y += (arguments[i+1]-arguments[i+3])*weight;
}
s.x /= denominator;
s.y /= denominator;
- s.x += d.x;
+ s.x += d.x; /* make it as relative displacement */
s.y += d.y;
-
- /* We can not determine derivatives using shepards method
- only color interpolatation, not area-resampling */
break;
}
default:
*/
sparse_method = (SparseColorMethod) distort_method;
if ( distort_method == ShepardsDistortion )
- sparse_method = method; /* return non-distiort methods to normal */
+ sparse_method = method; /* return non-distort methods to normal */
+ if ( sparse_method == InverseColorInterpolate )
+ coeff[0]=0.5; /* sqrt() the squared distance for inverse */
}
/* Verbose output */
double weight =
((double)i-arguments[ k ])*((double)i-arguments[ k ])
+ ((double)j-arguments[k+1])*((double)j-arguments[k+1]);
- if ( method == InverseColorInterpolate )
- weight = sqrt(weight); /* inverse, not inverse squared */
+ weight = pow(weight,coeff[0]); /* inverse of power factor */
weight = ( weight < 1.0 ) ? 1.0 : 1.0/weight;
if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
pixel.red += arguments[x++]*weight;