]> granicus.if.org Git - imagemagick/commitdiff
(no commit message)
authorcristy <urban-warrior@git.imagemagick.org>
Fri, 26 Nov 2010 21:56:11 +0000 (21:56 +0000)
committercristy <urban-warrior@git.imagemagick.org>
Fri, 26 Nov 2010 21:56:11 +0000 (21:56 +0000)
magick/compare.c

index a9f7293c4a924eea01d06d2dbe1a720ecea50aae..6b3a062b7dc53448465888483b24df7d9004477c 100644 (file)
@@ -64,6 +64,7 @@
 #include "magick/resource_.h"
 #include "magick/string_.h"
 #include "magick/statistic.h"
+#include "magick/transform.h"
 #include "magick/utility.h"
 #include "magick/version.h"
 \f
@@ -1546,91 +1547,30 @@ MagickExport MagickBooleanType IsImagesEqual(Image *image,
 static double GetSimilarityMetric(const Image *image,const Image *reference,
   const ssize_t x_offset,const ssize_t y_offset,ExceptionInfo *exception)
 {
-  CacheView
-    *image_view,
-    *reference_view;
-
   double
-    similarity;
-
-  ssize_t
-    y;
+    channel_distortion[AllChannels+1];
 
+  Image
+    *similarity_image;
   MagickBooleanType
     status;
 
-  /*
-    Compute the similarity in pixels between two images.
-  */
-  status=MagickTrue;
-  similarity=0.0;
-  image_view=AcquireCacheView(image);
-  reference_view=AcquireCacheView(reference);
-  for (y=0; y < (ssize_t) reference->rows; y++)
-  {
-    register const IndexPacket
-      *restrict indexes,
-      *restrict reference_indexes;
-
-    register const PixelPacket
-      *restrict p,
-      *restrict q;
+  RectangleInfo
+    geometry;
 
-    register ssize_t
-      x;
-
-    if (status == MagickFalse)
-      continue;
-    p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset+y,
-      reference->columns,1,exception);
-    q=GetCacheViewVirtualPixels(reference_view,0,y,reference->columns,1,
-      exception);
-    if ((p == (const PixelPacket *) NULL) || (q == (const PixelPacket *) NULL))
-      {
-        status=MagickFalse;
-        continue;
-      }
-    indexes=GetCacheViewVirtualIndexQueue(image_view);
-    reference_indexes=GetCacheViewVirtualIndexQueue(reference_view);
-    for (x=0; x < (ssize_t) reference->columns; x++)
-    {
-      double
-        thread_similarity;
-
-      MagickRealType
-        distance;
-
-      thread_similarity=0.0;
-      distance=QuantumScale*(p->red-(MagickRealType) q->red);
-      thread_similarity+=distance*distance;
-      distance=QuantumScale*(p->green-(MagickRealType) q->green);
-      thread_similarity+=distance*distance;
-      distance=QuantumScale*(p->blue-(MagickRealType) q->blue);
-      thread_similarity+=distance*distance;
-      if ((image->matte != MagickFalse) && (reference->matte != MagickFalse))
-        {
-          distance=QuantumScale*(p->opacity-(MagickRealType) q->opacity);
-          thread_similarity+=distance*distance;
-        }
-      if ((image->colorspace == CMYKColorspace) &&
-          (reference->colorspace == CMYKColorspace))
-        {
-          distance=QuantumScale*(indexes[x]-(MagickRealType)
-            reference_indexes[x]);
-          thread_similarity+=distance*distance;
-        }
-      similarity+=thread_similarity;
-      p++;
-      q++;
-    }
-  }
-  reference_view=DestroyCacheView(reference_view);
-  image_view=DestroyCacheView(image_view);
+  SetGeometry(reference,&geometry);
+  geometry.x=x_offset;
+  geometry.y=y_offset;
+  similarity_image=CropImage(image,&geometry,exception);
+  if (similarity_image == (Image *) NULL)
+    return(0.0);
+  status=GetNormalizedCrossCorrelationError(reference,similarity_image,
+    DefaultChannels,channel_distortion,exception);
+  similarity_image=DestroyImage(similarity_image);
   if (status == MagickFalse)
     return(0.0);
-  similarity/=((double) reference->columns*reference->rows);
-  similarity/=(double) GetNumberChannels(reference,AllChannels);
-  return(sqrt(similarity));
+  return(1.0-channel_distortion[AllChannels]);
 }
 
 MagickExport Image *SimilarityImage(Image *image,const Image *reference,