% The format of the SimilarityImageImage method is:
%
% Image *SimilarityImage(const Image *image,const Image *reference,
-% const MetricType metric,RectangleInfo *offset,double *similarity,
-% ExceptionInfo *exception)
+% const MetricType metric,const double similarity_threshold,
+% RectangleInfo *offset,double *similarity,ExceptionInfo *exception)
%
% A description of each parameter follows:
%
%
% o metric: the metric.
%
-% o the best match offset of the reference image within the image.
+% o similarity_threshold: minimum distortion for (sub)image match.
+%
+% o offset: the best match offset of the reference image within the image.
%
% o similarity: the computed similarity between the images.
%
}
MagickExport Image *SimilarityImage(Image *image,const Image *reference,
- const MetricType metric,RectangleInfo *offset,double *similarity_metric,
- ExceptionInfo *exception)
+ const MetricType metric,const double similarity_threshold,
+ RectangleInfo *offset,double *similarity_metric,ExceptionInfo *exception)
{
#define SimilarityImageTag "Similarity/Image"
extern MagickExport Image
*CompareImages(Image *,const Image *,const MetricType,double *,
ExceptionInfo *),
- *SimilarityImage(Image *,const Image *,const MetricType,RectangleInfo *,
- double *,ExceptionInfo *);
+ *SimilarityImage(Image *,const Image *,const MetricType,const double,
+ RectangleInfo *,double *,ExceptionInfo *);
extern MagickExport MagickBooleanType
GetImageDistortion(Image *,const Image *,const MetricType,double *,
{ "-sigmoidal-contrast", 1L, SimpleOperatorFlag, MagickFalse },
{ "+silent", 0L, NonMagickOptionFlag, MagickFalse },
{ "-silent", 1L, NonMagickOptionFlag, MagickFalse },
+ { "+similarity-threshold", 0L, NonMagickOptionFlag | ImageInfoOptionFlag, MagickFalse },
+ { "-similarity-threshold", 1L, NonMagickOptionFlag | ImageInfoOptionFlag, MagickFalse },
{ "+size", 0L, ImageInfoOptionFlag, MagickFalse },
{ "-size", 1L, ImageInfoOptionFlag, MagickFalse },
{ "+sketch", 1L, DeprecateOptionFlag, MagickTrue },
int argc,char **argv,char **metadata,ExceptionInfo *exception)
{
#define DefaultDissimilarityThreshold 0.31830988618379067154
+#define DefaultSimilarityThreshold 0.0
#define DestroyCompare() \
{ \
if (similarity_image != (Image *) NULL) \
difference_image=NewImageList();
similarity_image=NewImageList();
dissimilarity_threshold=DefaultDissimilarityThreshold;
+ similarity_threshold=DefaultSimilarityThreshold;
distortion=0.0;
format=(char *) NULL;
j=1;
ThrowCompareException(OptionError,"MissingArgument",option);
break;
}
+ if (LocaleCompare("similarity-threshold",option+1) == 0)
+ {
+ if (*option == '+')
+ break;
+ i++;
+ if (i == (ssize_t) argc)
+ ThrowCompareException(OptionError,"MissingArgument",option);
+ if (IsGeometry(argv[i]) == MagickFalse)
+ ThrowCompareInvalidArgumentException(option,argv[i]);
+ if (*option == '+')
+ similarity_threshold=DefaultSimilarityThreshold;
+ else
+ similarity_threshold=StringToDouble(argv[i],(char **) NULL);
+ break;
+ }
if (LocaleCompare("size",option+1) == 0)
{
if (*option == '+')
reconstruct_image=GetImageFromList(image,1);
if (subimage_search != MagickFalse)
{
- similarity_image=SimilarityImage(image,reconstruct_image,metric,&offset,
- &similarity_metric,exception);
+ similarity_image=SimilarityImage(image,reconstruct_image,metric,
+ similarity_threshold,&offset,&similarity_metric,exception);
if (similarity_metric > dissimilarity_threshold)
ThrowCompareException(ImageError,"ImagesTooDissimilar",image->filename);
}