scikit-image

Форк
0
213 строк · 5.9 Кб
1
import numpy as np
2

3
from ..util import img_as_float
4
from .._shared.utils import (
5
    _supported_float_type,
6
    check_nD,
7
)
8

9

10
class FeatureDetector:
11
    def __init__(self):
12
        self.keypoints_ = np.array([])
13

14
    def detect(self, image):
15
        """Detect keypoints in image.
16

17
        Parameters
18
        ----------
19
        image : 2D array
20
            Input image.
21

22
        """
23
        raise NotImplementedError()
24

25

26
class DescriptorExtractor:
27
    def __init__(self):
28
        self.descriptors_ = np.array([])
29

30
    def extract(self, image, keypoints):
31
        """Extract feature descriptors in image for given keypoints.
32

33
        Parameters
34
        ----------
35
        image : 2D array
36
            Input image.
37
        keypoints : (N, 2) array
38
            Keypoint locations as ``(row, col)``.
39

40
        """
41
        raise NotImplementedError()
42

43

44
def plot_matched_features(
45
    image0,
46
    image1,
47
    *,
48
    keypoints0,
49
    keypoints1,
50
    matches,
51
    ax,
52
    keypoints_color='k',
53
    matches_color=None,
54
    only_matches=False,
55
    alignment='horizontal',
56
):
57
    """Plot matched features between two images.
58

59
    .. versionadded:: 0.23
60

61
    Parameters
62
    ----------
63
    image0 : (N, M [, 3]) array
64
        First image.
65
    image1 : (N, M [, 3]) array
66
        Second image.
67
    keypoints0 : (K1, 2) array
68
        First keypoint coordinates as ``(row, col)``.
69
    keypoints1 : (K2, 2) array
70
        Second keypoint coordinates as ``(row, col)``.
71
    matches : (Q, 2) array
72
        Indices of corresponding matches in first and second sets of
73
        descriptors, where `matches[:, 0]` (resp. `matches[:, 1]`) contains
74
        the indices in the first (resp. second) set of descriptors.
75
    ax : matplotlib.axes.Axes
76
        The Axes object where the images and their matched features are drawn.
77
    keypoints_color : matplotlib color, optional
78
        Color for keypoint locations.
79
    matches_color : matplotlib color, optional
80
        Color for lines which connect keypoint matches. By default the
81
        color is chosen randomly.
82
    only_matches : bool, optional
83
        Set to True to plot matches only and not the keypoint locations.
84
    alignment : {'horizontal', 'vertical'}, optional
85
        Whether to show the two images side by side (`'horizontal'`), or one above
86
        the other (`'vertical'`).
87

88
    """
89
    image0 = img_as_float(image0)
90
    image1 = img_as_float(image1)
91

92
    new_shape0 = list(image0.shape)
93
    new_shape1 = list(image1.shape)
94

95
    if image0.shape[0] < image1.shape[0]:
96
        new_shape0[0] = image1.shape[0]
97
    elif image0.shape[0] > image1.shape[0]:
98
        new_shape1[0] = image0.shape[0]
99

100
    if image0.shape[1] < image1.shape[1]:
101
        new_shape0[1] = image1.shape[1]
102
    elif image0.shape[1] > image1.shape[1]:
103
        new_shape1[1] = image0.shape[1]
104

105
    if new_shape0 != image0.shape:
106
        new_image0 = np.zeros(new_shape0, dtype=image0.dtype)
107
        new_image0[: image0.shape[0], : image0.shape[1]] = image0
108
        image0 = new_image0
109

110
    if new_shape1 != image1.shape:
111
        new_image1 = np.zeros(new_shape1, dtype=image1.dtype)
112
        new_image1[: image1.shape[0], : image1.shape[1]] = image1
113
        image1 = new_image1
114

115
    offset = np.array(image0.shape)
116
    if alignment == 'horizontal':
117
        image = np.concatenate([image0, image1], axis=1)
118
        offset[0] = 0
119
    elif alignment == 'vertical':
120
        image = np.concatenate([image0, image1], axis=0)
121
        offset[1] = 0
122
    else:
123
        mesg = (
124
            f"`plot_matched_features` accepts either 'horizontal' or 'vertical' for "
125
            f"alignment, but '{alignment}' was given. See "
126
            f"https://scikit-image.org/docs/dev/api/skimage.feature.html#skimage.feature.plot_matched_features "  # noqa
127
            f"for details."
128
        )
129
        raise ValueError(mesg)
130

131
    if not only_matches:
132
        ax.scatter(
133
            keypoints0[:, 1],
134
            keypoints0[:, 0],
135
            facecolors='none',
136
            edgecolors=keypoints_color,
137
        )
138
        ax.scatter(
139
            keypoints1[:, 1] + offset[1],
140
            keypoints1[:, 0] + offset[0],
141
            facecolors='none',
142
            edgecolors=keypoints_color,
143
        )
144

145
    ax.imshow(image, cmap='gray')
146
    ax.axis((0, image0.shape[1] + offset[1], image0.shape[0] + offset[0], 0))
147

148
    rng = np.random.default_rng()
149

150
    for i in range(matches.shape[0]):
151
        idx0 = matches[i, 0]
152
        idx1 = matches[i, 1]
153

154
        if matches_color is None:
155
            color = rng.random(3)
156
        else:
157
            color = matches_color
158

159
        ax.plot(
160
            (keypoints0[idx0, 1], keypoints1[idx1, 1] + offset[1]),
161
            (keypoints0[idx0, 0], keypoints1[idx1, 0] + offset[0]),
162
            '-',
163
            color=color,
164
        )
165

166

167
def _prepare_grayscale_input_2D(image):
168
    image = np.squeeze(image)
169
    check_nD(image, 2)
170
    image = img_as_float(image)
171
    float_dtype = _supported_float_type(image.dtype)
172
    return image.astype(float_dtype, copy=False)
173

174

175
def _prepare_grayscale_input_nD(image):
176
    image = np.squeeze(image)
177
    check_nD(image, range(2, 6))
178
    image = img_as_float(image)
179
    float_dtype = _supported_float_type(image.dtype)
180
    return image.astype(float_dtype, copy=False)
181

182

183
def _mask_border_keypoints(image_shape, keypoints, distance):
184
    """Mask coordinates that are within certain distance from the image border.
185

186
    Parameters
187
    ----------
188
    image_shape : (2,) array_like
189
        Shape of the image as ``(rows, cols)``.
190
    keypoints : (N, 2) array
191
        Keypoint coordinates as ``(rows, cols)``.
192
    distance : int
193
        Image border distance.
194

195
    Returns
196
    -------
197
    mask : (N,) bool array
198
        Mask indicating if pixels are within the image (``True``) or in the
199
        border region of the image (``False``).
200

201
    """
202

203
    rows = image_shape[0]
204
    cols = image_shape[1]
205

206
    mask = (
207
        ((distance - 1) < keypoints[:, 0])
208
        & (keypoints[:, 0] < (rows - distance + 1))
209
        & ((distance - 1) < keypoints[:, 1])
210
        & (keypoints[:, 1] < (cols - distance + 1))
211
    )
212

213
    return mask
214

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.