无法使用 EMGU CV 连续从 RTSP 流中抓取图像
Unable to use EMGU CV to grab images from RTSP stream continuously
我正在尝试使用 C# Windows Forms 应用程序从网络摄像机的 RTSP 流中获取图像。我正在使用 EMGU CV 连续捕获流,但 RTSP Steam 在几秒钟后停止,然后 imageGrabbedEvent 永远不会触发。
我的目的很简单:从相机中获取每一帧并进行分析。
我正在使用 IP 地址为 192.168.1.64 的 HIKVision IP 摄像机 (DS-2CD2683G1-IZ) 在端口 554 上流式传输 RTSP(这是许多 Hikvision IP 摄像机的默认 IP 地址和端口号)
DateTime LastTimeImageGrabReinitialised = new DateTime();
public void InitializeCameraEMGUStream()
{
//added a datetime to the URL as recommended by another answer but it didnt help.
VideoCapture myVideoCapture = new VideoCapture("rtsp://admin:mysecretpassword@192.168.1.64:554/ch1/main/av_stream?"+DateTime.Now.ToString());
myVideoCapture.ImageGrabbed += imageGrabbedEvent;
myVideoCapture.Start();
LastTimeImageGrabReinitialised = DateTime.Now;
}
private void imageGrabbedEvent(object sender, EventArgs e)
{
lastTimeImageGrabbed = DateTime.Now;
try
{
Mat m = new Mat();
myVideoCapture.Retrieve(m);
LatestAcquiredImage = m.ToImage<Bgr, byte>().Bitmap;
pictureBox.Image = m.ToImage<Bgr, byte>().Bitmap;
imgEntrada = m.ToImage<Bgr, byte>();
}
catch (Exception Ex)
{
}
//I tried adding some logic to reinitialize the stream after a few hundred milliseconds,
//but it seems the reinitialization takes a while to obtain a clear image and many frames cannot be read.
if((DateTime.Now- LastTimeImageGrabReinitialised).TotalMilliseconds>200)
{
myVideoCapture.Start();
LastTimeImageGrabReinitialised = DateTime.Now;
}
}
我浏览了几个在线可用的答案,但找不到让流保持活跃的确定方法。如果能在这方面提供任何帮助,我将不胜感激。
仅供参考:我已经尝试过的:
我尝试每隔一段时间重新初始化 VideoCapture,但速度很慢,许多初始帧都是 noisy/unclear 图像。
我已经尝试使用 VLC.Dotnet 到 运行 RTSP 流,流工作得很好但是抓取图像并将其转换为图像非常慢,主要是因为 VLCControl.TakeSnapshot() 将文件保存在磁盘上。充其量,这会消耗超过 500 毫秒,并且在此期间会丢失许多帧。
我还尝试使用 RTSPClientSharp,在使用它时,imageGrabbed 事件会定期触发,但我无法显示解码图像。
我尝试使用 HTTP 从相机获取图像,但是,每张图像需要超过 600 毫秒才能到达,同时相机不会接受任何其他连接请求,因此再次出现许多帧迷路了。
我在 RTSP 流中遇到了类似的问题,我通过使用 QueryFrame
和超时而不是 ImageGrabbed
事件解决了它,所以这可能值得用你的相机试试。这是抓取帧的主要处理循环,我没有观察到任何意外丢帧我只看到 QueryFrame
超时,原因是相机断电:
try
{
if (!cameraOpened)
{
LogMessage("Opening camera stream...");
var openTask = Task.Run(() => capture = new Capture("rtsp://admin:redacted@10.0.0.22:554"));
if (await Task.WhenAny(openTask, Task.Delay(20000)) != openTask)
{
LogMessage("Unable to open camera stream");
}
else
{
LogMessage("Camera stream opened");
cameraOpened = true;
}
}
if (cameraOpened)
{
var captureTask = Task.Run(() => inputFrame = capture.QueryFrame());
if (await Task.WhenAny(captureTask, Task.Delay(5000)) != captureTask)
{
LogMessage("Camera connection lost");
cameraOpened = false;
}
else
{
if (inputFrame != null && !inputFrame.IsEmpty)
{
frameQueue.Enqueue(inputFrame);
}
}
}
} catch (Exception ex)
{
LogMessage(ex.Message);
Thread.Sleep(5000);
}
frameQueue
声明如下,处理发生在一个单独的线程中,这也可能有所帮助。我很久以前写了代码,而不是我现在使用 ConcurrentQueue
class.
Queue myQ = new Queue();
Queue frameQueue = Queue.Synchronized(myQ);
我终于找到了解决办法。
虽然 Emgu 的 RTSP 流采集器不稳定,但 RTSPClientSharp 是一个非常稳定的实现,用于从 RTSP 流中采集单个帧并将它们转换为位图,您可以将其用于 .NET 中的任何图像处理。 GitWorks 中提供的示例开箱即用。
https://github.com/BogdanovKirill/RtspClientSharp
从GitHub下载项目后,您可以尝试使用以下流进行抓取(如果仍然在线,请使用VLC检查以确保流仍然可用)
rtsp://rtsp.stream/pattern
我正在尝试使用 C# Windows Forms 应用程序从网络摄像机的 RTSP 流中获取图像。我正在使用 EMGU CV 连续捕获流,但 RTSP Steam 在几秒钟后停止,然后 imageGrabbedEvent 永远不会触发。
我的目的很简单:从相机中获取每一帧并进行分析。
我正在使用 IP 地址为 192.168.1.64 的 HIKVision IP 摄像机 (DS-2CD2683G1-IZ) 在端口 554 上流式传输 RTSP(这是许多 Hikvision IP 摄像机的默认 IP 地址和端口号)
DateTime LastTimeImageGrabReinitialised = new DateTime();
public void InitializeCameraEMGUStream()
{
//added a datetime to the URL as recommended by another answer but it didnt help.
VideoCapture myVideoCapture = new VideoCapture("rtsp://admin:mysecretpassword@192.168.1.64:554/ch1/main/av_stream?"+DateTime.Now.ToString());
myVideoCapture.ImageGrabbed += imageGrabbedEvent;
myVideoCapture.Start();
LastTimeImageGrabReinitialised = DateTime.Now;
}
private void imageGrabbedEvent(object sender, EventArgs e)
{
lastTimeImageGrabbed = DateTime.Now;
try
{
Mat m = new Mat();
myVideoCapture.Retrieve(m);
LatestAcquiredImage = m.ToImage<Bgr, byte>().Bitmap;
pictureBox.Image = m.ToImage<Bgr, byte>().Bitmap;
imgEntrada = m.ToImage<Bgr, byte>();
}
catch (Exception Ex)
{
}
//I tried adding some logic to reinitialize the stream after a few hundred milliseconds,
//but it seems the reinitialization takes a while to obtain a clear image and many frames cannot be read.
if((DateTime.Now- LastTimeImageGrabReinitialised).TotalMilliseconds>200)
{
myVideoCapture.Start();
LastTimeImageGrabReinitialised = DateTime.Now;
}
}
我浏览了几个在线可用的答案,但找不到让流保持活跃的确定方法。如果能在这方面提供任何帮助,我将不胜感激。
仅供参考:我已经尝试过的:
我尝试每隔一段时间重新初始化 VideoCapture,但速度很慢,许多初始帧都是 noisy/unclear 图像。
我已经尝试使用 VLC.Dotnet 到 运行 RTSP 流,流工作得很好但是抓取图像并将其转换为图像非常慢,主要是因为 VLCControl.TakeSnapshot() 将文件保存在磁盘上。充其量,这会消耗超过 500 毫秒,并且在此期间会丢失许多帧。
我还尝试使用 RTSPClientSharp,在使用它时,imageGrabbed 事件会定期触发,但我无法显示解码图像。
我尝试使用 HTTP 从相机获取图像,但是,每张图像需要超过 600 毫秒才能到达,同时相机不会接受任何其他连接请求,因此再次出现许多帧迷路了。
我在 RTSP 流中遇到了类似的问题,我通过使用 QueryFrame
和超时而不是 ImageGrabbed
事件解决了它,所以这可能值得用你的相机试试。这是抓取帧的主要处理循环,我没有观察到任何意外丢帧我只看到 QueryFrame
超时,原因是相机断电:
try
{
if (!cameraOpened)
{
LogMessage("Opening camera stream...");
var openTask = Task.Run(() => capture = new Capture("rtsp://admin:redacted@10.0.0.22:554"));
if (await Task.WhenAny(openTask, Task.Delay(20000)) != openTask)
{
LogMessage("Unable to open camera stream");
}
else
{
LogMessage("Camera stream opened");
cameraOpened = true;
}
}
if (cameraOpened)
{
var captureTask = Task.Run(() => inputFrame = capture.QueryFrame());
if (await Task.WhenAny(captureTask, Task.Delay(5000)) != captureTask)
{
LogMessage("Camera connection lost");
cameraOpened = false;
}
else
{
if (inputFrame != null && !inputFrame.IsEmpty)
{
frameQueue.Enqueue(inputFrame);
}
}
}
} catch (Exception ex)
{
LogMessage(ex.Message);
Thread.Sleep(5000);
}
frameQueue
声明如下,处理发生在一个单独的线程中,这也可能有所帮助。我很久以前写了代码,而不是我现在使用 ConcurrentQueue
class.
Queue myQ = new Queue();
Queue frameQueue = Queue.Synchronized(myQ);
我终于找到了解决办法。
虽然 Emgu 的 RTSP 流采集器不稳定,但 RTSPClientSharp 是一个非常稳定的实现,用于从 RTSP 流中采集单个帧并将它们转换为位图,您可以将其用于 .NET 中的任何图像处理。 GitWorks 中提供的示例开箱即用。
https://github.com/BogdanovKirill/RtspClientSharp
从GitHub下载项目后,您可以尝试使用以下流进行抓取(如果仍然在线,请使用VLC检查以确保流仍然可用)
rtsp://rtsp.stream/pattern