#python #numpy #opencv #scikit-image
Вопрос:
Я читаю видеофайл и конвертирую его в массив numpy.
вот так:
video= np.array(skvideo.io.vread(folder "video.avi"), dtype=np.int16)
позже я получаю доступ к первому кадру и сохраняю его в img
img = video[0]
форма теперь имеет 3 канала:
389, 516, 3
При преобразовании в оттенки серого:
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
Я получаю эту ошибку:
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::_InputArrayamp;; cv::OutputArray = const cv::_OutputArrayamp;]'
> Unsupported depth of input image:
> 'VDepth::contains(depth)'
> where
> 'depth' is 3 (CV_16S)
Видео и изображения отображаются нормально.
На самом деле я дошел до этой ошибки, потому что хотел построить гистограммы, и при передаче первого кадра я получаю ошибку без документации.
Возможно ли, что я должен использовать cv2.VideoCapture
? Я не понимаю, как это должно быть, так как это совершенно прекрасный массив numpy.
спасибо вам за вашу помощь!
Комментарии:
1. попробуйте использовать
dtype=np.uint8
для массива видео, opencv не поддерживает все типы данных
Ответ №1:
cvtColor
жалуется, потому что данные неверные dtype
.
Ваши данные имеют dtype
int16
(целое число со знаком).
cvtColor
принимает только uint8
, uint16
, и float32
. Это CV_8U
, CV_16U
, и CV_32F
на языке OpenCV, которые имеют числовые значения 0, 2, 5
.
Решение: используйте поддерживаемый тип dtype. Похоже, что skvideo.io.vread
он уже возвращает данные в uint8
. Просто отбросьте лишнее np.array(..., dtype=np.int16)
вокруг него.
Комментарии:
1. Спасибо, Кристоф, я попробую, @Dominik Ficek тоже сработал. Я получил вышеперечисленное, работая только с другой библиотекой, если я изменил dtype на int16, вот почему он там был.
Ответ №2:
Как ни странно, это работает, если я читаю видео с помощью видеозахвата, а затем повторяю кадры.
Таким образом, одним из решений вышеизложенного является
video= cv2.VideoCapture(folder 'video.avi')
is_true, frame = video.read()
затем сделайте все остальное, как и раньше.
Если бы кто-нибудь мог объяснить, почему (в чем разница между массивами), это было бы здорово.
Комментарии:
1. да, это работает, потому что это НЕ превращается во что-то глупое.
2. преобразование позже работает, вот что я имел в виду. @berak
3. что ж, ваше предыдущее преобразование было ошибкой (и выглядит как «слепое копирование»).
4. @berak, конечно, я копирую и вставляю (хотя я могу это делать только с открытыми глазами, вы пробовали с закрытыми глазами?) из документов, ТАК и в других местах, как должно быть видно из примеров кода 1:1, соответствующих документации, которую я использовал (в противном случае я ссылаюсь).
5. вердикт все еще таков : вы неправильно добавили (плохой) актерский состав, не зная (или не спрашивая), почему