抓取NTSC到USB转接器的帧,使用opencv2和python包装器。

6

上下文:

我一直在使用 Python 的 OpenCV2 包进行尝试。

我想用一个类似汽车后视摄像头的广角摄像头来玩几个点子。我从报废的撞车汽车上得到了一个有4根电线的广角摄像头,通过颜色编码猜测出每根线的作用,将它们与 USB Type A 的电源和接地线相连,并从 RCA 连接器馈入 NTSC 合成+合成- 信号。

我买了一个类似 这个 的 NTSC 转 USB 转换器。

它附带了驱动程序和一些现成的 VHStoDVD 软件。

问题:

我按以下普通示例测试它:

import numpy as np
import cv2

cam_index=0
cap=cv2.VideoCapture(cam_index)


print cap.isOpened()
ret, frame=cap.read()

#print frame.shape[0]
#print frame.shape[1]

while (cap.isOpened()):
    ret, frame=cap.read()
    #gray=cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)


    cv2.imshow('frame', frame)


    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

#release and close 
cap.release()
cv2.destroyAllWindows() 

这是来自Shell的输出:

True

Traceback (most recent call last):
  File "C:/../cam_capture_.py", line 19, in <module>
    cv2.imshow('frame', frame)
error: ..\..\..\..\opencv\modules\highgui\src\window.cpp:261: error: (-215) size.width>0 && size.height>0 in function cv::imshow

>>> 

关键观察结果:

屏幕截图

  1. 在控制面板中,USB dongle被显示为“OEM capture”,位于“声音、视频和游戏控制器”而不是“影像设备”,因此它不是一个简单的即插即用网络摄像头。

  2. 如果打开VHStoDVD软件,则需要配置两个方面:

    • 设置为Composite
    • 将编码设置为NTSC 然后,模拟相机提供的视频信号可以在VHStoDVD应用程序中正常显示。
  3. 当我在FLV(设备捕获)中打开设备视频通道时,设备流只是黑屏,但是如果我在FLV正在流式传输时打开VHStoDVD软件,则会在FLV上实时流式传输相机的视频并在VHStoDVD上显示黑屏。另一个重要区别是,当视频流在FLV中运行时,延迟非常大,约为0.5秒,而在VHStoDVD中运行时,延迟很小。

  4. 按照上述示例代码运行“cam_capture.py”时,在运行时的某个时候,我最终会得到一个停止错误代码0x0000008e:

详情:

stop: 0x0000008E (0xC0000005, 0xB8B5F417, 0X9DC979F4, 0X00000000 )

ks.sys - Address B8B5F417 base at B8B5900, Datestamp...

beg mem dump
phy mem dump complete

5. 如果我尝试打印frame.shape[0]或frame.shape[1],我会收到一个类型错误,说我不能打印类型None。

6. 如果尝试其他cam_index,结果始终为false。

简而言之:

在“控制面板”中,摄像头设备位于“声音、视频和游戏控制器”下,而不是“影像设备”下;

cam_index == 0;

capture.isOpened()= True;

帧大小为None;

如果VHStoDVD正在运行,并配置了复合NTSC,则相机可以正常工作,显然您无法在附件的打印屏幕上看到图像,但请相信我!;)

是否有任何形式的初始通信启动初始化方式,可以修复此问题,即模拟VHStoDVD设置(复合+NTSC)? 我想我可以开始VHStoDVD和dongle之间的通信,但感觉自己做了一些超出我的能力范围的事情,我认为这是一个关键的解决方案。

欢迎提出任何有建设性的见解、建议或更正!

谢谢

干杯


xp 2002 sp3 i5 @2.67GHz 2GB RAM 200GB - user3380927
只是想理解这个问题 - 你怎么会同时得到 stop:... 错误和标准的 traceback 错误?看起来你应该立即得到 traceback,而不是它会“运行”..? - KobeJohn
显然我没有足够的声望来使用聊天,但是让我们试试: - user3380927
仅使用FLV运行,只会出现黑屏。 - user3380927
当FLV运行时,初始化VHStoDVD,我可以在FLV上看到摄像头的视频,但是在VHStoDVD上看不到视频。 - user3380927
显示剩余11条评论
3个回答

7
好的,经过深入调查,初步怀疑得到了确认,即由于NTSC dongle不被视为成像设备(而是被视为视频控制器,类似于电视调谐卡的仿真),这意味着虽然我们能够使用cam_index=0调用cv2.VideoCapture,但视频通道本身没有传输,因为我们需要定义一堆参数:
  1. 编码
  2. 帧大小
  3. fps速率等
