]> granicus.if.org Git - imagemagick/blobdiff - MagickCore/effect.c
(no commit message)
[imagemagick] / MagickCore / effect.c
index ab698e34eda119aac1deaca8d8b8e3f22f92dccc..57433ba078796b65c571060ffd56c1e72d09d502 100644 (file)
@@ -863,8 +863,7 @@ MagickExport Image *BlurImage(const Image *image,const double radius,
 %
 %      Image *CannyEdgeImage(const Image *image,const double radius,
 %        const double sigma,const double lower_precent,
-%        const double upper_percent,const size_t threshold,
-%        ExceptionInfo *exception)
+%        const double upper_percent,ExceptionInfo *exception)
 %
 %  A description of each parameter follows:
 %
@@ -999,12 +998,15 @@ MagickExport Image *CannyEdgeImage(const Image *image,const double radius,
     *edge_view,
     *trace_view;
 
+  CannyInfo
+    pixel;
+
   char
     geometry[MaxTextExtent];
 
   double
-    upper_threshold,
-    lower_threshold;
+    lower_threshold,
+    upper_threshold;
 
   Image
     *edge_image;
@@ -1131,14 +1133,14 @@ MagickExport Image *CannyEdgeImage(const Image *image,const double radius,
             intensity;
 
           intensity=GetPixelIntensity(edge_image,kernel_pixels+u);
-          dx+=3.0*Gx[v][u]*intensity/2.0;
-          dy+=3.0*Gy[v][u]*intensity/2.0;
+          dx+=0.5*Gx[v][u]*intensity;
+          dy+=0.5*Gy[v][u]*intensity;
         }
         kernel_pixels+=edge_image->columns+1;
       }
       pixel.magnitude=sqrt(dx*dx+dy*dy);
-      pixel.orientation=0;
-      if (dx != 0.0)
+      pixel.orientation=2;
+      if (fabs(dx) > MagickEpsilon)
         {
           double
             theta;
@@ -1175,14 +1177,9 @@ MagickExport Image *CannyEdgeImage(const Image *image,const double radius,
     Non-maxima suppression, remove pixels that are not considered to be part
     of an edge.
   */
-  histogram=(size_t *) AcquireQuantumMemory(65536,sizeof(*histogram));
-  if (histogram == (size_t *) NULL)
-    {
-      pixel_cache=DestroyMatrixInfo(pixel_cache);
-      edge_image=DestroyImage(edge_image);
-      return((Image *) NULL);
-    }
-  (void) ResetMagickMemory(histogram,0,65536*sizeof(*histogram));
+  (void) GetMatrixElement(pixel_cache,0,0,&pixel);
+  max=pixel.intensity;
+  min=pixel.intensity;
   edge_view=AcquireAuthenticCacheView(edge_image,exception);
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
   #pragma omp parallel for schedule(static,4) shared(status) \
@@ -1256,14 +1253,16 @@ MagickExport Image *CannyEdgeImage(const Image *image,const double radius,
       if ((pixel.magnitude < alpha_pixel.magnitude) ||
           (pixel.magnitude < beta_pixel.magnitude))
         pixel.intensity=0;
-      else
-        if (pixel.magnitude > QuantumRange)
-          pixel.intensity=QuantumRange;
       (void) SetMatrixElement(pixel_cache,x,y,&pixel);
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
       #pragma omp critical (MagickCore_CannyEdgeImage)
 #endif
-      histogram[ScaleQuantumToShort(ClampToQuantum(pixel.intensity))]++;
+      {
+        if (pixel.intensity < min)
+          min=pixel.intensity;
+        if (pixel.intensity > max)
+          max=pixel.intensity;
+      }
       *q=0;
       q+=GetPixelChannels(edge_image);
     }
@@ -1274,16 +1273,8 @@ MagickExport Image *CannyEdgeImage(const Image *image,const double radius,
   /*
     Estimate hysteresis threshold.
   */
-  number_pixels=(size_t) (lower_precent*(image->columns*image->rows-
-    histogram[0]));
-  count=0;
-  for (i=65535; count < (ssize_t) number_pixels; i--)
-    count+=histogram[i];
-  upper_threshold=(double) ScaleShortToQuantum((unsigned short) i);
-  for (i=0; histogram[i] == 0; i++) ;
-  lower_threshold=upper_percent*(upper_threshold+
-    ScaleShortToQuantum((unsigned short) i));
-  histogram=(size_t *) RelinquishMagickMemory(histogram);
+  lower_threshold=lower_percent*(max-min)+min;
+  upper_threshold=upper_percent*(max-min)+min;
   /*
     Hysteresis threshold.
   */
@@ -1295,42 +1286,43 @@ MagickExport Image *CannyEdgeImage(const Image *image,const double radius,
 #endif
   for (y=0; y < (ssize_t) edge_image->rows; y++)
   {
-    register Quantum
-      *restrict q;
-
     register ssize_t
       x;
 
     if (status == MagickFalse)
       continue;
-    q=GetCacheViewAuthenticPixels(edge_view,0,y,edge_image->columns,1,
-      exception);
-    if (q == (Quantum *) NULL)
-      {
-        status=MagickFalse;
-        continue;
-      }
     for (x=0; x < (ssize_t) edge_image->columns; x++)
     {
       CannyInfo
         pixel;
 
+      register Quantum
+        *restrict q;
+
       /*
         Edge if pixel gradient higher than upper threshold.
       */
       status=GetMatrixElement(pixel_cache,x,y,&pixel);
       if (status == MagickFalse)
         break;
+      q=GetCacheViewAuthenticPixels(edge_view,x,y,1,1,exception);
+      if (q == (PixelPacket *) NULL)
+        {
+          status=MagickFalse;
+          continue;
+        }
       if ((pixel.intensity >= upper_threshold) &&
           (GetPixelIntensity(edge_image,q) == 0))
         {
           *q=QuantumRange;
+          status=SyncCacheViewAuthenticPixels(edge_view,exception);
+          if (status == MagickFalse)
+            continue;
           status=TraceEdges(edge_image,trace_view,pixel_cache,x,y,
             lower_threshold,exception);
           if (status == MagickFalse)
-            break;
+            continue;
         }
-      q+=GetPixelChannels(edge_image);
     }
     if (SyncCacheViewAuthenticPixels(edge_view,exception) == MagickFalse)
       status=MagickFalse;