简体   繁体   中英

OpenCV Error: Assertion failed ((scn == 3 || scn == 4) && (depth == CV_8U || depth == CV_32F)) in cvtColor

I keep getting the following error:

在此处输入图片说明

I've done research and found that this issue is caused by a non-existent image, however that isn't the case this time. I checked the shape of the image using np.shape, and it returned a value. Here's my code below

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)

and this where it breaks:

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)

Any suggestions would be greatly appreciated!

The culprit here is the statement frame = frame[1] , because (emphasis mine)

[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.

Hence, you've turned the 3-dimensional ndarray representing a 3-channel BGR image into a 2-dimensional ndarray . Due to the way how the Python bindings of OpenCV work, a 2-dimensional ndarray is treated as a 1-channel (grayscale) image.

This can be easily demonstrated in the command line interpreter:

>>> 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)

The solution is simple, use frame = frame[1:2] instead.

Continuing with the above demonstration:

>>> 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)

As Ivan Pozdeev mentions in the comment, there are other alternative notations. With that in mind, I'd probably pick

frame = frame[[1]]

since it's terse, and requires specifying just the index you need.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM