diff -r c8bc315fa273 inst/bwperim.m
--- a/inst/bwperim.m	Sat Feb 11 23:54:52 2017 +0000
+++ b/inst/bwperim.m	Sun Apr 09 09:03:52 2017 -0400
@@ -20,7 +20,7 @@
 ##
 ## Values from the matrix @var{bw} are considered part of an object perimeter
 ## if their value is non-zero and is connected to at least one zero-valued
-## element.
+## element, or to the outside of @var{bw}.
 ##
 ## Element connectivity @var{conn}, to define the size of objects, can be
 ## specified with a numeric scalar (number of elements in the neighborhood):
@@ -71,7 +71,7 @@
   for dim = 1:min (ndims (perim), ndims (conn))
     conn_idx = tmp_conn_idx;
     conn_idx{dim} = [1 3];
-    if (p_size(dim) == 1 || ! any (conn(conn_idx{:})(:)))
+    if (! any (conn(conn_idx{:})(:)))
       continue
     endif
 
@@ -262,3 +262,23 @@
 %! c = a;
 %! c(3:6,3:6,3) = false;
 %! assert (bwperim (a, 4), c)
+
+## test dimensions of length 1 (1x1, Nx1, etc) (bug #50153)
+%!test
+%! conn_self = logical ([0 0 0; 0 1 0; 0 0 0]);
+%! assert (bwperim (true), true)
+%! assert (bwperim (true, conn_self), false)
+%! assert (bwperim (true (1, 6)), true (1, 6))
+%! assert (bwperim (true (1, 6), conn_self), false (1, 6))
+%! assert (bwperim (true (6, 1)), true (6, 1))
+%!
+%! bw_3d = true (1, 1, 6);
+%! assert (bwperim (bw_3d), bw_3d)
+%! assert (bwperim (bw_3d, conn_self), false (1, 1, 6))
+%! assert (bwperim (bw_3d, true (3)), bw_3d)
+%!
+%! perim_3d = bw_3d;
+%! perim_3d(1, 1, 2:end-1) = false;
+%! conn_3d = false (3, 3, 3);
+%! conn_3d(2, 2, :) = true;
+%! assert (bwperim (true (1, 1, 6), conn_3d), perim_3d)
diff -r c8bc315fa273 src/config.h.in
--- a/src/config.h.in	Sat Feb 11 23:54:52 2017 +0000
+++ b/src/config.h.in	Sun Apr 09 09:03:52 2017 -0400
@@ -1,2 +1,5 @@
 /* Define if octave::math::min exists as replacement to xmin. */
 #undef HAVE_MIN_IN_OCTAVE_MATH_NAMESPACE
+
+/* Define if octave::feval exists as replacement to feval. */
+#undef HAVE_FEVAL_IN_OCTAVE_NAMESPACE
diff -r c8bc315fa273 src/configure.ac
--- a/src/configure.ac	Sat Feb 11 23:54:52 2017 +0000
+++ b/src/configure.ac	Sun Apr 09 09:03:52 2017 -0400
@@ -70,6 +70,20 @@
             [Define if octave::math::min exists as replacement to xmin.])
 fi
 
