I'm trying to extract orb features via scikit-image, but I got the error The parameter image must be a 2-dimensional array
. I converted it to greyscale so the image is actually 2-dimensional.
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)
And this is the error
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
I am afraid I cannot help you anymore than this:
I ran it with a debugger and the image at the second level of the pyramid that is created internally in ORB has only one entry and shape (1, 1)
, which will be redcued to a one-dimensional image in a subsequent np.squeeze
call.
Update: Op (Daria Musatkina) has found solution to the problem, quoting:
The problem here is that first parameter for orb is downsample and not n_keypoints. That's why octave with shape (1, 1)
was created.
For reference, the ORB API doc
My initial answer was incorrect (see comments below):
I assume that your image is RGB, which is probably imported as a 2D + channel (3D total) numpy.ndarray
with uint8
entries. ndarray.astype
does not change the dimensionality of the image, only the data type. Instead of a 3D array of uint8
, you now have a 3D array of float32
, with the same values (not considering any numerical errors here). Thus, you did not convert into gray scale space, you just changed the data type of your array. You could try to use np.mean
along the channel axis, instead, for example.