We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
profile_line gives wrong output for a binary mask
## Description

As of now (skimage 0.12.3), profile_line sometimes returns wrong output for binary masks (np.array(dtype=bool)). See below for an example. If the image is cast to an uint8 first, it returns the expected result.

A possible patch might be even just specifying the allowed dtypes in the docstring.
## Way to reproduce

``` python
from numpy import meshgrid, pi, cos, sin, all, uint8
from skimage.measure import profile_line

shape = (200, 200)
center_x, center_y = (140, 150)
radius = 20
x, y = meshgrid(range(shape[1]), range(shape[0]))
mask = (y - center_y)**2 + (x - center_x)**2 < radius**2
src = (center_y, center_x)
phi = 4*pi/9.
dy = 31 * cos(phi)
dx = 31 * sin(phi)
dst = (center_y + dy, center_x + dx)

profile_uint8 = profile_line(mask.astype(uint8), src, dst)
print profile_uint8
assert all(profile_uint8[:radius] == 1)

profile_bool = profile_line(mask, src, dst)
print profile_bool
assert all(profile_bool[:radius] == 1) # Fails

assert all(profile_bool == profile_uint8) # Fails
```

The output is (there is a zero in the middle of the profile_line output):

```
[ 1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.
  1.  1.  1.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.]
[ 1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  0. (ZERO HERE?!)  1.  1.
  1.  1.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.]

---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-24-1a94903a5586> in <module>()
     19 profile_bool = profile_line(mask, src, dst)
     20 print profile_bool
---> 21 assert all(profile_bool[:radius] == 1) # Fails
     22 
     23 assert all(profile_bool == profile_uint8) # Fails

AssertionError: 
```


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `skimage/measure/profile.py`
Content:
```
1 import numpy as np
2 from scipy import ndimage as ndi
3 
4 
5 def profile_line(image, src, dst, linewidth=1,
6                  order=1, mode='constant', cval=0.0,
7                  *, reduce_func=np.mean):
8     """Return the intensity profile of an image measured along a scan line.
9 
10     Parameters
11     ----------
12     image : numeric array, shape (M, N[, C])
13         The image, either grayscale (2D array) or multichannel
14         (3D array, where the final axis contains the channel
15         information).
16     src : 2-tuple of numeric scalar (float or int)
17         The start point of the scan line.
18     dst : 2-tuple of numeric scalar (float or int)
19         The end point of the scan line. The destination point is *included*
20         in the profile, in contrast to standard numpy indexing.
21     linewidth : int, optional
22         Width of the scan, perpendicular to the line
23     order : int in {0, 1, 2, 3, 4, 5}, optional
24         The order of the spline interpolation to compute image values at
25         non-integer coordinates. 0 means nearest-neighbor interpolation.
26     mode : {'constant', 'nearest', 'reflect', 'mirror', 'wrap'}, optional
27         How to compute any values falling outside of the image.
28     cval : float, optional
29         If `mode` is 'constant', what constant value to use outside the image.
30     reduce_func : callable, optional
31         Function used to calculate the aggregation of pixel values
32         perpendicular to the profile_line direction when `linewidth` > 1.
33         If set to None the unreduced array will be returned.
34 
35     Returns
36     -------
37     return_value : array
38         The intensity profile along the scan line. The length of the profile
39         is the ceil of the computed length of the scan line.
40 
41     Examples
42     --------
43     >>> x = np.array([[1, 1, 1, 2, 2, 2]])
44     >>> img = np.vstack([np.zeros_like(x), x, x, x, np.zeros_like(x)])
45     >>> img
46     array([[0, 0, 0, 0, 0, 0],
47            [1, 1, 1, 2, 2, 2],
48            [1, 1, 1, 2, 2, 2],
49            [1, 1, 1, 2, 2, 2],
50            [0, 0, 0, 0, 0, 0]])
51     >>> profile_line(img, (2, 1), (2, 4))
52     array([1., 1., 2., 2.])
53     >>> profile_line(img, (1, 0), (1, 6), cval=4)
54     array([1., 1., 1., 2., 2., 2., 4.])
55 
56     The destination point is included in the profile, in contrast to
57     standard numpy indexing.
58     For example:
59 
60     >>> profile_line(img, (1, 0), (1, 6))  # The final point is out of bounds
61     array([1., 1., 1., 2., 2., 2., 0.])
62     >>> profile_line(img, (1, 0), (1, 5))  # This accesses the full first row
63     array([1., 1., 1., 2., 2., 2.])
64 
65     For different reduce_func inputs:
66 
67     >>> profile_line(img, (1, 0), (1, 3), linewidth=3, reduce_func=np.mean)
68     array([0.66666667, 0.66666667, 0.66666667, 1.33333333])
69     >>> profile_line(img, (1, 0), (1, 3), linewidth=3, reduce_func=np.max)
70     array([1, 1, 1, 2])
71     >>> profile_line(img, (1, 0), (1, 3), linewidth=3, reduce_func=np.sum)
72     array([2, 2, 2, 4])
73 
74     The unreduced array will be returned when `reduce_func` is None or when
75     `reduce_func` acts on each pixel value individually.
76 
77     >>> profile_line(img, (1, 2), (4, 2), linewidth=3, order=0,
78     ...     reduce_func=None)
79     array([[1, 1, 2],
80            [1, 1, 2],
81            [1, 1, 2],
82            [0, 0, 0]])
83     >>> profile_line(img, (1, 0), (1, 3), linewidth=3, reduce_func=np.sqrt)
84     array([[1.        , 1.        , 0.        ],
85            [1.        , 1.        , 0.        ],
86            [1.        , 1.        , 0.        ],
87            [1.41421356, 1.41421356, 0.        ]])
88     """
89     perp_lines = _line_profile_coordinates(src, dst, linewidth=linewidth)
90     if image.ndim == 3:
91         pixels = [ndi.map_coordinates(image[..., i], perp_lines,
92                                       order=order, mode=mode, cval=cval)
93                   for i in range(image.shape[2])]
94         pixels = np.transpose(np.asarray(pixels), (1, 2, 0))
95     else:
96         pixels = ndi.map_coordinates(image, perp_lines,
97                                      order=order, mode=mode, cval=cval)
98     # The outputted array with reduce_func=None gives an array where the
99     # row values (axis=1) are flipped. Here, we make this consistent.
100     pixels = np.flip(pixels, axis=1)
101 
102     if reduce_func is None:
103         intensities = pixels
104     else:
105         try:
106             intensities = reduce_func(pixels, axis=1)
107         except TypeError:  # function doesn't allow axis kwarg
108             intensities = np.apply_along_axis(reduce_func, arr=pixels, axis=1)
109 
110     return intensities
111 
112 
113 def _line_profile_coordinates(src, dst, linewidth=1):
114     """Return the coordinates of the profile of an image along a scan line.
115 
116     Parameters
117     ----------
118     src : 2-tuple of numeric scalar (float or int)
119         The start point of the scan line.
120     dst : 2-tuple of numeric scalar (float or int)
121         The end point of the scan line.
122     linewidth : int, optional
123         Width of the scan, perpendicular to the line
124 
125     Returns
126     -------
127     coords : array, shape (2, N, C), float
128         The coordinates of the profile along the scan line. The length of the
129         profile is the ceil of the computed length of the scan line.
130 
131     Notes
132     -----
133     This is a utility method meant to be used internally by skimage functions.
134     The destination point is included in the profile, in contrast to
135     standard numpy indexing.
136     """
137     src_row, src_col = src = np.asarray(src, dtype=float)
138     dst_row, dst_col = dst = np.asarray(dst, dtype=float)
139     d_row, d_col = dst - src
140     theta = np.arctan2(d_row, d_col)
141 
142     length = int(np.ceil(np.hypot(d_row, d_col) + 1))
143     # we add one above because we include the last point in the profile
144     # (in contrast to standard numpy indexing)
145     line_col = np.linspace(src_col, dst_col, length)
146     line_row = np.linspace(src_row, dst_row, length)
147 
148     # we subtract 1 from linewidth to change from pixel-counting
149     # (make this line 3 pixels wide) to point distances (the
150     # distance between pixel centers)
151     col_width = (linewidth - 1) * np.sin(-theta) / 2
152     row_width = (linewidth - 1) * np.cos(theta) / 2
153     perp_rows = np.array([np.linspace(row_i - row_width, row_i + row_width,
154                                       linewidth) for row_i in line_row])
155     perp_cols = np.array([np.linspace(col_i - col_width, col_i + col_width,
156                                       linewidth) for col_i in line_col])
157     return np.array([perp_rows, perp_cols])
158
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/skimage/measure/profile.py b/skimage/measure/profile.py
--- a/skimage/measure/profile.py
+++ b/skimage/measure/profile.py
@@ -1,9 +1,10 @@
+from warnings import warn
 import numpy as np
 from scipy import ndimage as ndi
 
 
 def profile_line(image, src, dst, linewidth=1,
-                 order=1, mode='constant', cval=0.0,
+                 order=None, mode='constant', cval=0.0,
                  *, reduce_func=np.mean):
     """Return the intensity profile of an image measured along a scan line.
 
@@ -21,8 +22,9 @@
     linewidth : int, optional
         Width of the scan, perpendicular to the line
     order : int in {0, 1, 2, 3, 4, 5}, optional
-        The order of the spline interpolation to compute image values at
-        non-integer coordinates. 0 means nearest-neighbor interpolation.
+        The order of the spline interpolation, default is 0 if
+        image.dtype is bool and 1 otherwise. The order has to be in
+        the range 0-5. See `skimage.transform.warp` for detail.
     mode : {'constant', 'nearest', 'reflect', 'mirror', 'wrap'}, optional
         How to compute any values falling outside of the image.
     cval : float, optional
@@ -86,14 +88,26 @@
            [1.        , 1.        , 0.        ],
            [1.41421356, 1.41421356, 0.        ]])
     """
+    if order is None:
+        order = 0 if image.dtype == bool else 1
+
+    if image.dtype == bool and order != 0:
+        warn("Input image dtype is bool. Interpolation is not defined "
+             "with bool data type. Please set order to 0 or explicitely "
+             "cast input image to another data type. Starting from version "
+             "0.19 a ValueError will be raised instead of this warning.",
+             FutureWarning, stacklevel=2)
+
     perp_lines = _line_profile_coordinates(src, dst, linewidth=linewidth)
     if image.ndim == 3:
         pixels = [ndi.map_coordinates(image[..., i], perp_lines,
-                                      order=order, mode=mode, cval=cval)
-                  for i in range(image.shape[2])]
+                                      prefilter=order > 1,
+                                      order=order, mode=mode,
+                                      cval=cval) for i in
+                  range(image.shape[2])]
         pixels = np.transpose(np.asarray(pixels), (1, 2, 0))
     else:
-        pixels = ndi.map_coordinates(image, perp_lines,
+        pixels = ndi.map_coordinates(image, perp_lines, prefilter=order > 1,
                                      order=order, mode=mode, cval=cval)
     # The outputted array with reduce_func=None gives an array where the
     # row values (axis=1) are flipped. Here, we make this consistent.

{"golden_diff": "diff --git a/skimage/measure/profile.py b/skimage/measure/profile.py\n--- a/skimage/measure/profile.py\n+++ b/skimage/measure/profile.py\n@@ -1,9 +1,10 @@\n+from warnings import warn\n import numpy as np\n from scipy import ndimage as ndi\n \n \n def profile_line(image, src, dst, linewidth=1,\n-                 order=1, mode='constant', cval=0.0,\n+                 order=None, mode='constant', cval=0.0,\n                  *, reduce_func=np.mean):\n     \"\"\"Return the intensity profile of an image measured along a scan line.\n \n@@ -21,8 +22,9 @@\n     linewidth : int, optional\n         Width of the scan, perpendicular to the line\n     order : int in {0, 1, 2, 3, 4, 5}, optional\n-        The order of the spline interpolation to compute image values at\n-        non-integer coordinates. 0 means nearest-neighbor interpolation.\n+        The order of the spline interpolation, default is 0 if\n+        image.dtype is bool and 1 otherwise. The order has to be in\n+        the range 0-5. See `skimage.transform.warp` for detail.\n     mode : {'constant', 'nearest', 'reflect', 'mirror', 'wrap'}, optional\n         How to compute any values falling outside of the image.\n     cval : float, optional\n@@ -86,14 +88,26 @@\n            [1.        , 1.        , 0.        ],\n            [1.41421356, 1.41421356, 0.        ]])\n     \"\"\"\n+    if order is None:\n+        order = 0 if image.dtype == bool else 1\n+\n+    if image.dtype == bool and order != 0:\n+        warn(\"Input image dtype is bool. Interpolation is not defined \"\n+             \"with bool data type. Please set order to 0 or explicitely \"\n+             \"cast input image to another data type. Starting from version \"\n+             \"0.19 a ValueError will be raised instead of this warning.\",\n+             FutureWarning, stacklevel=2)\n+\n     perp_lines = _line_profile_coordinates(src, dst, linewidth=linewidth)\n     if image.ndim == 3:\n         pixels = [ndi.map_coordinates(image[..., i], perp_lines,\n-                                      order=order, mode=mode, cval=cval)\n-                  for i in range(image.shape[2])]\n+                                      prefilter=order > 1,\n+                                      order=order, mode=mode,\n+                                      cval=cval) for i in\n+                  range(image.shape[2])]\n         pixels = np.transpose(np.asarray(pixels), (1, 2, 0))\n     else:\n-        pixels = ndi.map_coordinates(image, perp_lines,\n+        pixels = ndi.map_coordinates(image, perp_lines, prefilter=order > 1,\n                                      order=order, mode=mode, cval=cval)\n     # The outputted array with reduce_func=None gives an array where the\n     # row values (axis=1) are flipped. Here, we make this consistent.\n", "issue": "profile_line gives wrong output for a binary mask\n## Description\n\nAs of now (skimage 0.12.3), profile_line sometimes returns wrong output for binary masks (np.array(dtype=bool)). See below for an example. If the image is cast to an uint8 first, it returns the expected result.\n\nA possible patch might be even just specifying the allowed dtypes in the docstring.\n## Way to reproduce\n\n``` python\nfrom numpy import meshgrid, pi, cos, sin, all, uint8\nfrom skimage.measure import profile_line\n\nshape = (200, 200)\ncenter_x, center_y = (140, 150)\nradius = 20\nx, y = meshgrid(range(shape[1]), range(shape[0]))\nmask = (y - center_y)**2 + (x - center_x)**2 < radius**2\nsrc = (center_y, center_x)\nphi = 4*pi/9.\ndy = 31 * cos(phi)\ndx = 31 * sin(phi)\ndst = (center_y + dy, center_x + dx)\n\nprofile_uint8 = profile_line(mask.astype(uint8), src, dst)\nprint profile_uint8\nassert all(profile_uint8[:radius] == 1)\n\nprofile_bool = profile_line(mask, src, dst)\nprint profile_bool\nassert all(profile_bool[:radius] == 1) # Fails\n\nassert all(profile_bool == profile_uint8) # Fails\n```\n\nThe output is (there is a zero in the middle of the profile_line output):\n\n```\n[ 1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.\n  1.  1.  1.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.]\n[ 1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  0. (ZERO HERE?!)  1.  1.\n  1.  1.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.]\n\n---------------------------------------------------------------------------\nAssertionError                            Traceback (most recent call last)\n<ipython-input-24-1a94903a5586> in <module>()\n     19 profile_bool = profile_line(mask, src, dst)\n     20 print profile_bool\n---> 21 assert all(profile_bool[:radius] == 1) # Fails\n     22 \n     23 assert all(profile_bool == profile_uint8) # Fails\n\nAssertionError: \n```\n\n", "before_files": [{"content": "import numpy as np\nfrom scipy import ndimage as ndi\n\n\ndef profile_line(image, src, dst, linewidth=1,\n                 order=1, mode='constant', cval=0.0,\n                 *, reduce_func=np.mean):\n    \"\"\"Return the intensity profile of an image measured along a scan line.\n\n    Parameters\n    ----------\n    image : numeric array, shape (M, N[, C])\n        The image, either grayscale (2D array) or multichannel\n        (3D array, where the final axis contains the channel\n        information).\n    src : 2-tuple of numeric scalar (float or int)\n        The start point of the scan line.\n    dst : 2-tuple of numeric scalar (float or int)\n        The end point of the scan line. The destination point is *included*\n        in the profile, in contrast to standard numpy indexing.\n    linewidth : int, optional\n        Width of the scan, perpendicular to the line\n    order : int in {0, 1, 2, 3, 4, 5}, optional\n        The order of the spline interpolation to compute image values at\n        non-integer coordinates. 0 means nearest-neighbor interpolation.\n    mode : {'constant', 'nearest', 'reflect', 'mirror', 'wrap'}, optional\n        How to compute any values falling outside of the image.\n    cval : float, optional\n        If `mode` is 'constant', what constant value to use outside the image.\n    reduce_func : callable, optional\n        Function used to calculate the aggregation of pixel values\n        perpendicular to the profile_line direction when `linewidth` > 1.\n        If set to None the unreduced array will be returned.\n\n    Returns\n    -------\n    return_value : array\n        The intensity profile along the scan line. The length of the profile\n        is the ceil of the computed length of the scan line.\n\n    Examples\n    --------\n    >>> x = np.array([[1, 1, 1, 2, 2, 2]])\n    >>> img = np.vstack([np.zeros_like(x), x, x, x, np.zeros_like(x)])\n    >>> img\n    array([[0, 0, 0, 0, 0, 0],\n           [1, 1, 1, 2, 2, 2],\n           [1, 1, 1, 2, 2, 2],\n           [1, 1, 1, 2, 2, 2],\n           [0, 0, 0, 0, 0, 0]])\n    >>> profile_line(img, (2, 1), (2, 4))\n    array([1., 1., 2., 2.])\n    >>> profile_line(img, (1, 0), (1, 6), cval=4)\n    array([1., 1., 1., 2., 2., 2., 4.])\n\n    The destination point is included in the profile, in contrast to\n    standard numpy indexing.\n    For example:\n\n    >>> profile_line(img, (1, 0), (1, 6))  # The final point is out of bounds\n    array([1., 1., 1., 2., 2., 2., 0.])\n    >>> profile_line(img, (1, 0), (1, 5))  # This accesses the full first row\n    array([1., 1., 1., 2., 2., 2.])\n\n    For different reduce_func inputs:\n\n    >>> profile_line(img, (1, 0), (1, 3), linewidth=3, reduce_func=np.mean)\n    array([0.66666667, 0.66666667, 0.66666667, 1.33333333])\n    >>> profile_line(img, (1, 0), (1, 3), linewidth=3, reduce_func=np.max)\n    array([1, 1, 1, 2])\n    >>> profile_line(img, (1, 0), (1, 3), linewidth=3, reduce_func=np.sum)\n    array([2, 2, 2, 4])\n\n    The unreduced array will be returned when `reduce_func` is None or when\n    `reduce_func` acts on each pixel value individually.\n\n    >>> profile_line(img, (1, 2), (4, 2), linewidth=3, order=0,\n    ...     reduce_func=None)\n    array([[1, 1, 2],\n           [1, 1, 2],\n           [1, 1, 2],\n           [0, 0, 0]])\n    >>> profile_line(img, (1, 0), (1, 3), linewidth=3, reduce_func=np.sqrt)\n    array([[1.        , 1.        , 0.        ],\n           [1.        , 1.        , 0.        ],\n           [1.        , 1.        , 0.        ],\n           [1.41421356, 1.41421356, 0.        ]])\n    \"\"\"\n    perp_lines = _line_profile_coordinates(src, dst, linewidth=linewidth)\n    if image.ndim == 3:\n        pixels = [ndi.map_coordinates(image[..., i], perp_lines,\n                                      order=order, mode=mode, cval=cval)\n                  for i in range(image.shape[2])]\n        pixels = np.transpose(np.asarray(pixels), (1, 2, 0))\n    else:\n        pixels = ndi.map_coordinates(image, perp_lines,\n                                     order=order, mode=mode, cval=cval)\n    # The outputted array with reduce_func=None gives an array where the\n    # row values (axis=1) are flipped. Here, we make this consistent.\n    pixels = np.flip(pixels, axis=1)\n\n    if reduce_func is None:\n        intensities = pixels\n    else:\n        try:\n            intensities = reduce_func(pixels, axis=1)\n        except TypeError:  # function doesn't allow axis kwarg\n            intensities = np.apply_along_axis(reduce_func, arr=pixels, axis=1)\n\n    return intensities\n\n\ndef _line_profile_coordinates(src, dst, linewidth=1):\n    \"\"\"Return the coordinates of the profile of an image along a scan line.\n\n    Parameters\n    ----------\n    src : 2-tuple of numeric scalar (float or int)\n        The start point of the scan line.\n    dst : 2-tuple of numeric scalar (float or int)\n        The end point of the scan line.\n    linewidth : int, optional\n        Width of the scan, perpendicular to the line\n\n    Returns\n    -------\n    coords : array, shape (2, N, C), float\n        The coordinates of the profile along the scan line. The length of the\n        profile is the ceil of the computed length of the scan line.\n\n    Notes\n    -----\n    This is a utility method meant to be used internally by skimage functions.\n    The destination point is included in the profile, in contrast to\n    standard numpy indexing.\n    \"\"\"\n    src_row, src_col = src = np.asarray(src, dtype=float)\n    dst_row, dst_col = dst = np.asarray(dst, dtype=float)\n    d_row, d_col = dst - src\n    theta = np.arctan2(d_row, d_col)\n\n    length = int(np.ceil(np.hypot(d_row, d_col) + 1))\n    # we add one above because we include the last point in the profile\n    # (in contrast to standard numpy indexing)\n    line_col = np.linspace(src_col, dst_col, length)\n    line_row = np.linspace(src_row, dst_row, length)\n\n    # we subtract 1 from linewidth to change from pixel-counting\n    # (make this line 3 pixels wide) to point distances (the\n    # distance between pixel centers)\n    col_width = (linewidth - 1) * np.sin(-theta) / 2\n    row_width = (linewidth - 1) * np.cos(theta) / 2\n    perp_rows = np.array([np.linspace(row_i - row_width, row_i + row_width,\n                                      linewidth) for row_i in line_row])\n    perp_cols = np.array([np.linspace(col_i - col_width, col_i + col_width,\n                                      linewidth) for col_i in line_col])\n    return np.array([perp_rows, perp_cols])\n", "path": "skimage/measure/profile.py"}], "after_files": [{"content": "from warnings import warn\nimport numpy as np\nfrom scipy import ndimage as ndi\n\n\ndef profile_line(image, src, dst, linewidth=1,\n                 order=None, mode='constant', cval=0.0,\n                 *, reduce_func=np.mean):\n    \"\"\"Return the intensity profile of an image measured along a scan line.\n\n    Parameters\n    ----------\n    image : numeric array, shape (M, N[, C])\n        The image, either grayscale (2D array) or multichannel\n        (3D array, where the final axis contains the channel\n        information).\n    src : 2-tuple of numeric scalar (float or int)\n        The start point of the scan line.\n    dst : 2-tuple of numeric scalar (float or int)\n        The end point of the scan line. The destination point is *included*\n        in the profile, in contrast to standard numpy indexing.\n    linewidth : int, optional\n        Width of the scan, perpendicular to the line\n    order : int in {0, 1, 2, 3, 4, 5}, optional\n        The order of the spline interpolation, default is 0 if\n        image.dtype is bool and 1 otherwise. The order has to be in\n        the range 0-5. See `skimage.transform.warp` for detail.\n    mode : {'constant', 'nearest', 'reflect', 'mirror', 'wrap'}, optional\n        How to compute any values falling outside of the image.\n    cval : float, optional\n        If `mode` is 'constant', what constant value to use outside the image.\n    reduce_func : callable, optional\n        Function used to calculate the aggregation of pixel values\n        perpendicular to the profile_line direction when `linewidth` > 1.\n        If set to None the unreduced array will be returned.\n\n    Returns\n    -------\n    return_value : array\n        The intensity profile along the scan line. The length of the profile\n        is the ceil of the computed length of the scan line.\n\n    Examples\n    --------\n    >>> x = np.array([[1, 1, 1, 2, 2, 2]])\n    >>> img = np.vstack([np.zeros_like(x), x, x, x, np.zeros_like(x)])\n    >>> img\n    array([[0, 0, 0, 0, 0, 0],\n           [1, 1, 1, 2, 2, 2],\n           [1, 1, 1, 2, 2, 2],\n           [1, 1, 1, 2, 2, 2],\n           [0, 0, 0, 0, 0, 0]])\n    >>> profile_line(img, (2, 1), (2, 4))\n    array([1., 1., 2., 2.])\n    >>> profile_line(img, (1, 0), (1, 6), cval=4)\n    array([1., 1., 1., 2., 2., 2., 4.])\n\n    The destination point is included in the profile, in contrast to\n    standard numpy indexing.\n    For example:\n\n    >>> profile_line(img, (1, 0), (1, 6))  # The final point is out of bounds\n    array([1., 1., 1., 2., 2., 2., 0.])\n    >>> profile_line(img, (1, 0), (1, 5))  # This accesses the full first row\n    array([1., 1., 1., 2., 2., 2.])\n\n    For different reduce_func inputs:\n\n    >>> profile_line(img, (1, 0), (1, 3), linewidth=3, reduce_func=np.mean)\n    array([0.66666667, 0.66666667, 0.66666667, 1.33333333])\n    >>> profile_line(img, (1, 0), (1, 3), linewidth=3, reduce_func=np.max)\n    array([1, 1, 1, 2])\n    >>> profile_line(img, (1, 0), (1, 3), linewidth=3, reduce_func=np.sum)\n    array([2, 2, 2, 4])\n\n    The unreduced array will be returned when `reduce_func` is None or when\n    `reduce_func` acts on each pixel value individually.\n\n    >>> profile_line(img, (1, 2), (4, 2), linewidth=3, order=0,\n    ...     reduce_func=None)\n    array([[1, 1, 2],\n           [1, 1, 2],\n           [1, 1, 2],\n           [0, 0, 0]])\n    >>> profile_line(img, (1, 0), (1, 3), linewidth=3, reduce_func=np.sqrt)\n    array([[1.        , 1.        , 0.        ],\n           [1.        , 1.        , 0.        ],\n           [1.        , 1.        , 0.        ],\n           [1.41421356, 1.41421356, 0.        ]])\n    \"\"\"\n    if order is None:\n        order = 0 if image.dtype == bool else 1\n\n    if image.dtype == bool and order != 0:\n        warn(\"Input image dtype is bool. Interpolation is not defined \"\n             \"with bool data type. Please set order to 0 or explicitely \"\n             \"cast input image to another data type. Starting from version \"\n             \"0.19 a ValueError will be raised instead of this warning.\",\n             FutureWarning, stacklevel=2)\n\n    perp_lines = _line_profile_coordinates(src, dst, linewidth=linewidth)\n    if image.ndim == 3:\n        pixels = [ndi.map_coordinates(image[..., i], perp_lines,\n                                      prefilter=order > 1,\n                                      order=order, mode=mode,\n                                      cval=cval) for i in\n                  range(image.shape[2])]\n        pixels = np.transpose(np.asarray(pixels), (1, 2, 0))\n    else:\n        pixels = ndi.map_coordinates(image, perp_lines, prefilter=order > 1,\n                                     order=order, mode=mode, cval=cval)\n    # The outputted array with reduce_func=None gives an array where the\n    # row values (axis=1) are flipped. Here, we make this consistent.\n    pixels = np.flip(pixels, axis=1)\n\n    if reduce_func is None:\n        intensities = pixels\n    else:\n        try:\n            intensities = reduce_func(pixels, axis=1)\n        except TypeError:  # function doesn't allow axis kwarg\n            intensities = np.apply_along_axis(reduce_func, arr=pixels, axis=1)\n\n    return intensities\n\n\ndef _line_profile_coordinates(src, dst, linewidth=1):\n    \"\"\"Return the coordinates of the profile of an image along a scan line.\n\n    Parameters\n    ----------\n    src : 2-tuple of numeric scalar (float or int)\n        The start point of the scan line.\n    dst : 2-tuple of numeric scalar (float or int)\n        The end point of the scan line.\n    linewidth : int, optional\n        Width of the scan, perpendicular to the line\n\n    Returns\n    -------\n    coords : array, shape (2, N, C), float\n        The coordinates of the profile along the scan line. The length of the\n        profile is the ceil of the computed length of the scan line.\n\n    Notes\n    -----\n    This is a utility method meant to be used internally by skimage functions.\n    The destination point is included in the profile, in contrast to\n    standard numpy indexing.\n    \"\"\"\n    src_row, src_col = src = np.asarray(src, dtype=float)\n    dst_row, dst_col = dst = np.asarray(dst, dtype=float)\n    d_row, d_col = dst - src\n    theta = np.arctan2(d_row, d_col)\n\n    length = int(np.ceil(np.hypot(d_row, d_col) + 1))\n    # we add one above because we include the last point in the profile\n    # (in contrast to standard numpy indexing)\n    line_col = np.linspace(src_col, dst_col, length)\n    line_row = np.linspace(src_row, dst_row, length)\n\n    # we subtract 1 from linewidth to change from pixel-counting\n    # (make this line 3 pixels wide) to point distances (the\n    # distance between pixel centers)\n    col_width = (linewidth - 1) * np.sin(-theta) / 2\n    row_width = (linewidth - 1) * np.cos(theta) / 2\n    perp_rows = np.array([np.linspace(row_i - row_width, row_i + row_width,\n                                      linewidth) for row_i in line_row])\n    perp_cols = np.array([np.linspace(col_i - col_width, col_i + col_width,\n                                      linewidth) for col_i in line_col])\n    return np.array([perp_rows, perp_cols])\n", "path": "skimage/measure/profile.py"}]}