Ошибка opencv: утверждение не удалось ((scn == 3 || scn == 4) && (depth == cv_8u || depth == cv_32f)) в cvtcolor

Я получаю следующую ошибку:

enter image description here

Я провел исследование и обнаружил, что эта проблема вызвана несуществующим изображением, однако на этот раз это не так. Я проверил форму изображения с помощью np.shape, и он вернул значение. Вот мой код ниже

def process_with_webcam(self):
    ret, frame = self.vs.read()
    frame = frame[1]
    rospy.loginfo(frame.shape)
    if (frame is not None):
        contours = self.detect_balls(frame)

и вот где он ломается:

def detect_balls(self, frame):
    if frame is None:
        rospy.logerror("Empty frame")

        # resize the frame, blur it, and convert it to the HSV
        # color space
        frame = imutils.resize(frame, width=600)
        blurred = cv2.GaussianBlur(frame, (11, 11), 0)
        hsv = cv2.cvtColor(blurred, cv2.COLOR_BGR2HSV)

Любые предложения будут ценны!

Какое значение возвращает np.shape? Есть ли у него три значения?

Mick 26.10.2018 09:06

Кажется, есть ошибка отступа внутри if frame is None:, вы вызываете imutils.resize(frame, width=600), что, я думаю, неправильно?

ZdaR 26.10.2018 09:17

Вы должны попробовать отладить, вывести тип изображения и количество каналов вашего кадра. Судя по исключению, у вас либо нет правильного типа изображения, либо не удалось загрузить изображение.

T A 26.10.2018 10:19

Пожалуйста, не размещайте текст в виде изображений (он недоступен для поиска и поиска) и укажите правильный минимальный воспроизводимый пример, чтобы улучшить этот вопрос.

Dan Mašek 26.10.2018 18:44

Возможный дубликат Ошибка Python OpenCV (-215) в VideoWriter.write

ivan_pozdeev 26.10.2018 18:55
1
5
405
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Виновником здесь является утверждение frame = frame[1], потому что (выделено мной)

[Indexing with] An integer, i, returns the same values as i:i+1 except the dimensionality of the returned object is reduced by 1. In particular, a selection tuple with the p-th element an integer (and all other entries :) returns the corresponding sub-array with dimension N - 1. If N = 1 then the returned object is an array scalar.

Следовательно, вы превратили трехмерный ndarray, представляющий 3-канальное изображение BGR, в двухмерный ndarray. Из-за того, как работают привязки Python к OpenCV, двухмерный ndarray обрабатывается как 1-канальное (в оттенках серого) изображение.

Это легко продемонстрировать в интерпретаторе командной строки:

>>> import numpy as np
>>> a = np.arange(4*4*3, dtype=np.uint8).reshape(4,4,3)
>>> a
array([[[ 0,  1,  2],
        [ 3,  4,  5],
        [ 6,  7,  8],
        [ 9, 10, 11]],

       [[12, 13, 14],
        [15, 16, 17],
        [18, 19, 20],
        [21, 22, 23]],

       [[24, 25, 26],
        [27, 28, 29],
        [30, 31, 32],
        [33, 34, 35]],

       [[36, 37, 38],
        [39, 40, 41],
        [42, 43, 44],
        [45, 46, 47]]], dtype=uint8)
>>> a.shape
(4, 4, 3)
>>> a[1]
array([[12, 13, 14],
       [15, 16, 17],
       [18, 19, 20],
       [21, 22, 23]], dtype=uint8)
>>> a[1].shape
(4, 3)

Решение простое, используйте вместо него frame = frame[1:2].

Продолжая демонстрацию выше:

>>> a[1:2]
array([[[12, 13, 14],
        [15, 16, 17],
        [18, 19, 20],
        [21, 22, 23]]], dtype=uint8)
>>> a[1:2].shape
(1, 4, 3)

Как отмечает в комментарии Иван Поздеев, есть и другие альтернативные обозначения. Имея это в виду, я бы, наверное, выбрал

frame = frame[[1]]

поскольку он краток и требует указания только нужного вам индекса.

Лучше a[(1,),:,:] или (тот же) a[[1],:,:] или a[[1]].

ivan_pozdeev 26.10.2018 19:20

@ivan_pozdeev Я думаю более откровенно. Однако это не обязательно, поскольку «Если количество объектов в выбранном кортеже меньше N, то: предполагается для любых последующих измерений». | Мне нравится третий.

Dan Mašek 26.10.2018 19:23

Другие вопросы по теме