11

我真的无法理解这个,所以我希望有人能帮我一把^^

我正在尝试通过我的网络摄像头检测 C# 中的运动。

到目前为止,我已经尝试了多个库(AForge Lib),但都失败了,因为我不明白如何使用它。

起初我只是想将当前帧的像素与上一个帧的像素进行比较,但结果却完全像 s**t 一样工作:I

现在,我的网络摄像头每次拍摄来自网络摄像头的图片时都会运行一个事件“webcam_ImageCaptured”,这就像 5-10 fps。

但我找不到一种简单的方法来从这两个图像中获得差异,或者至少是一些效果不错的东西。

有没有人知道我可以如何做到这一点相当简单(尽可能)?

4

2 回答 2

12

使用您提到的库让运动检测工作是微不足道的。以下是 AForge(版本 2.2.4)示例。它适用于视频文件,但您可以轻松地将其调整为网络摄像头事件。

Johannes 是对的,但我认为使用这些库可以简化理解基本图像处理的方式。

我的应用程序在具有 SSD 的非常快的机器上以 120FPS 的速度处理 720p 视频,在我的开发笔记本电脑上以大约 50FPS 的速度处理。

public static void Main()
{    
    float motionLevel = 0F;
    System.Drawing.Bitmap bitmap = null;
    AForge.Vision.Motion.MotionDetector motionDetector = null;
    AForge.Video.FFMPEG.VideoFileReader reader = new AForge.Video.FFMPEG.VideoFileReader();    

    motionDetector = GetDefaultMotionDetector();

    reader.Open(@"C:\Temp.wmv");

    while (true)
    {
        bitmap = reader.ReadVideoFrame();
        if (bitmap == null) break;

        // motionLevel will indicate the amount of motion as a percentage.
        motionLevel = motionDetector.ProcessFrame(bitmap);

        // You can also access the detected motion blobs as follows:
        // ((AForge.Vision.Motion.BlobCountingObjectsProcessing) motionDetector.Processor).ObjectRectangles [i]...
    }

    reader.Close();
}

// Play around with this function to tweak results.
public static AForge.Vision.Motion.MotionDetector GetDefaultMotionDetector ()
{
    AForge.Vision.Motion.IMotionDetector detector = null;
    AForge.Vision.Motion.IMotionProcessing processor = null;
    AForge.Vision.Motion.MotionDetector motionDetector = null;

    //detector = new AForge.Vision.Motion.TwoFramesDifferenceDetector()
    //{
    //  DifferenceThreshold = 15,
    //  SuppressNoise = true
    //};

    //detector = new AForge.Vision.Motion.CustomFrameDifferenceDetector()
    //{
    //  DifferenceThreshold = 15,
    //  KeepObjectsEdges = true,
    //  SuppressNoise = true
    //};

    detector = new AForge.Vision.Motion.SimpleBackgroundModelingDetector()
    {
        DifferenceThreshold = 10,
        FramesPerBackgroundUpdate = 10,
        KeepObjectsEdges = true,
        MillisecondsPerBackgroundUpdate = 0,
        SuppressNoise = true
    };

    //processor = new AForge.Vision.Motion.GridMotionAreaProcessing()
    //{
    //  HighlightColor = System.Drawing.Color.Red,
    //  HighlightMotionGrid = true,
    //  GridWidth = 100,
    //  GridHeight = 100,
    //  MotionAmountToHighlight = 100F
    //};

    processor = new AForge.Vision.Motion.BlobCountingObjectsProcessing()
    {
        HighlightColor = System.Drawing.Color.Red,
        HighlightMotionRegions = true,
        MinObjectsHeight = 10,
        MinObjectsWidth = 10
    };

    motionDetector = new AForge.Vision.Motion.MotionDetector(detector, processor);

    return (motionDetector);
}
于 2013-07-13T03:20:21.080 回答
1

运动检测是一个复杂的事情,它需要大量的计算能力。

尝试限制您首先要检测的内容。随着复杂性的增加:你想检测是否有运动吗?你想检测多少运动?您想检测图像的哪些区域实际在移动吗?

我假设您只想知道什么时候发生了变化:

  • 相互减去相邻帧
  • 计算所有像素差的所有平方和
  • 除以像素数
  • 观看您的网络摄像头流的号码。它会有一定的地面噪音,当有东西移动时会显着上升。
  • 尝试仅限于某个颜色通道,这可能会改善情况
于 2013-07-13T00:20:33.323 回答