changeset 11625:0f89dab6138b octave-forge

bwdist: remove .m, leave only actual code in C++
author carandraug
date Sun, 14 Apr 2013 16:22:13 +0000
parents d17d627be9f5
children aa5c3a75a940
files main/image/inst/bwdist.m main/image/src/Makefile main/image/src/__bwdist__.cc main/image/src/bwdist.cc
diffstat 4 files changed, 250 insertions(+), 311 deletions(-) [+]
line wrap: on
line diff
--- a/main/image/inst/bwdist.m	Sun Apr 14 16:19:31 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-## Copyright (C) 2006 Stefan Gustavson
-##
-## 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/>.
-
-## -*- texinfo -*-
-## @deftypefn {Function File} {@var{D} =} bwdist(@var{bw})
-##
-## Computes the distance transform of the image @var{bw}.
-## @var{bw} should be a binary 2D array, either a Boolean array or a
-## numeric array containing only the values 0 and 1.
-## The return value @var{D} is a double matrix of the same size as @var{bw}.
-## Elements with value 0 are considered background pixels, elements
-## with value 1 are considered object pixels. The return value
-## for each background pixel is the distance (according to the chosen
-## metric) to the closest object pixel. For each object pixel the
-## return value is 0.
-## 
-## @deftypefnx{Function File} {@var{D} =} bwdist(@var{bw}, @var{method})
-## 
-## @var{method} is a string to choose the distance metric. Currently
-## available metrics are 'euclidean', 'chessboard', 'cityblock' and
-## 'quasi-euclidean', which may each be abbreviated to any string
-## starting with 'e', 'ch', 'ci' and 'q', respectively.
-## If @var{method} is not specified, 'euclidean' is the default.
-## 
-## @deftypefnx {Function File} {[@var{D},@var{C}] =} bwdist(@var{bw}, @var{method})
-## 
-## If a second output argument is given, the linear index for the
-## closest object pixel is returned for each pixel. (For object
-## pixels, the index points to the pixel itself.) The return value
-## @var{C} is a matrix the same size as @var{bw}.
-## @end deftypefn
-
-# This M wrapper is an almost direct pass-through to an oct function,
-# but it might prove useful for a future extension to handle N-D data.
-# The algorithm implemented by __bwdist() is 2D-only.
-
-function [D, C] = bwdist(bw, method = "euclidean")
-  
-  if (!ischar(method))
-    error("bwdist: method name must be a string");
-  endif
-
-  if (nargout < 2)
-    D = __bwdist(bw, method);
-  else
-    [D, C] = __bwdist(bw, method);
-  endif
-
-endfunction
--- a/main/image/src/Makefile	Sun Apr 14 16:19:31 2013 +0000
+++ b/main/image/src/Makefile	Sun Apr 14 16:22:13 2013 +0000
@@ -2,7 +2,7 @@
 
 all: __spatial_filtering__.oct __bilateral__.oct __custom_gaussian_smoothing__.oct \
 	__boundary__.oct bwlabel.oct bwfill.oct rotate_scale.oct hough_line.oct \
-	graycomatrix.oct __bwdist__.oct nonmax_supress.oct bwlabeln.oct
+	graycomatrix.oct bwdist.oct nonmax_supress.oct bwlabeln.oct
 
 %.oct: %.cc
 	$(MKOCTFILE) $<