问题在于该设备不支持作为成像设备,调用cv2.VideoCapture.set(parameter, value)似乎不能改变原始视频源的任何内容。
我没有找到解决方案,但我找到了一个解决方法。网上有很多选项。搜索关键词DV to webcam或将摄像机作为网络摄像头。
我使用了DVdriver(http://www.trackerpod.com/TCamWeb/download.htm)(我用了试用版,因为我很抠门!)。
为什么它有效呢?
尽我所知,DVdriver从被设置为视频控制器的设备接收数据(类似于“Windows Movie Maker”或ffmpeg的捕获),然后通过“fairydust”将帧输出到cam_index = 0(假定没有其他相机连接),作为“imaging device” webcam。
总结:TLDR使用DVdriver或类似软件。
我找到了一个解决方法,但我真的很想从第一原理理解它,并可能从Python中生成类似的NTSC dongle初始化,而不需要任何其他软件依赖性,但在那之前,希望这将帮助其他也在苦苦挣扎或认为这是硬件问题的人。
现在我会给你留下一些贝克特: 曾经尝试过。曾经失败过。没关系。再试一次。再次失败。更好地失败。(!)

恭喜你找到了解决方法。你还确认了它实际上可以使用原始设置拾取相机,这是一个很大的进步。你提到 cv2.VideoCapture.set(...) 没有起作用,但让我确认一下... 当你使用它时,我非常确定你必须在创建的 VideoCapture 实例上调用它。即 cap = cv2.VideoCapture(..) 后跟 cap.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH, 1024)。你之前已经这样做了吗? - KobeJohn
我只是为了减少冗长但实现相同的目的而使用了“import cv2.cv as cv”。之前的情况是:1)VHStoDVD软件将摄像机作为独立应用程序进行捕获,结果:视频源正常;2)当VHStoDVD处于捕获模式时同时运行py脚本,结果:py脚本的“frame”是一个绿色屏幕BGR(0,136,0),而VHStoDVD源变成黑屏;3)作为独立运行脚本,没有额外的捕获软件,结果:停止错误代码0x00000008。 - user3380927
@kobejohn,你认为在Python中不使用第三方软件,仅通过初始化视频捕获设备并解析“图像设备”伪摄像头来实现OpenCV框架使用的相同功能是否可能? - user3380927
我相信这是可能的,但你可能需要修改OpenCV,就像我在一些博客中所读到的那样。如果你或我已经是专家,我打赌我们可以想出来(看看转换芯片/设备信息)。或者,如果我们有来自转换器的真正文档,也许我们可以想出来。但我们不是专家,也没有文档!很抱歉我无法帮忙解决这个问题。 - KobeJohn
不用道歉!感谢你的帮助!重要的是要不断进步!我们再见! - user3380927
显示剩余3条评论

1
我遇到了同样的问题。作为解决方法,我首先尝试了@user3380927提出的解决方案,它确实起作用了。但是由于我不想依赖外部软件,我开始使用Python中的opencv调整参数。
这些代码行非常有效(您必须在第一次读取帧之前插入它们):
cam.set(cv2.CAP_FFMPEG,True)
cam.set(cv2.CAP_PROP_FPS,30)

所以,基本相机读取的完整代码如下:
import cv2

cam = cv2.VideoCapture(1)
cam.set(cv2.CAP_FFMPEG,True)
cam.set(cv2.CAP_PROP_FPS,30)

while(True):
    ret,frame = cam.read()
    cv2.imshow('frame',frame)
    if (cv2.waitKey(1) & 0xFF == ord('q')):
        break

cam.release()
cv2.destroyAllWindows()

你可以像往常一样应用图像处理操作。仅供参考,这是我的配置:
  • Opencv 3.1.0
  • Python 2.7.5
  • Windows 8.1
  • Elgato视频捕获设备(也显示为声音视频和游戏控制器)

1
这篇文章虽晚了几个月,但仍然有用。当时我在Windows电脑上工作,并已经安装了随设备附带的驱动程序。我尝试运行与你提出问题时相同的代码,包括使用Somagic的Ezcap设备并得到了相同的错误。由于“frame为None”,我决定在它周围加上if语句——以防它是初始化错误。将其放入循环中:
if frame is None:
    print 0
else:
    print 1

结果为:01110111111111111111111111111...。
如果将循环上面的“frame = cap.read()”注释掉 - 我得到:00111111111111111...。
因此对于我的设备捕获设备,似乎在第5个帧之后捕获所有帧都有效。我不确定这是为什么,但现在它可能是一个有用的解决方法。
免责声明:不幸的是,我的摄像头输入目前处于辐射场中,所以我需要几周时间才能确保它是否确实正常工作。然而,目前的图像是黑框架(这是没有正确输入的预期结果)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接