Решено: Python YU12 в RGB с CV2 не удалось - PullRequest
0 голосов
/ 30 января 2020

Я попытался получить кадры с веб-камеры и обработать их в python. Веб-камера сообщает мне, что использует код YU12 c. Необработанная рамка (1280x720) выглядит следующим образом: enter image description here На снимке вы должны увидеть чашку кофе, мою руку и монитор на заднем плане. По какой-то причине картина выглядит странно. Посмотрите на ручку банка.

Если я пытаюсь преобразовать его в RGB, я получаю следующую ошибку:

cv2.error: OpenCV (4.1.2) / io / opencv / modules / imgproc / src / color.simd_helpers.hpp: 92: ошибка: (-2: неопределенная ошибка) в функции 'cv :: impl :: {anonymous} :: CvtHelper :: CvtHelper (cv :: InputArray, cv :: OutputArray, int) [with VScn = cv :: impl :: {anonymous} :: Set <1>; VDcn = cv :: impl :: {anonymous} :: Set <3, 4>; VDepth = cv :: impl :: {anonymous} :: Set <0>; cv :: impl :: {anonymous} :: SizePolicy sizePolicy = (cv :: impl :::: SizePolicy) 1u; cv :: InputArray = const cv :: _ InputArray &; cv :: OutputArray = const cv :: _ OutputArray &] 'Неверное количество каналов во входном изображении:' VScn :: contains (scn) ', где' scn 'равно 3

import os
import sys
import cv2

videoSource = 0


def getFrame():
    """"""

    cv_cam_0 = cv2.VideoCapture(0)
    if not cv_cam_0.isOpened():
        raise Exception('video source: %s could not be opened' %(str(videoSource)))

    codec_char_code = int(cv_cam_0.get(cv2.CAP_PROP_FOURCC))
    a = chr(0x000000FF&  codec_char_code)
    b = chr((0x0000FF00& codec_char_code)  >> 8)
    c = chr((0x00FF0000& codec_char_code)  >> 16)
    d = chr((0xFF000000& codec_char_code)  >> 24)

    print('codec 4 char code: ' + a+b+c+d)

    ret, raw_frame = cv_cam_0.read()
    cv2.imwrite('/tmp/test0.jpg', raw_frame)
    rgbFrame = cv2.cvtColor(raw_frame, cv2.COLOR_YUV2RGB_I420)
    cv2.imwrite('/tmp/testConvert.jpg', rgbFrame)



def main(args):
    getFrame()
    sys.exit()


if __name__ == "__main__":
    main(sys.argv)

, если я использую mplayer картинка с веб-камеры выглядит нормально. Для целей отладки выведите из mplayer:

Не удалось найти соответствующее цветовое пространство - повторная попытка с -vf scale ... Открытие видеофильтра: [scale] Mov ie -Аспект не определен - предварительное масштабирование не применяется. [swscaler @ 0x5638ca496560] bicubi c scaler, от yuyv422 до yuv420p с использованием MMXEXT [swscaler @ 0x5638ca496560] с использованием немасштабированного специального конвертера yuyv422 -> yuv420p VO: [xv * 1920x1022y: код 1920x1080 => 1920x1080yv10x1080 => 1920x10x1080u10x10802: 10x1080 => 1920x10x1080u10x10802 ] vfm: raw (RAW YUY2)

Ответы [ 3 ]

0 голосов
/ 03 февраля 2020

Я провел дополнительное расследование. Для теста я изменил код, чтобы использовать pygame для захвата изображений с веб-камеры. Короче говоря: камера работает и показывает красивые картинки. По некоторым причинам открытое видео имеет некоторые проблемы с декодированием кадров веб-камеры. Возможно, я пропускаю некоторые параметры, но в настоящее время я не знаю, какие параметры отсутствуют.

import pygame
import pygame.camera

def getFrame():
    """"""
    pygame.init()
    pygame.camera.init()
    cam = pygame.camera.Camera('/dev/video2',(1280, 720))
    cam.start()
    screen = pygame.display.set_mode((1280, 720),0)

    while(True):
        image = cam.get_image()
        screen.blit(image,(0,0))
        pygame.display.flip()


 def main(args):
    getFrame()
    sys.exit()


if __name__ == "__main__":
    main(sys.argv)
0 голосов
/ 03 февраля 2020

Хорошие новости, проблема решена. Открытое видео выбирает неправильный декодер. В моем случае "YU12", но веб-камера использует: YUYV. Я должен установить его вручную - (Функция: установить (cv2.CAP_PROP_FOUR CC, четыре cc)). Рабочий код ниже:

import os
import sys
import cv2

videoSource = 0

def getFrame():
    """"""


    cv_cam_0 = cv2.VideoCapture(videoSource)
    if not cv_cam_0.isOpened():
        raise Exception('video source: %s could not be opened' %(str(videoSource)))

    cv_cam_0.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
    cv_cam_0.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)

    fourcc = cv2.VideoWriter_fourcc(*'YUYV')
    ret = cv_cam_0.set(cv2.CAP_PROP_FOURCC, fourcc)

    codec_char_code = int(cv_cam_0.get(cv2.CAP_PROP_FOURCC))
    a = chr(0x000000FF&  codec_char_code)
    b = chr((0x0000FF00& codec_char_code)  >> 8)
    c = chr((0x00FF0000& codec_char_code)  >> 16)
    d = chr((0xFF000000& codec_char_code)  >> 24)

    print('codec 4 char code: ' + a+b+c+d)


    #ret, raw_frame = cv_cam_0.read()
    ret = cv_cam_0.grab()
    ret, raw_frame = cv_cam_0.retrieve()

    cv2.imwrite('/tmp/testRaw.png', raw_frame)

def main(args):
    getFrame()
    sys.exit()


if __name__ == "__main__":
    main(sys.argv)
0 голосов
/ 03 февраля 2020

Точно знаю, я понятия не имею, что не так. Я использовал v4l2-ctl, возможно, кто-то может дать мне подсказку.

v4l2-ctl -d / dev / video2 --all

Формат записи видео:

Width/Height      : 1280/720
Pixel Format      : 'YUYV' (YUYV 4:2:2)
Field             : None
Bytes per Line    : 2560
Size Image        : 1843200
Colorspace        : sRGB
Transfer Function : Default (maps to sRGB)
YCbCr/HSV Encoding: Default (maps to ITU-R 601)
Quantization      : Default (maps to Limited Range)
Flags             : 
...