【问题标题】:Using OpenCV Output as Webcam [closed]使用 OpenCV 输出作为网络摄像头 [关闭]
【发布时间】:2014-02-22 03:41:37
【问题描述】:

所以,我想编写一个程序,使 OpenCV 处理后的输出被视为一个网络摄像头。我想用它来为像 Skype 这样的程序创建效果。我被卡住了,谷歌搜索没有任何帮助。请帮我。我需要为此找司机吗?存储为 AVI 并与其他应用程序一起流式传输该 AVI 怎么样?

我想编写一个程序来遮住我的脸,这样当我与我正在辅导但不认识的人进行 Skype 通话时,我不必担心我的隐私!

顺便说一句,我对 C++ 还是有点陌生​​。但是,这是我更喜欢的语言。不过,我也懂 Java 和 Python。

您是否建议我尝试获取另一个库/库集合,例如 OpenFrameworks?

我正在用 C++ 编写 OpenCV。以下是我所有可用的平台: Ubuntu: 来自 apt-get 的 OpenCV,带有 pkg​​-config,QT Creator Ubuntu: 来自 apt-get 的 OpenCV,带有 pkg​​-config 和 libfreenect,QT Creator Windows 7的: OpenCV 2.4.8.0,最新的二进制文件,x86,Visual Studio 2010 express Windows 7的: 未安装 OpenCV 视窗 8.1 专业版: OpenCV 2.4.8.0,最新的二进制文件,x86,Visual Studio Express 2013 Express Desktop,Hyper-V,与 Windows 7:1 相同的配置

我注意到了一些混乱。我正在尝试使用打开 CV 的进程输出并将其发送到另一个程序,如 Skype。主要目的是我要教小学生编程和 OpenCV。我想直接流式传输输出,所以我不必共享我的桌面。

【问题讨论】:

  • 你看SplitCam方法了吗?
  • 它适用于 Linux 吗?我想使用一些开源的东西,这样我就可以为不同的环境编译它!

标签: c++ opencv webcam


【解决方案1】:

我遇到了同样的问题:我祖母的听力很差,所以我希望能够在我的 Skype 视频源中添加字幕。我还想为笑声添加一些效果。我无法让webcamoid 工作。屏幕捕获方法(上面提到的)似乎太老套了,我无法让 Skype 检测 ffmpegs 虚拟输出摄像头(虽然 guvcview 检测到)。然后我遇到了这个:

https://github.com/jremmons/pyfakewebcam

它不是 C++,而是 Python。尽管如此,它在我的非花哨笔记本电脑上还是足够快的。它可以创建多个虚拟网络摄像头(我只需要两个)。它也适用于 Python3。自述文件中提到的步骤很容易在 Ubuntu 18.04 上重现。在 2-3 分钟内,示例代码开始运行。在撰写本文时,此处给出的示例并未使用来自真实网络摄像头的输入。所以我添加了我的代码,它处理真实网络摄像头的输入并将其输出到两个虚拟摄像头:

import cv2
import time
import pyfakewebcam
import numpy as np

IMG_W = 1280
IMG_H = 720

cam = cv2.VideoCapture(0)
cam.set(cv2.CAP_PROP_FRAME_WIDTH, IMG_W)
cam.set(cv2.CAP_PROP_FRAME_HEIGHT, IMG_H)

fake1 = pyfakewebcam.FakeWebcam('/dev/video1', IMG_W, IMG_H)
fake2 = pyfakewebcam.FakeWebcam('/dev/video2', IMG_W, IMG_H)

