]> granicus.if.org Git - imagemagick/commitdiff
https://www.imagemagick.org/discourse-server/viewtopic.php?f=2&t=30866
authorCristy <urban-warrior@imagemagick.org>
Sun, 20 Nov 2016 14:08:14 +0000 (09:08 -0500)
committerCristy <urban-warrior@imagemagick.org>
Sun, 20 Nov 2016 14:08:14 +0000 (09:08 -0500)
ChangeLog
MagickCore/compare.c
MagickCore/quantize.c
MagickCore/statistic.c

index da8423d7fcc29dd68198c941aac4d68e7a35c6f3..16c9b698761085c86d58ed4ca39470399ef307f3 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,6 +4,8 @@
     https://www.imagemagick.org/discourse-server/viewtopic.php?f=3&t=30887).
   * Set alpha member of draw structure to OpaqueAlpha (reference
     https://www.imagemagick.org/discourse-server/viewtopic.php?f=3&t=30894).
+  * Off by 1 error when computing the standard deviation (reference
+    https://www.imagemagick.org/discourse-server/viewtopic.php?f=2&t=30866).
 
 2016-11-15  7.0.3-7 Cristy  <quetzlzacatenango@image...>
   * Release ImageMagick version 7.0.3-7, GIT revision 19024:87aca83:20161115.
@@ -22,7 +24,7 @@
   * Prevent fault in MSL interpreter (reference
     https://www.imagemagick.org/discourse-server/viewtopic.php?f=3&t=30797).
   * Mask composite produces proper results for the convert utility (reference
-    http://www.imagemagick.org/discourse-server/viewtopic.php?f=3&t=29675).
+    https://www.imagemagick.org/discourse-server/viewtopic.php?f=3&t=29675).
     
 
 2016-10-10  7.0.3-5 Cristy  <quetzlzacatenango@image...>
index d3349dbdecf4535985faa1de3f30fdcea9f352fc..adfd562ed8a46b98893bd9a0a26eaf00ec2803ff 100644 (file)
@@ -675,6 +675,7 @@ static MagickBooleanType GetMeanErrorPerPixel(Image *image,
 
   double
     area,
+    gamma,
     maximum_error,
     mean_error;
 
@@ -753,8 +754,9 @@ static MagickBooleanType GetMeanErrorPerPixel(Image *image,
   }
   reconstruct_view=DestroyCacheView(reconstruct_view);
   image_view=DestroyCacheView(image_view);
-  image->error.mean_error_per_pixel=distortion[CompositePixelChannel]/area;
-  image->error.normalized_mean_error=QuantumScale*QuantumScale*mean_error/area;
+  gamma=PerceptibleReciprocal(area);
+  image->error.mean_error_per_pixel=gamma*distortion[CompositePixelChannel];
+  image->error.normalized_mean_error=gamma*QuantumScale*QuantumScale*mean_error;
   image->error.normalized_maximum_error=QuantumScale*maximum_error;
   return(status);
 }
@@ -1646,6 +1648,7 @@ MagickExport MagickBooleanType SetImageColorMetric(Image *image,
 
   double
     area,
+    gamma,
     maximum_error,
     mean_error,
     mean_error_per_pixel;
@@ -1726,10 +1729,10 @@ MagickExport MagickBooleanType SetImageColorMetric(Image *image,
   }
   reconstruct_view=DestroyCacheView(reconstruct_view);
   image_view=DestroyCacheView(image_view);
-  image->error.mean_error_per_pixel=(double) (mean_error_per_pixel/area);
-  image->error.normalized_mean_error=(double) (QuantumScale*QuantumScale*
-    mean_error/area);
-  image->error.normalized_maximum_error=(double) (QuantumScale*maximum_error);
+  gamma=PerceptibleReciprocal(area);
+  image->error.mean_error_per_pixel=gamma*mean_error_per_pixel;
+  image->error.normalized_mean_error=gamma*QuantumScale*QuantumScale*mean_error;
+  image->error.normalized_maximum_error=(double) QuantumScale*maximum_error;
   status=image->error.mean_error_per_pixel == 0.0 ? MagickTrue : MagickFalse;
   return(status);
 }
index 48b456799b02876478144fea199ff70174212e8d..248d89ca6669a8b9924a8a8d4a262a70357801fe 100644 (file)
@@ -2189,6 +2189,7 @@ MagickExport MagickBooleanType GetImageQuantizeError(Image *image,
     area,
     beta,
     distance,
+    gamma,
     maximum_error,
     mean_error,
     mean_error_per_pixel;
@@ -2255,10 +2256,10 @@ MagickExport MagickBooleanType GetImageQuantizeError(Image *image,
     }
   }
   image_view=DestroyCacheView(image_view);
-  image->error.mean_error_per_pixel=(double) mean_error_per_pixel/area;
-  image->error.normalized_mean_error=(double) QuantumScale*QuantumScale*
-    mean_error/area;
-  image->error.normalized_maximum_error=(double) QuantumScale*maximum_error;
+  gamma=PerceptibleReciprocal(area);
+  image->error.mean_error_per_pixel=gamma*mean_error_per_pixel;
+  image->error.normalized_mean_error=gamma*QuantumScale*QuantumScale*mean_error;
+  image->error.normalized_maximum_error=QuantumScale*maximum_error;
   return(MagickTrue);
 }
 \f
index 20558747fb5736ca1d554ffdfcbc87a380649cff..145b817d45efed9f854e0ac4410ac7377726c5da 100644 (file)
@@ -1115,7 +1115,8 @@ MagickExport MagickBooleanType GetImageEntropy(const Image *image,
   double *entropy,ExceptionInfo *exception)
 {
   double
-    area;
+    area,
+    gamma;
 
   ChannelStatistics
     *channel_statistics;
@@ -1145,12 +1146,11 @@ MagickExport MagickBooleanType GetImageEntropy(const Image *image,
       channel_statistics[i].entropy;
     area++;
   }
-  if (area > MagickEpsilon)
-    {
-      channel_statistics[CompositePixelChannel].entropy/=area;
-      channel_statistics[CompositePixelChannel].standard_deviation=
-        sqrt(channel_statistics[CompositePixelChannel].standard_deviation/area);
-    }
+  gamma=PerceptibleReciprocal(area);
+  channel_statistics[CompositePixelChannel].entropy*=gamma;
+  gamma=PerceptibleReciprocal(area-1.0);
+  channel_statistics[CompositePixelChannel].standard_deviation=
+    sqrt(gamma*channel_statistics[CompositePixelChannel].standard_deviation);
   *entropy=channel_statistics[CompositePixelChannel].entropy;
   channel_statistics=(ChannelStatistics *) RelinquishMagickMemory(
     channel_statistics);
@@ -1378,7 +1378,8 @@ MagickExport MagickBooleanType GetImageMean(const Image *image,double *mean,
   double *standard_deviation,ExceptionInfo *exception)
 {
   double
-    area;
+    area,
+    gamma;
 
   ChannelStatistics
     *channel_statistics;
@@ -1410,12 +1411,11 @@ MagickExport MagickBooleanType GetImageMean(const Image *image,double *mean,
       channel_statistics[i].mean;
     area++;
   }
-  if (area > MagickEpsilon)
-    {
-      channel_statistics[CompositePixelChannel].mean/=area;
-      channel_statistics[CompositePixelChannel].standard_deviation=
-        sqrt(channel_statistics[CompositePixelChannel].standard_deviation/area);
-    }
+  gamma=PerceptibleReciprocal(area);
+  channel_statistics[CompositePixelChannel].mean*=gamma;
+  gamma=PerceptibleReciprocal(area-1.0);
+  channel_statistics[CompositePixelChannel].standard_deviation=
+    sqrt(gamma*channel_statistics[CompositePixelChannel].standard_deviation);
   *mean=channel_statistics[CompositePixelChannel].mean;
   *standard_deviation=
     channel_statistics[CompositePixelChannel].standard_deviation;