«Параметр image должен быть двухмерным массивом» - PullRequest
0 голосов
/ 15 января 2019

Я пытаюсь извлечь объекты сферы через scikit-изображение, но я получил ошибку The parameter image must be a 2-dimensional array. Я преобразовал его в оттенки серого, чтобы изображение на самом деле было двухмерным.

    from skimage.feature import ORB
    from skimage.color import rgb2gray

    def find_orb(img, n_keypoints=2000, **kwargs):
        descriptor_extractor = ORB(n_keypoints, **kwargs)
        descriptor_extractor.detect_and_extract(rgb2gray(img))
        return descriptor_extractor.keypoints, descriptor_extractor.descriptors

    pano_image_collection = io.ImageCollection('jpeg/lowres/8_*.jpg',
                                    load_func=lambda f:io.imread(f).astype(np.float32) / 255)
    img = pano_image_collection[0]
    keypoints, descriptors = find_orb(img)

А это ошибка

ValueError                                Traceback (most recent call last)
<ipython-input-5-5dce31f8d3f4> in <module>()
----> 7 keypoints, descriptors = find_orb(img)

<ipython-input-4-26e09ccf38ce> in find_orb(img, n_keypoints, **kwargs)
 14     descriptor_extractor = ORB(n_keypoints, **kwargs)
---> 15     descriptor_extractor.detect_and_extract(rgb2gray(img))
 16     return descriptor_extractor.keypoints, descriptor_extractor.descriptors

/usr/local/lib/python3.6/site-packages/skimage/feature/orb.py in detect_and_extract(self, image)
302 
303             keypoints, orientations, responses = \
--> 304                 self._detect_octave(octave_image)
305 
306             if len(keypoints) == 0:

/usr/local/lib/python3.6/site-packages/skimage/feature/orb.py in _detect_octave(self, octave_image)
139         # Extract keypoints for current octave
140         fast_response = corner_fast(octave_image, self.fast_n,
--> 141                                     self.fast_threshold)
142         keypoints = corner_peaks(fast_response, min_distance=1)
143 

/usr/local/lib/python3.6/site-packages/skimage/feature/corner.py in corner_fast(image, n, threshold)
745 
746     """
--> 747     image = _prepare_grayscale_input_2D(image)
748 
749     image = np.ascontiguousarray(image)

/usr/local/lib/python3.6/site-packages/skimage/feature/util.py in _prepare_grayscale_input_2D(image)
140 def _prepare_grayscale_input_2D(image):
141     image = np.squeeze(image)
--> 142     assert_nD(image, 2)
143     return img_as_float(image)
144 

/usr/local/lib/python3.6/site-packages/skimage/_shared/utils.py in assert_nD(array, ndim, arg_name)
176         raise ValueError(msg_empty_array % (arg_name))
177     if not array.ndim in ndim:
--> 178         raise ValueError(msg_incorrect_dim % (arg_name, '-or-'.join([str(n) for n in ndim])))
179 
180 

ValueError: The parameter `image` must be a 2-dimensional array

1 Ответ

0 голосов
/ 15 января 2019

Боюсь, я не могу помочь вам больше, чем это: Я запустил его с помощью отладчика, и изображение на втором уровне пирамиды, созданное внутри ORB, имеет только одну запись и форму (1, 1), которая будет преобразована в одномерное изображение при последующем вызове np.squeeze.

Обновление: Op (Дарья Мусаткина) нашла решение проблемы, цитируя: Проблема в том, что первым параметром для orb является downsample, а не n_keypoints. Вот почему была создана октава с формой (1, 1).

Для справки, ORB API документ

Мой первоначальный ответ был неверным (см. Комментарии ниже):

Я предполагаю, что ваше изображение имеет формат RGB, который, вероятно, импортируется как канал 2D + (всего 3D) numpy.ndarray с uint8 записями. ndarray.astype не меняет размерность изображения, только тип данных. Вместо трехмерного массива uint8 теперь у вас есть трехмерный массив float32 с теми же значениями (без учета здесь числовых ошибок). Таким образом, вы не конвертировали в пространство серой шкалы, вы просто изменили тип данных вашего массива. Вместо этого можно попробовать использовать np.mean вдоль оси канала, например.

...