while True:
    ret, frame = cam.read()

    flipped = cv2.flip(frame, 1)

    # Mirror effect 
    frame[0 : IMG_H, IMG_W//2 : IMG_W] = flipped[0 : IMG_H, IMG_W//2 : IMG_W]

    fake1.schedule_frame(frame)
    fake2.schedule_frame(flipped)

    time.sleep(1/15.0)

【讨论】:

    【解决方案2】:

    pyfakewebcam 的跨平台替代品是pyvirtualcam(免责声明:我是它的开发者)。该存储库有一个sample,用于对 OpenCV 捕获的网络摄像头应用过滤器。作为参考,代码如下所示:

    import cv2
    import pyvirtualcam
    from pyvirtualcam import PixelFormat
    
    vc = cv2.VideoCapture(0)
    
    if not vc.isOpened():
        raise RuntimeError('Could not open video source')
    
    pref_width = 1280
    pref_height = 720
    pref_fps = 30
    vc.set(cv2.CAP_PROP_FRAME_WIDTH, pref_width)
    vc.set(cv2.CAP_PROP_FRAME_HEIGHT, pref_height)
    vc.set(cv2.CAP_PROP_FPS, pref_fps)
    
    # Query final capture device values
    # (may be different from preferred settings)
    width = int(vc.get(cv2.CAP_PROP_FRAME_WIDTH))
    height = int(vc.get(cv2.CAP_PROP_FRAME_HEIGHT))
    fps = vc.get(cv2.CAP_PROP_FPS)
    
    with pyvirtualcam.Camera(width, height, fps, fmt=PixelFormat.BGR) as cam:
        print('Virtual camera device: ' + cam.device)
        while True:
            ret, frame = vc.read()
    
            # .. apply your filter ..
    
            cam.send(frame)
            cam.sleep_until_next_frame()
    

    【讨论】:

      【解决方案3】:

      所以,我为此找到了一个 hack;不一定是最好的方法,但它绝对有效..

      下载一个类似SplitCam的程序;这可以从视频文件、IP 提要和/或桌面屏幕的特定部分模拟网络摄像头提要。.

      所以本质上,您可以编写一个程序来处理网络摄像头视频并使用 OpenCV 的 highgui 窗口显示它,您可以使用 SplitCam 将此窗口作为任何其他应用程序(如 Skype)的输入。我现在试了一下,效果很好!

      HTH

      【讨论】:

      • 绝对是省力的解决方案
      • @berak - 好吧,我找不到另一种方法来让它工作.. :) .. 不过,我很想知道一个更“直接”的方法..跨度>
      • 我知道如何将mjpg stream 写入套接字,但您发现的好处似乎是,它模仿了“网络摄像头驱动程序”,因此任意程序都可以使用它
      • 是的,我也是。我用socket试验了一段时间,如果有突破,我会更新答案。
      • 我可以在 Linux 中使用它吗?我希望能够以很少的配置在 ARM 芯片上运行所有东西这就是我在 Ubuntu 中使用 OpenCV 的原因。我什至可以在基本的 RISC/TriCore 处理器上安装整个系统,所以我可以说 ARM 会很容易。
      【解决方案4】:

      查看gstreamer。 OpenCV 允许您创建定义为 gstreamer 管道的VideoCapture 对象,源可以是网络摄像头或视频文件。 Gstreamer 允许用户创建过滤器,使用opencv 或其他库来修改循环中的视频,一些examples 可用。

      我没有将它与 Skype 结合的经验,但看起来这是可能的。只需要创建正确的pipeline,例如: gst-launch videotestsrc ! ffmpegcolorspace ! "video/x-raw-yuv,format=(fourcc)YUY2" ! v4l2sink device=/dev/video1.

      【讨论】:

        【解决方案5】:

        这样做的一种方法是将 Mat 对象直接发送到套接字,并在接收端将字节数组转换为 Mat,但问题是您需要在两台 PC 上安装 OpenCV。在另一种方式中,您可以使用 Mjpeg streamer 将视频流式传输到 ibternet 并在接收端处理视频,这里您只需要在接收端安装 OpenCV。

        使用套接字

        获取 Mat.data 并直接发送到套接字,数据格式类似于 BGR BGR BGR.... 在接收端你应该知道你要接收的图像的大小。接收后只需将接收到的缓冲区(BGR BGR...数组)分配给您已经知道的大小的 Mat。

        客户:-

        Mat frame;
        frame = (frame.reshape(0,1)); // to make it continuous
        
        int  imgSize = frame.total()*frame.elemSize();
        
        // Send data here
        bytes = send(clientSock, frame.data, imgSize, 0))
        

        服务器:-

        Mat  img = Mat::zeros( height,width, CV_8UC3);
           int  imgSize = img.total()*img.elemSize();
           uchar sockData[imgSize];
        
         //Receive data here
        
           for (int i = 0; i < imgSize; i += bytes) {
           if ((bytes = recv(connectSock, sockData +i, imgSize  - i, 0)) == -1) {
             quit("recv failed", 1);
            }
           }
        
         // Assign pixel value to img
        
         int ptr=0;
         for (int i = 0;  i < img.rows; i++) {
          for (int j = 0; j < img.cols; j++) {                                     
           img.at<cv::Vec3b>(i,j) = cv::Vec3b(sockData[ptr+ 0],sockData[ptr+1],sockData[ptr+2]);
           ptr=ptr+3;
           }
          }
        

        对于套接字编程,您可以参考link

        使用 Mjpeg Streamer

        在这里,您需要在连接了网络摄像头的 PC 上安装 Mjpeg streamer software,在所有接收 PC 上,您需要安装 OpenCV 并从那里进行处理。您可以使用 OpenCV VideoCapture 类直接打开网络流,如

        Cap.open("http://192.168.1.30:8080/?dummy=param.mjpg");
        

        【讨论】:

        • 我也是这么想的,但是如何将服务器用作网络摄像头模拟器,以便任何应用程序都可以从中检测到提要..?
        • 然后您可以尝试编辑 Mjpeg 流媒体源,您可以直接将 jpg 文件流式传输到网络,您可以通过网络浏览器或 vlc 之类的软件访问此流。因此,您可以编辑 Mjpeg 流媒体使用的 v4l 驱动程序并先处理帧,然后再进行流式处理。试试这个OpenCV ported to Google Chrome NaCl and PNaCl
        • 好的,我试过这样做,但我无法将相机的输入替换为程序输出的输入.. :/
        • 再次,该帖子是如何从相机收集饲料。我已经使用 CvCapture 功能解决了这个问题。只需执行 CvCapture *cam=cvCaptureFromFile("10.11.65.11/mjpg/video.mjpg"); 在这种情况下,我想创建自己的提要,无论是 MJPG 文件还是让 OpenCV 看起来像另一个网络摄像头,类似于笔记本电脑中的一个屏幕。此外,这种套接字方法是我将处理后的图像从我们的机器人(机器人技术)传输到驱动站的方式。将有一个服务器,将数据发送到驱动站终端上的客户端!好运气!
        【解决方案6】:

        这不是微不足道的,但您可以修改像 https://github.com/rdp/screen-capture-recorder-to-video-windows-free 这样的开源“虚拟相机源”,以从 OpenCV 而不是桌面获取其输入。 GL!

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-01-29
          • 1970-01-01
          • 2012-06-19
          • 1970-01-01
          • 2012-01-27
          • 1970-01-01
          • 2016-10-16
          • 2015-03-24
          相关资源
          最近更新 更多