Windows 到 EmguCV VideoCapture 的命名管道
Windows named pipe to EmguCV VideoCapture
我想在 C# 中使用 emguCV 显示 h264 视频流。如果我使用 raspberry pi,我使用 netcat 从 raspberry pi 发送流我可以看到流但不是来自 c# 程序(我是 emgucv 的新手)。
NamedPipeServerStream ncatPipe = new NamedPipeServerStream(
"ncatPipe",
PipeDirection.InOut,
NamedPipeServerStream.MaxAllowedServerInstances,
PipeTransmissionMode.Message,
PipeOptions.None,
1024,
1024
);
Process ncat = new Process();
ncat.StartInfo.FileName = "CMD.exe";
ncat.StartInfo.Arguments = "/C ncat -v -l 5000 >\\.\pipe\ncatPipe 2>nul";
ncat.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
ncat.Start();
ncatPipe.WaitForConnection();
VideoCapture videoCapture = new VideoCapture("\\.\pipe\ncatPipe");
videoCapture.SetCaptureProperty(Emgu.CV.CvEnum.CapProp.FourCC, VideoWriter.Fourcc('h', '2', '6', '4'));
videoCapture.SetCaptureProperty(Emgu.CV.CvEnum.CapProp.Fps, 60);
videoCapture.SetCaptureProperty(Emgu.CV.CvEnum.CapProp.FrameHeight, 480);
videoCapture.SetCaptureProperty(Emgu.CV.CvEnum.CapProp.FrameWidth, 640);
Timer playerTimer = new Timer();
playerTimer.Interval = 1000 / 60;
playerTimer.Tick += new EventHandler((object sender1, EventArgs e1) =>
{
Bitmap captureBmp = videoCapture.QueryFrame().Bitmap;
if (captureBmp != null)
{
picture.Image = captureBmp;
}
else
{
picture.Image = null;
playerTimer.Stop();
ncatPipe.Disconnect();
ncatPipe.Dispose();
ncat.Kill();
ncat.Dispose();
videoCapture.Dispose();
}
});
playerTimer.Start();
Exception thrown: 'Emgu.CV.Util.CvException' in Emgu.CV.World.dll
[ERROR:0] global D:\bb\cv_x86\build\opencv\modules\videoio\src\cap.cpp
(122) cv::VideoCapture::open VIDEOIO(CV_IMAGES): raised unknown C++
exception!
编辑 1:现在我正在尝试使用 FFMPEG 从管道中获取位图帧。
编辑 2:FFMPEG 有效,但我的延迟约为 4000 毫秒。
Mencoder 解决方案延迟:200ms~,
结合 mplayer gpu acc 的延迟甚至更低。 window 在表格中。
windows Mplayer 和 Mencoder 版本:http://mplayerwin.sourceforge.net/downloads.html
(在客户端上设置更高的 fps 自动修复延迟(使用 Mplayer 和 Mencoder))
Raspberry PI 命令:
raspivid -t 0 -n -o - -fl -md 4 -w 1296 -h 972 -fps 30 -ih | nc -u 192.168.137.1 5000
C#:
Process ncat = new Process();
ncat.StartInfo.FileName = "ncat\ncat.exe";
ncat.StartInfo.Arguments = "-u -l 5000";
ncat.StartInfo.UseShellExecute = false;
ncat.StartInfo.CreateNoWindow = true;
ncat.StartInfo.RedirectStandardOutput = true;
ncat.Start();
Process mencoder = new Process();
mencoder.StartInfo.FileName = "mplayer\mencoder.exe";
mencoder.StartInfo.Arguments = "-fps 60 -nosound - -ofps 30 -ovc raw -of rawvideo -vf format=bgr24 -really-quiet -o -";
mencoder.StartInfo.UseShellExecute = false;
mencoder.StartInfo.CreateNoWindow = true;
mencoder.StartInfo.RedirectStandardInput = true;
mencoder.StartInfo.RedirectStandardOutput = true;
mencoder.Start();
ncat.StandardOutput.BaseStream.CopyToAsync(mencoder.StandardInput.BaseStream);
byte[] raw = new byte[1296 * 972 * 3];
byte[,,] rawEmgu = new byte[972, 1296, 3];
while (true)
{
mencoder.StandardOutput.BaseStream.Flush();
mencoder.StandardOutput.BaseStream.Read(raw, 0, 1296 * 972 * 3);
int n = 0;
for (int y = 0; y < 972; y++)
{
for (int x = 0; x < 1296; x++)
{
rawEmgu[y, x, 0] = raw[n++];
rawEmgu[y, x, 1] = raw[n++];
rawEmgu[y, x, 2] = raw[n++];
}
}
imageBox1.Image = new Image<Bgr, Byte>(rawEmgu);
}
我想在 C# 中使用 emguCV 显示 h264 视频流。如果我使用 raspberry pi,我使用 netcat 从 raspberry pi 发送流我可以看到流但不是来自 c# 程序(我是 emgucv 的新手)。
NamedPipeServerStream ncatPipe = new NamedPipeServerStream(
"ncatPipe",
PipeDirection.InOut,
NamedPipeServerStream.MaxAllowedServerInstances,
PipeTransmissionMode.Message,
PipeOptions.None,
1024,
1024
);
Process ncat = new Process();
ncat.StartInfo.FileName = "CMD.exe";
ncat.StartInfo.Arguments = "/C ncat -v -l 5000 >\\.\pipe\ncatPipe 2>nul";
ncat.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
ncat.Start();
ncatPipe.WaitForConnection();
VideoCapture videoCapture = new VideoCapture("\\.\pipe\ncatPipe");
videoCapture.SetCaptureProperty(Emgu.CV.CvEnum.CapProp.FourCC, VideoWriter.Fourcc('h', '2', '6', '4'));
videoCapture.SetCaptureProperty(Emgu.CV.CvEnum.CapProp.Fps, 60);
videoCapture.SetCaptureProperty(Emgu.CV.CvEnum.CapProp.FrameHeight, 480);
videoCapture.SetCaptureProperty(Emgu.CV.CvEnum.CapProp.FrameWidth, 640);
Timer playerTimer = new Timer();
playerTimer.Interval = 1000 / 60;
playerTimer.Tick += new EventHandler((object sender1, EventArgs e1) =>
{
Bitmap captureBmp = videoCapture.QueryFrame().Bitmap;
if (captureBmp != null)
{
picture.Image = captureBmp;
}
else
{
picture.Image = null;
playerTimer.Stop();
ncatPipe.Disconnect();
ncatPipe.Dispose();
ncat.Kill();
ncat.Dispose();
videoCapture.Dispose();
}
});
playerTimer.Start();
Exception thrown: 'Emgu.CV.Util.CvException' in Emgu.CV.World.dll
[ERROR:0] global D:\bb\cv_x86\build\opencv\modules\videoio\src\cap.cpp (122) cv::VideoCapture::open VIDEOIO(CV_IMAGES): raised unknown C++ exception!
编辑 1:现在我正在尝试使用 FFMPEG 从管道中获取位图帧。
编辑 2:FFMPEG 有效,但我的延迟约为 4000 毫秒。
Mencoder 解决方案延迟:200ms~, 结合 mplayer gpu acc 的延迟甚至更低。 window 在表格中。 windows Mplayer 和 Mencoder 版本:http://mplayerwin.sourceforge.net/downloads.html
(在客户端上设置更高的 fps 自动修复延迟(使用 Mplayer 和 Mencoder))
Raspberry PI 命令:
raspivid -t 0 -n -o - -fl -md 4 -w 1296 -h 972 -fps 30 -ih | nc -u 192.168.137.1 5000
C#:
Process ncat = new Process();
ncat.StartInfo.FileName = "ncat\ncat.exe";
ncat.StartInfo.Arguments = "-u -l 5000";
ncat.StartInfo.UseShellExecute = false;
ncat.StartInfo.CreateNoWindow = true;
ncat.StartInfo.RedirectStandardOutput = true;
ncat.Start();
Process mencoder = new Process();
mencoder.StartInfo.FileName = "mplayer\mencoder.exe";
mencoder.StartInfo.Arguments = "-fps 60 -nosound - -ofps 30 -ovc raw -of rawvideo -vf format=bgr24 -really-quiet -o -";
mencoder.StartInfo.UseShellExecute = false;
mencoder.StartInfo.CreateNoWindow = true;
mencoder.StartInfo.RedirectStandardInput = true;
mencoder.StartInfo.RedirectStandardOutput = true;
mencoder.Start();
ncat.StandardOutput.BaseStream.CopyToAsync(mencoder.StandardInput.BaseStream);
byte[] raw = new byte[1296 * 972 * 3];
byte[,,] rawEmgu = new byte[972, 1296, 3];
while (true)
{
mencoder.StandardOutput.BaseStream.Flush();
mencoder.StandardOutput.BaseStream.Read(raw, 0, 1296 * 972 * 3);
int n = 0;
for (int y = 0; y < 972; y++)
{
for (int x = 0; x < 1296; x++)
{
rawEmgu[y, x, 0] = raw[n++];
rawEmgu[y, x, 1] = raw[n++];
rawEmgu[y, x, 2] = raw[n++];
}
}
imageBox1.Image = new Image<Bgr, Byte>(rawEmgu);
}