--- a/main/image/src/__bwdist__.cc	Sun Apr 14 16:19:31 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,249 +0,0 @@
-// Copyright (C) 2009 Stefan Gustavson <stefan.gustavson@gmail.com>
-//
-// 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/>.
-
-// __bwdist__.cc - OCT file, implements the BWDIST function
-// Depends on "edtfunc.c" for the actual computations
-
-#include <octave/oct.h>
-
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-#define DIST_EUCLIDEAN(x,y) ((int)(x)*(x) + (y)*(y))
-#define MAX(x,y) ((x)>(y) ? (x) : (y))
-#define DIST_CHESSBOARD(x,y) (MAX(abs(x), abs(y)))
-#define DIST_CITYBLOCK(x,y) (abs(x) + abs(y))
-#define SQRT2_1 0.4142136536
-#define DIST_QUASI_EUCLIDEAN(x,y) (abs(x)>abs(y) ? (abs(x) + SQRT2_1 * abs(y)) : (SQRT2_1 * abs(x) + abs(y)))
-
-#define DIST(x,y) DIST_EUCLIDEAN(x,y)
-#define FUNCNAME euclidean
-#include "edtfunc.c"
-#undef DIST
-#undef FUNCNAME
-
-#define DIST(x,y) DIST_CHESSBOARD(x,y)
-#define FUNCNAME chessboard
-#include "edtfunc.c"
-#undef DIST
-#undef FUNCNAME
-
-#define DIST(x,y) DIST_CITYBLOCK(x,y)
-#define FUNCNAME cityblock
-#include "edtfunc.c"
-#undef DIST
-#undef FUNCNAME
-
-#define DIST(x,y) DIST_QUASI_EUCLIDEAN(x,y)
-#define FUNCNAME quasi_euclidean
-#include "edtfunc.c"
-#undef DIST
-#undef FUNCNAME
-
-#ifdef __cplusplus
-}  /* end extern "C" */
-#endif
-
-DEFUN_DLD ( __bwdist__, args, nargout,
-"-*- texinfo -*-\n\
-@deftypefn {Loadable Function} {@var{D} =} __bwdist__(@var{bw})\n\
-Computes the distance transform of the image @var{bw}.\n\
-@var{bw} should be a binary 2D array, either a Boolean array or a\n\
-numeric array containing only the values 0 and 1.\n\
-The return value @var{D} is a double matrix of the same size as @var{bw}.\n\
-Elements with value 0 are considered background pixels, elements\n\
-with value 1 are considered object pixels. The return value\n\
-for each background pixel is the distance (according to the chosen\n\
-metric) to the closest object pixel. For each object pixel the\n\
-return value is 0.\n\
-\n\
-@deftypefnx{Loadable Function} {@var{D} =} __bwdist__(@var{bw}, @var{method})\n\
-\n\
-@var{method} is a string to choose the distance metric. Currently\n\
-available metrics are 'euclidean', 'chessboard', 'cityblock' and\n\
-'quasi-euclidean', which may each be abbreviated\n\
-to any string starting with 'e', 'ch', 'ci' and 'q', respectively.\n\
-If @var{method} is not specified, 'euclidean' is the default.\n\
-\n\
-@deftypefnx {Loadable Function} {[@var{D},@var{C}] =} __bwdist__(@var{bw}, @var{method})\n\
-\n\
-If a second output argument is given, the linear index for the\n\
-closest object pixel is returned for each pixel. (For object\n\
-pixels, the index points to the pixel itself.) The return value\n\
-@var{C} is a matrix the same size as @var{bw}.\n\n\
-@end deftypefn")
-{
-  const int nargin = args.length();
-  octave_value_list retval;
-
-  /* Check for proper number of input and output arguments */
-  if ((nargin < 1) || (nargin>2)) {
-    error ("bwdist accepts only one or two input parameters.");
-  }
-  else if (nargout > 2) {
-    error ("bwdist returns at most 2 output parameters.");
-  }
-  else {
-    /* Make sure input is a matrix */
-    const Matrix bw = args(0).matrix_value();
-    if (error_state) {
-      error ("bwdist input argument must be a matrix");
-      return retval;
-    }
-    /* Warn if input is not a binary image */
-    if(bw.any_element_not_one_or_zero()) {
-      warning ("bwdist input contains values other than 1 and 0.");
-    }
-
-    /* Everything seems to be OK to proceed */
-    dim_vector dims = bw.dims();
-    int rows = dims(0);
-    int cols = dims(1);
-    int caseMethod = 0; // Default 0 means Euclidean
-    if(nargin > 1) {
-      charMatrix method = args(1).char_matrix_value();
-      if(method(0) == 'e') caseMethod = 0; // Euclidean;
-      else if (method(0) == 'c') {
-        if(method(1) == 'h') caseMethod = 1; // chessboard
-        else if(method(1) == 'i') caseMethod = 2; // cityblock
-      }
-      else if(method(0) == 'q') caseMethod = 3; // quasi-Euclidean
-      else {
-        warning ("unknown metric, using 'euclidean'");
-        caseMethod = 0;
-      }
-    }
-
-    if (!error_state) {
-      /* Allocate two arrays for temporary output values */
-      OCTAVE_LOCAL_BUFFER (short, xdist, dims.numel());
-      OCTAVE_LOCAL_BUFFER (short, ydist, dims.numel());
-
-      /* Create final output array */
-      Matrix D (rows, cols);
-
-      /* Call the appropriate C subroutine and compute output */
-      switch(caseMethod) {
-
-      case 1:
-        chessboard(bw, rows, cols, xdist, ydist);
-        for(int i=0; i<rows*cols; i++) {
-          D(i) = DIST_CHESSBOARD(xdist[i], ydist[i]);
-        }
-        break;
-
-      case 2:
-        cityblock(bw, rows, cols, xdist, ydist);
-        for(int i=0; i<rows*cols; i++) {
-          D(i) = DIST_CITYBLOCK(xdist[i], ydist[i]);
-        }
-        break;
-
-      case 3:
-        quasi_euclidean(bw, rows, cols, xdist, ydist);
-        for(int i=0; i<rows*cols; i++) {
-          D(i) = DIST_QUASI_EUCLIDEAN(xdist[i], ydist[i]);
-        }
-        break;
-
-      case 0:
-      default:
-        euclidean(bw, rows, cols, xdist, ydist);
-        /* Remember sqrt() for the final output */
-        for(int i=0; i<rows*cols; i++) {
-          D(i) = sqrt((double)DIST_EUCLIDEAN(xdist[i], ydist[i]));
-        }
-        break;
-      }
-
-      retval(0) = D;
-
-      if(nargout > 1) {
-        /* Create a second output array */
-        Matrix C (rows, cols);
-        /* Compute optional 'index to closest object pixel' */
-        for(int i=0; i<rows*cols; i++) {
-          C (i) = i+1 - xdist[i] - ydist[i]*rows;
-        }
-        retval(1) = C;
-      }
-    }
-  }
-  return retval;
-}
-
-/*
-%!shared bw, out
-%!
-%! bw = [0   1   0   1   0   1   1   0
-%!       0   0   0   1   1   0   0   0
-%!       0   0   0   1   1   0   0   0
-%!       0   0   0   1   1   0   0   0
-%!       0   0   1   1   1   1   1   1
-%!       1   1   1   1   0   0   0   1
-%!       1   1   1   0   0   0   1   0
-%!       0   0   1   0   0   0   1   1];
-%!
-%! out = [ 1.00000   0.00000   1.00000   0.00000   1.00000   0.00000   0.00000   1.00000
-%!         1.41421   1.00000   1.00000   0.00000   0.00000   1.00000   1.00000   1.41421
-%!         2.23607   2.00000   1.00000   0.00000   0.00000   1.00000   2.00000   2.00000
-%!         2.00000   1.41421   1.00000   0.00000   0.00000   1.00000   1.00000   1.00000
-%!         1.00000   1.00000   0.00000   0.00000   0.00000   0.00000   0.00000   0.00000
-%!         0.00000   0.00000   0.00000   0.00000   1.00000   1.00000   1.00000   0.00000
-%!         0.00000   0.00000   0.00000   1.00000   1.41421   1.00000   0.00000   1.00000
-%!         1.00000   1.00000   0.00000   1.00000   2.00000   1.00000   0.00000   0.00000];
-%!
-%!assert (bwdist (bw, "euclidean"), out, 0.0001);
-%!assert (bwdist (logical (bw), "euclidean"), out, 0.0001);
-%!
-%! out = [ 1   0   1   0   1   0   0   1
-%!         1   1   1   0   0   1   1   1
-%!         2   2   1   0   0   1   2   2
-%!         2   1   1   0   0   1   1   1
-%!         1   1   0   0   0   0   0   0
-%!         0   0   0   0   1   1   1   0
-%!         0   0   0   1   1   1   0   1
-%!         1   1   0   1   2   1   0   0];
-%!
-%!assert (bwdist (bw, "chessboard"), out);
-%!
-%! out = [ 1   0   1   0   1   0   0   1
-%!         2   1   1   0   0   1   1   2
-%!         3   2   1   0   0   1   2   2
-%!         2   2   1   0   0   1   1   1
-%!         1   1   0   0   0   0   0   0
-%!         0   0   0   0   1   1   1   0
-%!         0   0   0   1   2   1   0   1
-%!         1   1   0   1   2   1   0   0];
-%!
-%!assert (bwdist (bw, "cityblock"), out);
-%!
-%! out = [ 1.00000   0.00000   1.00000   0.00000   1.00000   0.00000   0.00000   1.00000
-%!         1.41421   1.00000   1.00000   0.00000   0.00000   1.00000   1.00000   1.41421
-%!         2.41421   2.00000   1.00000   0.00000   0.00000   1.00000   2.00000   2.00000
-%!         2.00000   1.41421   1.00000   0.00000   0.00000   1.00000   1.00000   1.00000
-%!         1.00000   1.00000   0.00000   0.00000   0.00000   0.00000   0.00000   0.00000
-%!         0.00000   0.00000   0.00000   0.00000   1.00000   1.00000   1.00000   0.00000
-%!         0.00000   0.00000   0.00000   1.00000   1.41421   1.00000   0.00000   1.00000
-%!         1.00000   1.00000   0.00000   1.00000   2.00000   1.00000   0.00000   0.00000];
-%!
-%!assert (bwdist (bw, "quasi-euclidean"), out, 0.0001);
-%!
-%!error bwdist (magic (5));
-%!error bwdist (magic (5), "euclidean");
-*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main/image/src/bwdist.cc	Sun Apr 14 16:22:13 2013 +0000
@@ -0,0 +1,249 @@
+// Copyright (C) 2009 Stefan Gustavson <stefan.gustavson@gmail.com>
+//
+// 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/>.
+
+// __bwdist__.cc - OCT file, implements the BWDIST function
+// Depends on "edtfunc.c" for the actual computations
+
+#include <octave/oct.h>
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define DIST_EUCLIDEAN(x,y) ((int)(x)*(x) + (y)*(y))
+#define MAX(x,y) ((x)>(y) ? (x) : (y))
+#define DIST_CHESSBOARD(x,y) (MAX(abs(x), abs(y)))
+#define DIST_CITYBLOCK(x,y) (abs(x) + abs(y))
+#define SQRT2_1 0.4142136536
+#define DIST_QUASI_EUCLIDEAN(x,y) (abs(x)>abs(y) ? (abs(x) + SQRT2_1 * abs(y)) : (SQRT2_1 * abs(x) + abs(y)))
+
+#define DIST(x,y) DIST_EUCLIDEAN(x,y)
+#define FUNCNAME euclidean
+#include "edtfunc.c"
+#undef DIST
+#undef FUNCNAME
+
+#define DIST(x,y) DIST_CHESSBOARD(x,y)
+#define FUNCNAME chessboard
+#include "edtfunc.c"
+#undef DIST
+#undef FUNCNAME
+
+#define DIST(x,y) DIST_CITYBLOCK(x,y)
+#define FUNCNAME cityblock
+#include "edtfunc.c"
+#undef DIST
+#undef FUNCNAME
+
+#define DIST(x,y) DIST_QUASI_EUCLIDEAN(x,y)
+#define FUNCNAME quasi_euclidean
+#include "edtfunc.c"
+#undef DIST
+#undef FUNCNAME
+
+#ifdef __cplusplus
+}  /* end extern "C" */
+#endif
+
+DEFUN_DLD ( __bwdist__, args, nargout,
+"-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {@var{D} =} __bwdist__(@var{bw})\n\
+Computes the distance transform of the image @var{bw}.\n\
+@var{bw} should be a binary 2D array, either a Boolean array or a\n\
+numeric array containing only the values 0 and 1.\n\
+The return value @var{D} is a double matrix of the same size as @var{bw}.\n\
+Elements with value 0 are considered background pixels, elements\n\
+with value 1 are considered object pixels. The return value\n\
+for each background pixel is the distance (according to the chosen\n\
+metric) to the closest object pixel. For each object pixel the\n\
+return value is 0.\n\
+\n\
+@deftypefnx{Loadable Function} {@var{D} =} __bwdist__(@var{bw}, @var{method})\n\
+\n\
+@var{method} is a string to choose the distance metric. Currently\n\
+available metrics are 'euclidean', 'chessboard', 'cityblock' and\n\
+'quasi-euclidean', which may each be abbreviated\n\
+to any string starting with 'e', 'ch', 'ci' and 'q', respectively.\n\
+If @var{method} is not specified, 'euclidean' is the default.\n\
+\n\
+@deftypefnx {Loadable Function} {[@var{D},@var{C}] =} __bwdist__(@var{bw}, @var{method})\n\
+\n\
+If a second output argument is given, the linear index for the\n\
+closest object pixel is returned for each pixel. (For object\n\
+pixels, the index points to the pixel itself.) The return value\n\
+@var{C} is a matrix the same size as @var{bw}.\n\n\
+@end deftypefn")
+{
+  const int nargin = args.length();
+  octave_value_list retval;
+
+  /* Check for proper number of input and output arguments */
+  if ((nargin < 1) || (nargin>2)) {
+    error ("bwdist accepts only one or two input parameters.");
+  }
+  else if (nargout > 2) {
+    error ("bwdist returns at most 2 output parameters.");
+  }
+  else {
+    /* Make sure input is a matrix */
+    const Matrix bw = args(0).matrix_value();
+    if (error_state) {
+      error ("bwdist input argument must be a matrix");
+      return retval;
+    }
+    /* Warn if input is not a binary image */
+    if(bw.any_element_not_one_or_zero()) {
+      warning ("bwdist input contains values other than 1 and 0.");
+    }
+
+    /* Everything seems to be OK to proceed */
+    dim_vector dims = bw.dims();
+    int rows = dims(0);
+    int cols = dims(1);
+    int caseMethod = 0; // Default 0 means Euclidean
+    if(nargin > 1) {
+      charMatrix method = args(1).char_matrix_value();
+      if(method(0) == 'e') caseMethod = 0; // Euclidean;
+      else if (method(0) == 'c') {
+        if(method(1) == 'h') caseMethod = 1; // chessboard
+        else if(method(1) == 'i') caseMethod = 2; // cityblock
+      }
+      else if(method(0) == 'q') caseMethod = 3; // quasi-Euclidean
+      else {
+        warning ("unknown metric, using 'euclidean'");
+        caseMethod = 0;
+      }
+    }
+
+    if (!error_state) {
+      /* Allocate two arrays for temporary output values */
+      OCTAVE_LOCAL_BUFFER (short, xdist, dims.numel());
+      OCTAVE_LOCAL_BUFFER (short, ydist, dims.numel());
+
+      /* Create final output array */
+      Matrix D (rows, cols);
+
+      /* Call the appropriate C subroutine and compute output */
+      switch(caseMethod) {
+
+      case 1:
+        chessboard(bw, rows, cols, xdist, ydist);
+        for(int i=0; i<rows*cols; i++) {
+          D(i) = DIST_CHESSBOARD(xdist[i], ydist[i]);
+        }
+        break;
+
+      case 2:
+        cityblock(bw, rows, cols, xdist, ydist);
+        for(int i=0; i<rows*cols; i++) {
+          D(i) = DIST_CITYBLOCK(xdist[i], ydist[i]);
+        }
+        break;
+
+      case 3:
+        quasi_euclidean(bw, rows, cols, xdist, ydist);
+        for(int i=0; i<rows*cols; i++) {
+          D(i) = DIST_QUASI_EUCLIDEAN(xdist[i], ydist[i]);
+        }
+        break;
+
+      case 0:
+      default:
+        euclidean(bw, rows, cols, xdist, ydist);
+        /* Remember sqrt() for the final output */
+        for(int i=0; i<rows*cols; i++) {
+          D(i) = sqrt((double)DIST_EUCLIDEAN(xdist[i], ydist[i]));
+        }
+        break;
+      }
+
+      retval(0) = D;
+
+      if(nargout > 1) {
+        /* Create a second output array */
+        Matrix C (rows, cols);
+        /* Compute optional 'index to closest object pixel' */
+        for(int i=0; i<rows*cols; i++) {
+          C (i) = i+1 - xdist[i] - ydist[i]*rows;
+        }
+        retval(1) = C;
+      }
+    }
+  }
+  return retval;
+}
+
+/*
+%!shared bw, out
+%!
+%! bw = [0   1   0   1   0   1   1   0
+%!       0   0   0   1   1   0   0   0
+%!       0   0   0   1   1   0   0   0
+%!       0   0   0   1   1   0   0   0
+%!       0   0   1   1   1   1   1   1
+%!       1   1   1   1   0   0   0   1
+%!       1   1   1   0   0   0   1   0
+%!       0   0   1   0   0   0   1   1];
+%!
+%! out = [ 1.00000   0.00000   1.00000   0.00000   1.00000   0.00000   0.00000   1.00000
+%!         1.41421   1.00000   1.00000   0.00000   0.00000   1.00000   1.00000   1.41421
+%!         2.23607   2.00000   1.00000   0.00000   0.00000   1.00000   2.00000   2.00000
+%!         2.00000   1.41421   1.00000   0.00000   0.00000   1.00000   1.00000   1.00000
+%!         1.00000   1.00000   0.00000   0.00000   0.00000   0.00000   0.00000   0.00000
+%!         0.00000   0.00000   0.00000   0.00000   1.00000   1.00000   1.00000   0.00000
+%!         0.00000   0.00000   0.00000   1.00000   1.41421   1.00000   0.00000   1.00000
+%!         1.00000   1.00000   0.00000   1.00000   2.00000   1.00000   0.00000   0.00000];
+%!
+%!assert (bwdist (bw, "euclidean"), out, 0.0001);
+%!assert (bwdist (logical (bw), "euclidean"), out, 0.0001);
+%!
+%! out = [ 1   0   1   0   1   0   0   1
+%!         1   1   1   0   0   1   1   1
+%!         2   2   1   0   0   1   2   2
+%!         2   1   1   0   0   1   1   1
+%!         1   1   0   0   0   0   0   0
+%!         0   0   0   0   1   1   1   0
+%!         0   0   0   1   1   1   0   1
+%!         1   1   0   1   2   1   0   0];
+%!
+%!assert (bwdist (bw, "chessboard"), out);
+%!
+%! out = [ 1   0   1   0   1   0   0   1
+%!         2   1   1   0   0   1   1   2
+%!         3   2   1   0   0   1   2   2
+%!         2   2   1   0   0   1   1   1
+%!         1   1   0   0   0   0   0   0
+%!         0   0   0   0   1   1   1   0
+%!         0   0   0   1   2   1   0   1
+%!         1   1   0   1   2   1   0   0];
+%!
+%!assert (bwdist (bw, "cityblock"), out);
+%!
+%! out = [ 1.00000   0.00000   1.00000   0.00000   1.00000   0.00000   0.00000   1.00000
+%!         1.41421   1.00000   1.00000   0.00000   0.00000   1.00000   1.00000   1.41421
+%!         2.41421   2.00000   1.00000   0.00000   0.00000   1.00000   2.00000   2.00000
+%!         2.00000   1.41421   1.00000   0.00000   0.00000   1.00000   1.00000   1.00000
+%!         1.00000   1.00000   0.00000   0.00000   0.00000   0.00000   0.00000   0.00000
+%!         0.00000   0.00000   0.00000   0.00000   1.00000   1.00000   1.00000   0.00000
+%!         0.00000   0.00000   0.00000   1.00000   1.41421   1.00000   0.00000   1.00000
+%!         1.00000   1.00000   0.00000   1.00000   2.00000   1.00000   0.00000   0.00000];
+%!
+%!assert (bwdist (bw, "quasi-euclidean"), out, 0.0001);
+%!
+%!error bwdist (magic (5));
+%!error bwdist (magic (5), "euclidean");
+*/