We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
peak_local_max Incorrect output type 
This [function](http://scikit-image.org/docs/dev/api/skimage.feature.html#peak-local-max) is returning a `list` instead of an `ndarray` if no peaks are detected.

I traced the problem till this [line](https://github.com/scikit-image/scikit-image/blob/master/skimage/feature/peak.py#L122). However, I have to check if there is other case (beyond this line) that produces an incorrect output.

I will work on it this weekend and submit a pull-request or a code snippet here


--- 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/feature/peak.py`
Content:
```
1 import numpy as np
2 import scipy.ndimage as ndi
3 from ..filters import rank_order
4 
5 
6 def peak_local_max(image, min_distance=10, threshold_abs=0, threshold_rel=0.1,
7                    exclude_border=True, indices=True, num_peaks=np.inf,
8                    footprint=None, labels=None):
9     """
10     Find peaks in an image, and return them as coordinates or a boolean array.
11 
12     Peaks are the local maxima in a region of `2 * min_distance + 1`
13     (i.e. peaks are separated by at least `min_distance`).
14 
15     NOTE: If peaks are flat (i.e. multiple adjacent pixels have identical
16     intensities), the coordinates of all such pixels are returned.
17 
18     Parameters
19     ----------
20     image : ndarray of floats
21         Input image.
22     min_distance : int
23         Minimum number of pixels separating peaks in a region of `2 *
24         min_distance + 1` (i.e. peaks are separated by at least
25         `min_distance`). If `exclude_border` is True, this value also excludes
26         a border `min_distance` from the image boundary.
27         To find the maximum number of peaks, use `min_distance=1`.
28     threshold_abs : float
29         Minimum intensity of peaks.
30     threshold_rel : float
31         Minimum intensity of peaks calculated as `max(image) * threshold_rel`.
32     exclude_border : bool
33         If True, `min_distance` excludes peaks from the border of the image as
34         well as from each other.
35     indices : bool
36         If True, the output will be an array representing peak coordinates.
37         If False, the output will be a boolean array shaped as `image.shape`
38         with peaks present at True elements.
39     num_peaks : int
40         Maximum number of peaks. When the number of peaks exceeds `num_peaks`,
41         return `num_peaks` peaks based on highest peak intensity.
42     footprint : ndarray of bools, optional
43         If provided, `footprint == 1` represents the local region within which
44         to search for peaks at every point in `image`.  Overrides
45         `min_distance`, except for border exclusion if `exclude_border=True`.
46     labels : ndarray of ints, optional
47         If provided, each unique region `labels == value` represents a unique
48         region to search for peaks. Zero is reserved for background.
49 
50     Returns
51     -------
52     output : ndarray or ndarray of bools
53 
54         * If `indices = True`  : (row, column, ...) coordinates of peaks.
55         * If `indices = False` : Boolean array shaped like `image`, with peaks
56           represented by True values.
57 
58     Notes
59     -----
60     The peak local maximum function returns the coordinates of local peaks
61     (maxima) in a image. A maximum filter is used for finding local maxima.
62     This operation dilates the original image. After comparison between
63     dilated and original image, peak_local_max function returns the
64     coordinates of peaks where dilated image = original.
65 
66     Examples
67     --------
68     >>> img1 = np.zeros((7, 7))
69     >>> img1[3, 4] = 1
70     >>> img1[3, 2] = 1.5
71     >>> img1
72     array([[ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ],
73            [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ],
74            [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ],
75            [ 0. ,  0. ,  1.5,  0. ,  1. ,  0. ,  0. ],
76            [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ],
77            [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ],
78            [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ]])
79 
80     >>> peak_local_max(img1, min_distance=1)
81     array([[3, 2],
82            [3, 4]])
83 
84     >>> peak_local_max(img1, min_distance=2)
85     array([[3, 2]])
86 
87     >>> img2 = np.zeros((20, 20, 20))
88     >>> img2[10, 10, 10] = 1
89     >>> peak_local_max(img2, exclude_border=False)
90     array([[10, 10, 10]])
91 
92     """
93     out = np.zeros_like(image, dtype=np.bool)
94     # In the case of labels, recursively build and return an output
95     # operating on each label separately
96     if labels is not None:
97         label_values = np.unique(labels)
98         # Reorder label values to have consecutive integers (no gaps)
99         if np.any(np.diff(label_values) != 1):
100             mask = labels >= 1
101             labels[mask] = 1 + rank_order(labels[mask])[0].astype(labels.dtype)
102         labels = labels.astype(np.int32)
103 
104         # New values for new ordering
105         label_values = np.unique(labels)
106         for label in label_values[label_values != 0]:
107             maskim = (labels == label)
108             out += peak_local_max(image * maskim, min_distance=min_distance,
109                                   threshold_abs=threshold_abs,
110                                   threshold_rel=threshold_rel,
111                                   exclude_border=exclude_border,
112                                   indices=False, num_peaks=np.inf,
113                                   footprint=footprint, labels=None)
114 
115         if indices is True:
116             return np.transpose(out.nonzero())
117         else:
118             return out.astype(np.bool)
119 
120     if np.all(image == image.flat[0]):
121         if indices is True:
122             return []
123         else:
124             return out
125 
126     image = image.copy()
127     # Non maximum filter
128     if footprint is not None:
129         image_max = ndi.maximum_filter(image, footprint=footprint,
130                                        mode='constant')
131     else:
132         size = 2 * min_distance + 1
133         image_max = ndi.maximum_filter(image, size=size, mode='constant')
134     mask = (image == image_max)
135     image *= mask
136 
137     if exclude_border:
138         # zero out the image borders
139         for i in range(image.ndim):
140             image = image.swapaxes(0, i)
141             image[:min_distance] = 0
142             image[-min_distance:] = 0
143             image = image.swapaxes(0, i)
144 
145     # find top peak candidates above a threshold
146     peak_threshold = max(np.max(image.ravel()) * threshold_rel, threshold_abs)
147 
148     # get coordinates of peaks
149     coordinates = np.argwhere(image > peak_threshold)
150 
151     if coordinates.shape[0] > num_peaks:
152         intensities = image.flat[np.ravel_multi_index(coordinates.transpose(),image.shape)]
153         idx_maxsort = np.argsort(intensities)[::-1]
154         coordinates = coordinates[idx_maxsort][:num_peaks]
155 
156     if indices is True:
157         return coordinates
158     else:
159         nd_indices = tuple(coordinates.T)
160         out[nd_indices] = True
161         return out
162
```
--- 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/feature/peak.py b/skimage/feature/peak.py
--- a/skimage/feature/peak.py
+++ b/skimage/feature/peak.py
@@ -119,7 +119,7 @@
 
     if np.all(image == image.flat[0]):
         if indices is True:
-            return []
+            return np.empty((0, 2), np.int)
         else:
             return out

{"golden_diff": "diff --git a/skimage/feature/peak.py b/skimage/feature/peak.py\n--- a/skimage/feature/peak.py\n+++ b/skimage/feature/peak.py\n@@ -119,7 +119,7 @@\n \n     if np.all(image == image.flat[0]):\n         if indices is True:\n-            return []\n+            return np.empty((0, 2), np.int)\n         else:\n             return out\n", "issue": "peak_local_max Incorrect output type \nThis [function](http://scikit-image.org/docs/dev/api/skimage.feature.html#peak-local-max) is returning a `list` instead of an `ndarray` if no peaks are detected.\n\nI traced the problem till this [line](https://github.com/scikit-image/scikit-image/blob/master/skimage/feature/peak.py#L122). However, I have to check if there is other case (beyond this line) that produces an incorrect output.\n\nI will work on it this weekend and submit a pull-request or a code snippet here\n\n", "before_files": [{"content": "import numpy as np\nimport scipy.ndimage as ndi\nfrom ..filters import rank_order\n\n\ndef peak_local_max(image, min_distance=10, threshold_abs=0, threshold_rel=0.1,\n                   exclude_border=True, indices=True, num_peaks=np.inf,\n                   footprint=None, labels=None):\n    \"\"\"\n    Find peaks in an image, and return them as coordinates or a boolean array.\n\n    Peaks are the local maxima in a region of `2 * min_distance + 1`\n    (i.e. peaks are separated by at least `min_distance`).\n\n    NOTE: If peaks are flat (i.e. multiple adjacent pixels have identical\n    intensities), the coordinates of all such pixels are returned.\n\n    Parameters\n    ----------\n    image : ndarray of floats\n        Input image.\n    min_distance : int\n        Minimum number of pixels separating peaks in a region of `2 *\n        min_distance + 1` (i.e. peaks are separated by at least\n        `min_distance`). If `exclude_border` is True, this value also excludes\n        a border `min_distance` from the image boundary.\n        To find the maximum number of peaks, use `min_distance=1`.\n    threshold_abs : float\n        Minimum intensity of peaks.\n    threshold_rel : float\n        Minimum intensity of peaks calculated as `max(image) * threshold_rel`.\n    exclude_border : bool\n        If True, `min_distance` excludes peaks from the border of the image as\n        well as from each other.\n    indices : bool\n        If True, the output will be an array representing peak coordinates.\n        If False, the output will be a boolean array shaped as `image.shape`\n        with peaks present at True elements.\n    num_peaks : int\n        Maximum number of peaks. When the number of peaks exceeds `num_peaks`,\n        return `num_peaks` peaks based on highest peak intensity.\n    footprint : ndarray of bools, optional\n        If provided, `footprint == 1` represents the local region within which\n        to search for peaks at every point in `image`.  Overrides\n        `min_distance`, except for border exclusion if `exclude_border=True`.\n    labels : ndarray of ints, optional\n        If provided, each unique region `labels == value` represents a unique\n        region to search for peaks. Zero is reserved for background.\n\n    Returns\n    -------\n    output : ndarray or ndarray of bools\n\n        * If `indices = True`  : (row, column, ...) coordinates of peaks.\n        * If `indices = False` : Boolean array shaped like `image`, with peaks\n          represented by True values.\n\n    Notes\n    -----\n    The peak local maximum function returns the coordinates of local peaks\n    (maxima) in a image. A maximum filter is used for finding local maxima.\n    This operation dilates the original image. After comparison between\n    dilated and original image, peak_local_max function returns the\n    coordinates of peaks where dilated image = original.\n\n    Examples\n    --------\n    >>> img1 = np.zeros((7, 7))\n    >>> img1[3, 4] = 1\n    >>> img1[3, 2] = 1.5\n    >>> img1\n    array([[ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ],\n           [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ],\n           [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ],\n           [ 0. ,  0. ,  1.5,  0. ,  1. ,  0. ,  0. ],\n           [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ],\n           [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ],\n           [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ]])\n\n    >>> peak_local_max(img1, min_distance=1)\n    array([[3, 2],\n           [3, 4]])\n\n    >>> peak_local_max(img1, min_distance=2)\n    array([[3, 2]])\n\n    >>> img2 = np.zeros((20, 20, 20))\n    >>> img2[10, 10, 10] = 1\n    >>> peak_local_max(img2, exclude_border=False)\n    array([[10, 10, 10]])\n\n    \"\"\"\n    out = np.zeros_like(image, dtype=np.bool)\n    # In the case of labels, recursively build and return an output\n    # operating on each label separately\n    if labels is not None:\n        label_values = np.unique(labels)\n        # Reorder label values to have consecutive integers (no gaps)\n        if np.any(np.diff(label_values) != 1):\n            mask = labels >= 1\n            labels[mask] = 1 + rank_order(labels[mask])[0].astype(labels.dtype)\n        labels = labels.astype(np.int32)\n\n        # New values for new ordering\n        label_values = np.unique(labels)\n        for label in label_values[label_values != 0]:\n            maskim = (labels == label)\n            out += peak_local_max(image * maskim, min_distance=min_distance,\n                                  threshold_abs=threshold_abs,\n                                  threshold_rel=threshold_rel,\n                                  exclude_border=exclude_border,\n                                  indices=False, num_peaks=np.inf,\n                                  footprint=footprint, labels=None)\n\n        if indices is True:\n            return np.transpose(out.nonzero())\n        else:\n            return out.astype(np.bool)\n\n    if np.all(image == image.flat[0]):\n        if indices is True:\n            return []\n        else:\n            return out\n\n    image = image.copy()\n    # Non maximum filter\n    if footprint is not None:\n        image_max = ndi.maximum_filter(image, footprint=footprint,\n                                       mode='constant')\n    else:\n        size = 2 * min_distance + 1\n        image_max = ndi.maximum_filter(image, size=size, mode='constant')\n    mask = (image == image_max)\n    image *= mask\n\n    if exclude_border:\n        # zero out the image borders\n        for i in range(image.ndim):\n            image = image.swapaxes(0, i)\n            image[:min_distance] = 0\n            image[-min_distance:] = 0\n            image = image.swapaxes(0, i)\n\n    # find top peak candidates above a threshold\n    peak_threshold = max(np.max(image.ravel()) * threshold_rel, threshold_abs)\n\n    # get coordinates of peaks\n    coordinates = np.argwhere(image > peak_threshold)\n\n    if coordinates.shape[0] > num_peaks:\n        intensities = image.flat[np.ravel_multi_index(coordinates.transpose(),image.shape)]\n        idx_maxsort = np.argsort(intensities)[::-1]\n        coordinates = coordinates[idx_maxsort][:num_peaks]\n\n    if indices is True:\n        return coordinates\n    else:\n        nd_indices = tuple(coordinates.T)\n        out[nd_indices] = True\n        return out\n", "path": "skimage/feature/peak.py"}], "after_files": [{"content": "import numpy as np\nimport scipy.ndimage as ndi\nfrom ..filters import rank_order\n\n\ndef peak_local_max(image, min_distance=10, threshold_abs=0, threshold_rel=0.1,\n                   exclude_border=True, indices=True, num_peaks=np.inf,\n                   footprint=None, labels=None):\n    \"\"\"\n    Find peaks in an image, and return them as coordinates or a boolean array.\n\n    Peaks are the local maxima in a region of `2 * min_distance + 1`\n    (i.e. peaks are separated by at least `min_distance`).\n\n    NOTE: If peaks are flat (i.e. multiple adjacent pixels have identical\n    intensities), the coordinates of all such pixels are returned.\n\n    Parameters\n    ----------\n    image : ndarray of floats\n        Input image.\n    min_distance : int\n        Minimum number of pixels separating peaks in a region of `2 *\n        min_distance + 1` (i.e. peaks are separated by at least\n        `min_distance`). If `exclude_border` is True, this value also excludes\n        a border `min_distance` from the image boundary.\n        To find the maximum number of peaks, use `min_distance=1`.\n    threshold_abs : float\n        Minimum intensity of peaks.\n    threshold_rel : float\n        Minimum intensity of peaks calculated as `max(image) * threshold_rel`.\n    exclude_border : bool\n        If True, `min_distance` excludes peaks from the border of the image as\n        well as from each other.\n    indices : bool\n        If True, the output will be an array representing peak coordinates.\n        If False, the output will be a boolean array shaped as `image.shape`\n        with peaks present at True elements.\n    num_peaks : int\n        Maximum number of peaks. When the number of peaks exceeds `num_peaks`,\n        return `num_peaks` peaks based on highest peak intensity.\n    footprint : ndarray of bools, optional\n        If provided, `footprint == 1` represents the local region within which\n        to search for peaks at every point in `image`.  Overrides\n        `min_distance`, except for border exclusion if `exclude_border=True`.\n    labels : ndarray of ints, optional\n        If provided, each unique region `labels == value` represents a unique\n        region to search for peaks. Zero is reserved for background.\n\n    Returns\n    -------\n    output : ndarray or ndarray of bools\n\n        * If `indices = True`  : (row, column, ...) coordinates of peaks.\n        * If `indices = False` : Boolean array shaped like `image`, with peaks\n          represented by True values.\n\n    Notes\n    -----\n    The peak local maximum function returns the coordinates of local peaks\n    (maxima) in a image. A maximum filter is used for finding local maxima.\n    This operation dilates the original image. After comparison between\n    dilated and original image, peak_local_max function returns the\n    coordinates of peaks where dilated image = original.\n\n    Examples\n    --------\n    >>> img1 = np.zeros((7, 7))\n    >>> img1[3, 4] = 1\n    >>> img1[3, 2] = 1.5\n    >>> img1\n    array([[ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ],\n           [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ],\n           [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ],\n           [ 0. ,  0. ,  1.5,  0. ,  1. ,  0. ,  0. ],\n           [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ],\n           [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ],\n           [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ]])\n\n    >>> peak_local_max(img1, min_distance=1)\n    array([[3, 2],\n           [3, 4]])\n\n    >>> peak_local_max(img1, min_distance=2)\n    array([[3, 2]])\n\n    >>> img2 = np.zeros((20, 20, 20))\n    >>> img2[10, 10, 10] = 1\n    >>> peak_local_max(img2, exclude_border=False)\n    array([[10, 10, 10]])\n\n    \"\"\"\n    out = np.zeros_like(image, dtype=np.bool)\n    # In the case of labels, recursively build and return an output\n    # operating on each label separately\n    if labels is not None:\n        label_values = np.unique(labels)\n        # Reorder label values to have consecutive integers (no gaps)\n        if np.any(np.diff(label_values) != 1):\n            mask = labels >= 1\n            labels[mask] = 1 + rank_order(labels[mask])[0].astype(labels.dtype)\n        labels = labels.astype(np.int32)\n\n        # New values for new ordering\n        label_values = np.unique(labels)\n        for label in label_values[label_values != 0]:\n            maskim = (labels == label)\n            out += peak_local_max(image * maskim, min_distance=min_distance,\n                                  threshold_abs=threshold_abs,\n                                  threshold_rel=threshold_rel,\n                                  exclude_border=exclude_border,\n                                  indices=False, num_peaks=np.inf,\n                                  footprint=footprint, labels=None)\n\n        if indices is True:\n            return np.transpose(out.nonzero())\n        else:\n            return out.astype(np.bool)\n\n    if np.all(image == image.flat[0]):\n        if indices is True:\n            return np.empty((0, 2), np.int)\n        else:\n            return out\n\n    image = image.copy()\n    # Non maximum filter\n    if footprint is not None:\n        image_max = ndi.maximum_filter(image, footprint=footprint,\n                                       mode='constant')\n    else:\n        size = 2 * min_distance + 1\n        image_max = ndi.maximum_filter(image, size=size, mode='constant')\n    mask = (image == image_max)\n    image *= mask\n\n    if exclude_border:\n        # zero out the image borders\n        for i in range(image.ndim):\n            image = image.swapaxes(0, i)\n            image[:min_distance] = 0\n            image[-min_distance:] = 0\n            image = image.swapaxes(0, i)\n\n    # find top peak candidates above a threshold\n    peak_threshold = max(np.max(image.ravel()) * threshold_rel, threshold_abs)\n\n    # get coordinates of peaks\n    coordinates = np.argwhere(image > peak_threshold)\n\n    if coordinates.shape[0] > num_peaks:\n        intensities = image.flat[np.ravel_multi_index(coordinates.transpose(),image.shape)]\n        idx_maxsort = np.argsort(intensities)[::-1]\n        coordinates = coordinates[idx_maxsort][:num_peaks]\n\n    if indices is True:\n        return coordinates\n    else:\n        nd_indices = tuple(coordinates.T)\n        out[nd_indices] = True\n        return out\n", "path": "skimage/feature/peak.py"}]}