+AC_CACHE_CHECK(
+  [whether feval is in the octave namespace],
+  [octave_image_cv_feval_in_octave_namespace],
+  [AC_COMPILE_IFELSE(
+    [AC_LANG_PROGRAM([#include <parse.h>],
+                     [octave::feval ("eye")])],
+    [octave_image_cv_feval_in_octave_namespace=yes],
+    [octave_image_cv_feval_in_octave_namespace=no])])
+
+if test "$octave_image_cv_feval_in_octave_namespace" = yes; then
+  AC_DEFINE([HAVE_FEVAL_IN_OCTAVE_NAMESPACE], [1],
+            [Define if octave::feval exists as replacement to feval.])
+fi
+
 CXXFLAGS="$image_save_CXXFLAGS"
 
 
diff -r c8bc315fa273 src/imreconstruct.cc
--- a/src/imreconstruct.cc	Sat Feb 11 23:54:52 2017 +0000
+++ b/src/imreconstruct.cc	Sun Apr 09 09:03:52 2017 -0400
@@ -24,8 +24,6 @@
 // This should still be more efficient than using subscript indices to find
 // when we are on the border.
 
-#include "config.h"
-
 #include <functional>
 #include <queue>
 
@@ -38,20 +36,8 @@
 
 using namespace octave::image;
 
-namespace octave_image
-{
-  // Temporary wrapper until we no longer support Octave 4.0 (bug #48618)
-  template <typename T>
-  inline T
-  min (T x, T y)
-  {
-#if defined HAVE_MIN_IN_OCTAVE_MATH_NAMESPACE
-    return octave::math::min (x, y);
-#else
-    return xmin (x, y);
-#endif
-  }
-}
+#define WANTS_MIN 1
+#include "octave-wrappers.h"
 
 /*
 ## A dirty implementation of the fast hybrid reconstruction as m file
diff -r c8bc315fa273 src/octave-wrappers.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/octave-wrappers.h	Sun Apr 09 09:03:52 2017 -0400
@@ -0,0 +1,70 @@
+// Copyright (C) 2017 Carnë Draug <carandraug@octave.org>
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, see
+// <http://www.gnu.org/licenses/>.
+
+// Core is going through a bunch of changes, and moving a lot of
+// functions into the octave namespace and deprecating thw old
+// functions.  We want to be compatible with older versions and we
+// don't want to scare users with deprecation warnings so we have our
+// own wrappers so nothing breaks.
+//
+// We don't want to have a file per function we need to wrap; we don't
+// want to repeat the wrapper in each file that needs it; we don't
+// want to disable the deprecation warnings (so that we get warnings
+// next time we something else gets deprecated); and we don't want to
+// include all needed headers.
+//
+// It is the job of the file that includes this to include the
+// required headers, at least as long as core only changes the
+// namespace and not the header file.
+//
+// This wrappers are all temporary until we no longer support the
+// Octave version that made the change.
+
+#include "config.h"
+
+namespace octave_image
+{
+  // Temporary wrapper until we no longer support Octave 4.0 (bug #48618)
+#if defined WANTS_MIN && ! defined HAS_MIN
+#define HAS_MIN 1
+  template <typename T>
+  inline T
+  min (T x, T y)
+  {
+#if defined HAVE_MIN_IN_OCTAVE_MATH_NAMESPACE
+    return octave::math::min (x, y);
+#else
+    return xmin (x, y);
+#endif
+  }
+#endif
+
+  // Temporary wrapper until we no longer support Octave 4.2 (bug #50180)
+#if defined WANTS_FEVAL && ! defined HAS_FEVAL
+#define HAS_FEVAL 1
+  inline octave_value_list
+  feval (const std::string& name,
+         const octave_value_list& args,
+         int nargout = 0)
+  {
+#if defined HAVE_FEVAL_IN_OCTAVE_NAMESPACE
+    return octave::feval (name, args, nargout);
+#else
+    return ::feval (name, args, nargout);
+#endif
+  }
+#endif
+}
diff -r c8bc315fa273 src/strel.cc
--- a/src/strel.cc	Sat Feb 11 23:54:52 2017 +0000
+++ b/src/strel.cc	Sun Apr 09 09:03:52 2017 -0400
@@ -27,6 +27,9 @@
 #include <octave/parse.h>  // gives us feval so we can use @strel
 #include <octave/oct-map.h>
 
+#define WANTS_FEVAL 1
+#include "octave-wrappers.h"
+
 // Constructors
 
 // Expects a @strel object, or a boolean matrix (or something
@@ -49,13 +52,13 @@
       strel_args(0) = "arbitrary";
       strel_args(1) = se;
       // We are leaving the input check up to @strel
-      se = feval ("strel", strel_args)(0);
+      se = octave_image::feval ("strel", strel_args)(0);
       if (error_state)
         return;
     }
 
-  nhood   = feval ("getnhood",  se)(0).bool_array_value ();
-  height  = feval ("getheight", se)(0).array_value ();
+  nhood   = octave_image::feval ("getnhood",  se)(0).bool_array_value ();
+  height  = octave_image::feval ("getheight", se)(0).array_value ();
 
   // Maybe we should handle this better but how?  This makes imerode
   // and imdilate work with a [] strel
@@ -68,8 +71,9 @@
   ini_ctor ();
   origin  = default_origin ();
 
-  const octave_value se_seq       = feval ("getsequence", se)(0);
-  const octave_idx_type seq_numel = feval ("numel", se_seq)(0).idx_type_value ();
+  const octave_value se_seq = octave_image::feval ("getsequence", se)(0);
+  const octave_idx_type seq_numel
+    = octave_image::feval ("numel", se_seq)(0).idx_type_value ();
 
   // This is to emulate the strel_obj(idx) syntax in function form
   static const char *fields[] = {"type", "subs", 0};
@@ -86,10 +90,13 @@
           ref.setfield ("subs", Cell (octave_value (subs+1)));
           subsref_args(1) = ref;
           // Equivalent to "selem = strel_obj(subs)"
-          const octave_value_list elem = feval ("subsref", subsref_args)(0);
+          const octave_value_list elem
+            = octave_image::feval ("subsref", subsref_args)(0);
 
-          const boolNDArray elem_nhood  = feval ("getnhood",  elem)(0).bool_array_value ();
-          const NDArray elem_height     = feval ("getheight", elem)(0).array_value ();
+          const boolNDArray elem_nhood
+            = octave_image::feval ("getnhood",  elem)(0).bool_array_value ();
+          const NDArray elem_height
+            = octave_image::feval ("getheight", elem)(0).array_value ();
 
           decomposition.push_back (strel (elem_nhood, elem_height));
         }
diff -r c8bc315fa273 src/watershed.cc
--- a/src/watershed.cc	Sat Feb 11 23:54:52 2017 +0000
+++ b/src/watershed.cc	Sun Apr 09 09:03:52 2017 -0400
@@ -21,6 +21,9 @@
 #include <octave/Cell.h>
 #include <octave/oct-map.h>
 
+#define WANTS_FEVAL 1
+#include "octave-wrappers.h"
+
 #include "connectivity.h"
 using namespace octave::image;
 
@@ -57,7 +60,7 @@
   args(0) = im;
   args(1) = conn.mask;
   args(2) = conn.mask;
-  const octave_value gradient = feval ("mmgradm", args)(0);
+  const octave_value gradient = octave_image::feval ("mmgradm", args)(0);
   return ov2T<T> (gradient);
 }
 
@@ -68,7 +71,8 @@
   octave_value_list args (2);
   args(0) = im;
   args(1) = conn.mask;
-  const octave_value regional_min = feval ("imregionalmin", args)(0);
+  const octave_value regional_min = octave_image::feval ("imregionalmin",
+                                                         args)(0);
   return regional_min.bool_array_value ();
 }
 
@@ -78,7 +82,7 @@
   octave_value_list args (2);
   args(0) = bw;
   args(1) = conn.mask;
-  const octave_value label = feval ("bwlabeln", args)(0);
+  const octave_value label = octave_image::feval ("bwlabeln", args)(0);
   return label.array_value ();
 }
 
