已解决:使用CV2将Python YU12转换为RGB失败

2024-09-27 04:28:33 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图从网络摄像头中获取帧并用python处理它们。网络摄像头告诉我它使用YU12编解码器。未处理的帧(1280x720)看起来像:enter image description here你应该在图片中看到一杯咖啡,我的手臂和我的显示器在背景中。由于某种原因,这幅画看起来很奇怪。看壶柄

如果我尝试将其转换为RGB,则会出现以下错误:

cv2.error: OpenCV(4.1.2) /io/opencv/modules/imgproc/src/color.simd_helpers.hpp:92: error: (-2:Unspecified error) in function '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&]' Invalid number of channels in input image: 'VScn::contains(scn)' where 'scn' is 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的输出:

Could not find matching colorspace - retrying with -vf scale... Opening video filter: [scale] Movie-Aspect is undefined - no prescaling applied. [swscaler @ 0x5638ca496560] bicubic scaler, from yuyv422 to yuv420p using MMXEXT [swscaler @ 0x5638ca496560] using unscaled yuyv422 -> yuv420p special converter VO: [xv] 1920x1080 => 1920x1080 Planar YV12 Selected video codec: [rawyuy2] vfm: raw (RAW YUY2)


Tags: 网络rawcodeerrorcv2cvcodec摄像头
3条回答

是的,我不知道怎么了。我所做的是使用v4l2 ctl,也许有人能给我一个提示

v4l2 ctl-d/dev/video2所有

格式视频捕获:

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             : 

我做了进一步的调查。为了进行测试,我更改了代码,使用pygame从网络摄像头抓取图像。简言之:相机正在工作,并显示美丽的图像。由于某些原因,open video在解码网络摄像头帧时存在一些问题。也许我遗漏了一些参数,但目前我不知道遗漏了哪些参数

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)

好消息,问题解决了。打开视频选择了错误的解码器。在我的例子中是“YU12”,但网络摄像头使用:YUYV。我必须手动设置-(功能:set(cv2.CAP_PROP_FOURCC,FOURCC))。工作代码如下:

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)

相关问题 更多 >

    热门问题