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

已解决:使用CV2将Python YU12转换为RGB失败,python,opencv,rgb,cv2,Python,Opencv,Rgb,Cv2,我试图从网络摄像头中获取帧并用python处理它们。网络摄像头告诉我它使用YU12编解码器。未处理的帧(1280x720)看起来像:你应该在图片中看到一杯咖啡,我的手臂和显示器在背景中。由于某种原因,这幅画看起来很奇怪。看壶柄 如果我尝试将其转换为RGB,则会出现以下错误: cv2.error:OpenCV(4.1.2)/io/OpenCV/modules/imgproc/src/color.simd_helpers.hpp:92:error:(-2:Unspecified error)在函数'

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

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

cv2.error:OpenCV(4.1.2)/io/OpenCV/modules/imgproc/src/color.simd_helpers.hpp:92:error:(-2:Unspecified error)在函数'cv::impl::{anonymous}::CvtHelper::CvtHelper(cv::InputArray,cv::OutputArray,int)[with VScn=cv::impl:{anonymous}Set;VDcn=cv::impl:{anonymous}onymous}Set;VDepth=cv::impl:{::impl:{匿名}::SizePolicy SizePolicy=(cv::impl:::SizePolicy)1u;cv::InputArray=常量cv::_InputArray&;cv::OutputArray=常量cv::_OutputArray&] 输入图像中的通道数无效: 'VScn::contains(scn)' 哪里 “scn”是3

如果我使用mplayer,网络摄像头中的图片看起来很好。为了调试mplayer的输出:

找不到匹配的颜色空间-正在使用-vf scale重试。。。 打开视频过滤器:[缩放]未定义电影方面-否 应用了处方。[swscaler@0x5638ca496560]双三次定标器,来自 使用MMXEXT[swscaler@0x5638ca496560]将yuyv422连接到yuv420p 无标度yuyv422->yuv420p专用变频器VO:[xv]1920x1080=> 1920x1080平面YV12选定视频编解码器:[rawyuy2]vfm:raw(raw YUY2)


是的,我不知道怎么了。我所做的是使用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)

如果您要编写JPEG,您的图像应该是BGR格式,因此我会尝试
cvtColor(…,cv2.COLOR\u YUV2BGR)
原始帧格式看起来不像
YU12
格式。请以PNG格式(非JPEG)保存。将其保存为灰度图像,而不是RGB(因为YU12没有颜色),然后发布新图像。与其发布三个答案,不如发布一个答案,并在每个答案之间使用线分隔符。为每个部分添加一个标题,如更新:---
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)