changeset 902:0d49dd1a084c

imerode.cc: specialization for boolean dilation and erosion * imerode.cc: rather than check in the loop if image is boolean, have a separate function to handle them. Not much difference for binary images but almost twice as fast for other types.
author Carnë Draug <carandraug@octave.org>
date Thu, 09 Oct 2014 20:26:26 +0100
parents fd72bb9e1e9f
children dd4242ff0fa4
files src/imerode.cc
diffstat 1 files changed, 36 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/src/imerode.cc
+++ b/src/imerode.cc
@@ -128,7 +128,7 @@
 // argument, it's all done at compile time so we get better performance.
 // If erosion is false, we perform dilation instead
 template<class P, bool erosion, bool flat>
-static void
+inline static void
 erode_line (const P* in, P* out, const octave_idx_type* offsets, const P* height,
             const octave_idx_type& nnz, const octave_idx_type& line_length)
 {
@@ -141,20 +141,12 @@
               if (erosion)
                 {
                   if (in[offsets[nnz_idx]] < out[line_idx])
-                    {
-                      out[line_idx] = in[offsets[nnz_idx]];
-                      if (typeid (P) == typeid (bool))
-                        break;
-                    }
+                    out[line_idx] = in[offsets[nnz_idx]];
                 }
               else
                 {
                   if (in[offsets[nnz_idx]] > out[line_idx])
-                    {
-                      out[line_idx] = in[offsets[nnz_idx]];
-                      if (typeid (P) == typeid (bool))
-                        break;
-                    }
+                    out[line_idx] = in[offsets[nnz_idx]];
                 }
             }
           else
@@ -179,6 +171,39 @@
     }
 }
 
+// For the specific case of boolean dilation/erosion, we may be able to
+// break from the loop sooner.  Also, there is non-flat binary erosion
+// and dilation.
+template<class P, bool erosion, bool flat>
+inline static void
+erode_line (const bool* in, bool* out, const octave_idx_type* offsets, const bool* height,
+            const octave_idx_type& nnz, const octave_idx_type& line_length)
+{
+  for (octave_idx_type line_idx = 0; line_idx < line_length; line_idx++)
+    {
+      for (octave_idx_type nnz_idx = 0; nnz_idx < nnz; nnz_idx++)
+        {
+          if (erosion)
+            {
+              if (! in[offsets[nnz_idx]])
+                {
+                  out[line_idx] = false;
+                  break;
+                }
+            }
+          else
+            {
+              if (in[offsets[nnz_idx]])
+                {
+                  out[line_idx] = true;
+                  break;
+                }
+            }
+        }
+      in++;
+    }
+}
+
 template<class P, bool erosion, bool flat>
 static void
 erode_nd (const P* in, const dim_vector& in_cd,