Home > Mobile >  OpenCV unsupported depth of input image, 'depth' is 3 (CV_16S) when using cv2.cvtColor
OpenCV unsupported depth of input image, 'depth' is 3 (CV_16S) when using cv2.cvtColor

Time:10-04

I'm reading in a video file and convert it to a numpy array.

like so:

video= np.array(skvideo.io.vread(folder   "video.avi"), dtype=np.int16)

later I access the first frame and save it under img

img = video[0]

the shape now has 3 channels:

389, 516, 3

When converting to grayscale:

gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)

I get this error:

error: OpenCV(4.1.2) /io/opencv/modules/imgproc/src/color.simd_helpers.hpp:94: error: (-2:Unspecified error) in function 'cv::impl::{anonymous}::CvtHelper<VScn, VDcn, VDepth, sizePolicy>::CvtHelper(cv::InputArray, cv::OutputArray, int) [with VScn = cv::impl::{anonymous}::Set<3, 4>; VDcn = cv::impl::{anonymous}::Set<1>; VDepth = cv::impl::{anonymous}::Set<0, 2, 5>; cv::impl::{anonymous}::SizePolicy sizePolicy = (cv::impl::<unnamed>::SizePolicy)2u; cv::InputArray = const cv::_InputArray&; cv::OutputArray = const cv::_OutputArray&]'
> Unsupported depth of input image:
>     'VDepth::contains(depth)'
> where
>     'depth' is 3 (CV_16S) 

The video and images display fine. I actually got to this error because I wanted to plot histograms and I get an error with no documentation when passing the first frame.

Is it possible that I have to use cv2.VideoCapture? I don't see how this should be the case as it's a perfectly fine numpy array.

thank you for your help!

CodePudding user response:

cvtColor complains because the data has the wrong dtype.

Your data has dtype int16 (signed integer).

cvtColor only accepts uint8, uint16, and float32. Those are CV_8U, CV_16U, and CV_32F in OpenCV parlance, which have the numerical values 0, 2, 5.

Solution: use a supported dtype. It seems that skvideo.io.vread already returns data in uint8. Just drop the superfluous np.array(..., dtype=np.int16) around it.

CodePudding user response:

Weirdly, it does work if I read in the video with video capture and then iterate over the frames.

So one solution to above is

video= cv2.VideoCapture(folder   'video.avi')
is_true, frame = video.read()

then do the rest as before.

If someone could explain why (what the difference between the arrays is) that'd be great.

  • Related