所以,我想编写一个程序,使OpenCV的处理输出被视为WebCam。我想用它为像Skype这样的程序创建效果。我被困住了,谷歌搜索没有帮助。请帮我。我需要为此获得一个驱动程序吗?如何将AVI存储为AVI并将AVI与其他应用程序一起流式传输?
我想编写一个程序来掩盖我的脸,所以当与我正在辅导但不亲自知道的人Skype上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快递 Windows 7的: OpenCV未安装 Windows 8.1 Pro: OpenCV 2.4.8.0,最新二进制文件,x86,Visual Studio Express 2013 Express Desktop,Hyper-V,与Windows 7相同的配置:1
我注意到有点混乱。我正在尝试使用开放式CV中的进程输出并将其发送到另一个程序,如Skype。主要目的是我要教小学儿童节目和OpenCV。我想直接输出输出,所以我不必共享我的桌面。
答案 0 :(得分:8)
我遇到了同样的问题:我的祖母听得不好,所以我希望能够将字幕添加到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)
答案 1 :(得分:3)
所以,我发现了这个黑客;不一定是最好的方法,但它绝对有效..
下载与SplitCam类似的程序;这可以模拟来自视频文件,IP Feed和/或桌面屏幕特定部分的网络摄像头Feed ..
所以从本质上讲,您可以编写一个程序来处理网络摄像头视频并使用OpenCV的highgui窗口显示它,您可以使用SplitCam将此窗口作为任何其他应用程序(如Skype)的输入。我现在尝试了它完美无缺。!
HTH
答案 2 :(得分:0)
一种方法是将Mat对象直接发送到套接字并在接收端将字节数组转换为Mat,但问题是您需要在两台PC上安装OpenCV。在另一种方式中,您可以使用Mjpeg流媒体将视频流式传输到ibternet并在接收端处理视频,这里您只需要在接收端安装OpenCV。
使用套接字
获取Mat.data并直接发送到套接字,数据格式类似于BGR BGR BGR ....在接收方,您应该知道您将要接收的图像大小。收到后,只需将收到的缓冲区(BGR BGR ...数组)分配给您已知的大小的垫子。
客户端: -
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");
答案 3 :(得分:0)
不是一件容易的事,但你可以修改一个开源的虚拟摄像机来源&#34;像https://github.com/rdp/screen-capture-recorder-to-video-windows-free一样从OpenCV而不是桌面获取输入。 GL!
答案 4 :(得分:0)
签出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 :(得分:0)
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()