]> granicus.if.org Git - imagemagick/commitdiff
(no commit message)
authorcristy <urban-warrior@git.imagemagick.org>
Sat, 29 Mar 2014 15:30:43 +0000 (15:30 +0000)
committercristy <urban-warrior@git.imagemagick.org>
Sat, 29 Mar 2014 15:30:43 +0000 (15:30 +0000)
MagickCore/effect.c
MagickCore/effect.h
MagickCore/option.c
MagickWand/convert.c
MagickWand/mogrify.c
MagickWand/operation.c
PerlMagick/Magick.xs
utilities/convert.1.in
utilities/mogrify.1.in

index b0ef02e43801e3f37c5abc972c92567b89df6b57..ee645be4eff7210e72455e8ed54f5ad82620bbf3 100644 (file)
@@ -849,6 +849,60 @@ MagickExport Image *BlurImage(const Image *image,const double radius,
 %                                                                             %
 %                                                                             %
 %                                                                             %
+%     C a n n y E d g e I m a g e                                             %
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%  CannyEdgeImage() uses a multi-stage algorithm to detect a wide range of
+%  edges in images.
+%
+%  The format of the EdgeImage method is:
+%
+%      Image *CannyEdgeImage(const Image *image,const double radius,
+%        const double sigma,const double low_factor,const double high_factor,
+%        const size_t threshold,ExceptionInfo *exception)
+%
+%  A description of each parameter follows:
+%
+%    o image: the image.
+%
+%    o channel: the channel type.
+%
+%    o radius: the radius of the gaussian smoothing filter.
+%
+%    o sigma: the sigma of the gaussian smoothing filter.
+%
+%    o low_factor: use this low factor in hysteresis.
+%
+%    o hight_factor: use this high factor in hysteresis.
+%
+%    o exception: return any errors or warnings in this structure.
+%
+*/
+MagickExport Image *CannyEdgeImage(const Image *image,const double radius,
+  const double sigma,const double low_factor,const double high_factor,
+  ExceptionInfo *exception)
+{
+  Image
+    *edge_image;
+
+  assert(image != (const Image *) NULL);
+  assert(image->signature == MagickSignature);
+  if (image->debug != MagickFalse)
+    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
+  assert(exception != (ExceptionInfo *) NULL);
+  assert(exception->signature == MagickSignature);
+  edge_image=(Image *) NULL;
+  return(edge_image);
+}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
 %     C o n v o l v e I m a g e                                               %
 %                                                                             %
 %                                                                             %
index 91344d0fff7ab9eeccb33ea4a7e5d58044e7871b..37c06a3ebcbdd51396bf4232d6b0a535040a3e38 100644 (file)
@@ -63,6 +63,8 @@ extern MagickExport Image
   *AdaptiveSharpenImage(const Image *,const double,const double,
      ExceptionInfo *),
   *BlurImage(const Image *,const double,const double,ExceptionInfo *),
+  *CannyEdgeImage(const Image *,const double,const double,const double,
+    const double,ExceptionInfo *),
   *ConvolveImage(const Image *,const KernelInfo *,ExceptionInfo *),
   *DespeckleImage(const Image *,ExceptionInfo *),
   *EdgeImage(const Image *,const double,ExceptionInfo *),
index fa1975b88929c15d5c87767b6ce57b0953b8f601..e46b43d104552cef8deb733c8ebf7a98a4078fb4 100644 (file)
@@ -259,6 +259,8 @@ static const OptionInfo
     { "-brightness-contrast", 1L, SimpleOperatorFlag, MagickFalse },
     { "+cache", 0L, GlobalOptionFlag, MagickFalse },
     { "-cache", 1L, GlobalOptionFlag, MagickFalse },
+    { "+edge", 1L, SimpleOperatorFlag, MagickTrue },
+    { "-edge", 1L, SimpleOperatorFlag, MagickFalse },
     { "+caption", 0L, ImageInfoOptionFlag | NeverInterpretArgsFlag, MagickFalse },
     { "-caption", 1L, ImageInfoOptionFlag | NeverInterpretArgsFlag, MagickFalse },
     { "+cdl", 1L, DeprecateOptionFlag, MagickTrue },
index d9f98a7e66deae4012e221523e0f5cd8c73f2cf6..d7ab8da2aab47f7ef97df06a323bfc6aa774237d 100644 (file)
@@ -177,6 +177,7 @@ static MagickBooleanType ConvertUsage(void)
       "-bordercolor color   border color",
       "-brightness-contrast geometry",
       "                     improve brightness / contrast of the image",
+      "-canny geometry      detect edges in the image",
       "-cdl filename        color correct with a color decision list",
       "-charcoal radius     simulate a charcoal drawing",
       "-chop geometry       remove pixels from the image interior",
@@ -863,6 +864,17 @@ WandExport MagickBooleanType ConvertImageCommand(ImageInfo *image_info,
               ThrowConvertInvalidArgumentException(option,argv[i]);
             break;
           }
+        if (LocaleCompare("canny",option+1) == 0)
+          {
+            if (*option == '+')
+              break;
+            i++;
+            if (i == (ssize_t) (argc-1))
+              ThrowConvertException(OptionError,"MissingArgument",option);
+            if (IsGeometry(argv[i]) == MagickFalse)
+              ThrowConvertInvalidArgumentException(option,argv[i]);
+            break;
+          }
         if (LocaleCompare("caption",option+1) == 0)
           {
             if (*option == '+')
index 7112e4133ebcbaf0ec60cf815a7cad48a5e347c1..2857f9ac1610546f6646f150fdd78c0265d3c1cb 100644 (file)
@@ -981,6 +981,23 @@ WandExport MagickBooleanType MogrifyImage(ImageInfo *image_info,const int argc,
       }
       case 'c':
       {
+        if (LocaleCompare("canny",option+1) == 0)
+          {
+            /*
+              Detect edges in the image.
+            */
+            (void) SyncImageSettings(mogrify_info,*image,exception);
+            flags=ParseGeometry(argv[i+1],&geometry_info);
+            if ((flags & SigmaValue) == 0)
+              geometry_info.sigma=1.0;
+            if ((flags & XiValue) == 0)
+              geometry_info.xi=0.35;
+            if ((flags & PsiValue) == 0)
+              geometry_info.psi=0.75;
+            mogrify_image=CannyEdgeImage(*image,geometry_info.rho,
+              geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
+            break;
+          }
         if (LocaleCompare("cdl",option+1) == 0)
           {
             char
@@ -3286,6 +3303,7 @@ static MagickBooleanType MogrifyUsage(void)
       "-bordercolor color   border color",
       "-brightness-contrast geometry",
       "                     improve brightness / contrast of the image",
+      "-canny geometry      detect edges in the image",
       "-cdl filename        color correct with a color decision list",
       "-charcoal geometry   simulate a charcoal drawing",
       "-chop geometry       remove pixels from the image interior",
@@ -4009,6 +4027,17 @@ WandExport MagickBooleanType MogrifyImageCommand(ImageInfo *image_info,
               ThrowMogrifyInvalidArgumentException(option,argv[i]);
             break;
           }
+        if (LocaleCompare("canny",option+1) == 0)
+          {
+            if (*option == '+')
+              break;
+            i++;
+            if (i == (ssize_t) argc)
+              ThrowMogrifyException(OptionError,"MissingArgument",option);
+            if (IsGeometry(argv[i]) == MagickFalse)
+              ThrowMogrifyInvalidArgumentException(option,argv[i]);
+            break;
+          }
         if (LocaleCompare("caption",option+1) == 0)
           {
             if (*option == '+')
index 88aa388af7661c06bb0f0ac304b00fbf44cbb16e..11b5c0af6a75d48e9f504294edd915a384b60a91 100644 (file)
@@ -1914,6 +1914,21 @@ static MagickBooleanType CLISimpleOperatorImage(MagickCLI *cli_wand,
     }
     case 'c':
     {
+      if (LocaleCompare("canny",option+1) == 0)
+        {
+          flags=ParseGeometry(arg1,&geometry_info);
+          if ((flags & (RhoValue|SigmaValue)) == 0)
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          if ((flags & SigmaValue) == 0)
+            geometry_info.sigma=1.0;
+          if ((flags & XiValue) == 0)
+            geometry_info.xi=0.35;
+          if ((flags & PsiValue) == 0)
+            geometry_info.psi=0.75;
+          new_image=CannyEdgeImage(_image,geometry_info.rho,
+            geometry_info.sigma,geometry_info.xi,geometry_info.psi,_exception);
+          break;
+        }
       if (LocaleCompare("cdl",option+1) == 0)
         {
           /* Note: arguments do not have percent escapes expanded */
index b66ca308f0fdc79f253c0cd1eeac0af0ed6f12fb..e207408fca59b5eef8bb1ed55d5f432f8079219f 100644 (file)
@@ -544,6 +544,9 @@ static struct
     { "Poly", { {"terms", ArrayReference},
       {"channel", MagickChannelOptions} } },
     { "Grayscale", { {"method", MagickNoiseOptions} } },
+    { "CannyEdge", { {"geometry", StringReference},
+      {"radius", RealReference}, {"sigma", RealReference},
+      {"low-factor", RealReference}, {"high-factor", RealReference} } },
   };
 
 static SplayTreeInfo
@@ -7525,6 +7528,8 @@ Mogrify(ref,...)
     PolyImage          = 274
     Grayscale          = 275
     GrayscaleImage     = 276
+    CannyEdge          = 278
+    CannyEdgeImage     = 279
     MogrifyRegion      = 666
   PPCODE:
   {
@@ -11092,6 +11097,36 @@ Mogrify(ref,...)
           (void) GrayscaleImage(image,method,exception);
           break;
         }
+        case 138:  /* Canny */
+        {
+          if (attribute_flag[0] != 0)
+            {
+              flags=ParseGeometry(argument_list[0].string_reference,
+                &geometry_info);
+              if ((flags & SigmaValue) == 0)
+                geometry_info.sigma=1.0;
+              if ((flags & XiValue) == 0)
+                geometry_info.xi=0.35;
+              if ((flags & PsiValue) == 0)
+                geometry_info.psi=0.75;
+            }
+          if (attribute_flag[1] != 0)
+            geometry_info.rho=argument_list[1].real_reference;
+          if (attribute_flag[2] != 0)
+            geometry_info.sigma=argument_list[2].real_reference;
+          if (attribute_flag[3] != 0)
+            geometry_info.xi=argument_list[3].real_reference;
+          if (attribute_flag[4] != 0)
+            geometry_info.psi=argument_list[4].real_reference;
+          if (attribute_flag[5] != 0)
+            channel=(ChannelType) argument_list[5].integer_reference;
+          channel_mask=SetImageChannelMask(image,channel);
+          image=CannyEdgeImage(image,geometry_info.rho,geometry_info.sigma,
+            geometry_info.xi,geometry_info.psi,exception);
+          if (image != (Image *) NULL)
+            (void) SetImageChannelMask(image,channel_mask);
+          break;
+        }
       }
       if (next != (Image *) NULL)
         (void) CatchImageException(next);
index 4a542b5a2ede944ad3b0d0c5818236117fb9255e..f80930c8523f5fbae6a9f13d6195bdd89fae7895 100644 (file)
@@ -135,6 +135,7 @@ Image Operators:
   \-border geometry     surround image with a border of color
   \-brightness-contrast geometry
   \                     improve brightness / contrast of the image
+  \-canny geometry      detect edges in the image
   \-charcoal radius     simulate a charcoal drawing
   \-chop geometry       remove pixels from the image interior
   \-clamp               keep pixel values in range (0-QuantumRange)
index 248f5b69ad3006930c56d2e28fbf9fde7bf1e3cd..00af63ee21e92f167dfa7ea134104a085eb42127 100644 (file)
@@ -133,6 +133,7 @@ Image Operators:
   \-border geometry     surround image with a border of color
   \-brightness-contrast geometry
                        improve brightness / contrast of the image
+  \-canny geometry      detect edges in the image
   \-charcoal radius     simulate a charcoal drawing
   \-chop geometry       remove pixels from the image interior
   \-clamp               keep pixel values in range (0-QuantumRange)