您的位置:首页 > 编程语言 > Go语言

[导入]Motion Detection Algorithms---动作捕捉算法

2005-08-12 13:55 429 查看
本来想找些关于视频流方面的东西,在CodeProject上搜索了看看,没想到找到很好玩的东西:
视频中Motion Detection(动作捕捉)的一个程序,好文章,翻译一下给大家看看:

// create filters
Difference differenceFilter = new Difference();
IFilter thresholdFilter = new Threshold(15, 255);
// set backgroud frame as an overlay for difference filter
differenceFilter.OverlayImage = backgroundFrame;
// apply the filters
Bitmap tmp1 = differenceFilter.Apply(currentFrame);
Bitmap tmp2 = thresholdFilter.Apply(tmp1);

在这个步骤中,我们可以得到一张图片,当前帧与背景帧中不同的地方,都已经被着成白色。现在,已经可以数出两张图上不同像素点的数目。当这个数目大于一个事先定义好的数字时,我们便可以标注为一个动作事件。
但是,大多数相机照出的照片,都有杂点,所以很有可能在没有任何动作的时候,程序会认为有新的动作发生了。要去处照片上随即的杂点(random noisy pixels), 我们可以用一个
Erosion
filter。 这样,我们可以我们可以得到一个比较真实的结果。

// create filter
IFilter erosionFilter = new Erosion();
// apply the filter
Bitmap tmp3 = erosionFilter.Apply(tmp2);
一个最简单的动作捕捉器已经搞好了,如果需要的话我们可以让有动作的区域高亮显示。

// extract red channel from the original image
IFilter extrachChannel = new ExtractChannel(RGB.R);
Bitmap redChannel = extrachChannel.Apply(image);
// merge red channel with motion regions
Merge mergeFilter = new Merge();
mergeFilter.OverlayImage = tmp3;
Bitmap tmp4 = mergeFilter.Apply(redChannel);
// replace red channel in the original image
ReplaceChannel replaceChannel = new ReplaceChannel(RGB.R);
replaceChannel.ChannelImage = tmp4;
Bitmap tmp5 = replaceChannel.Apply(image);
下面便是结果:
// create filter
MoveTowards moveTowardsFilter = new MoveTowards();
// move background towards current frame
moveTowardsFilter.OverlayImage = currentFrame;
Bitmap tmp = moveTowardsFilter.Apply(backgroundFrame);
// dispose old background
backgroundFrame.Dispose();
backgroundFrame = tmp;
现在,我们可以用相同的方法处理下面的内容。但是我还扩展了这个方法,让它得出更好玩的一个结果。

// create processing filters sequence
FiltersSequence processingFilter = new FiltersSequence();
processingFilter.Add(new Difference(backgroundFrame));
processingFilter.Add(new Threshold(15, 255));
processingFilter.Add(new Opening());
processingFilter.Add(new Edges());
// apply the filter
Bitmap tmp1 = processingFilter.Apply(currentFrame);

// extract red channel from the original image
IFilter extrachChannel = new ExtractChannel(RGB.R);
Bitmap redChannel = extrachChannel.Apply(image);
// merge red channel with moving object borders
Merge mergeFilter = new Merge();
mergeFilter.OverlayImage = tmp1;
Bitmap tmp2 = mergeFilter.Apply(redChannel);
// replace red channel in the original image
ReplaceChannel replaceChannel = new ReplaceChannel(RGB.R);
replaceChannel.ChannelImage = tmp2;
Bitmap tmp3 = replaceChannel.Apply(image);

// create filter
IFilter pixellateFilter = new Pixellate();
// apply the filter
Bitmap newImage = pixellateFilter(image);
这样,我们有了像素处理后的当前帧和原始帧版本。现在,我们需要将背景帧“移向”当前帧(和以前做的一样)。

// create processing filters sequence
FiltersSequence processingFilter = new FiltersSequence();
processingFilter.Add(new Difference(backgroundFrame));
processingFilter.Add(new Threshold(15, 255));
processingFilter.Add(new Dilatation());
processingFilter.Add(new Edges());
// apply the filter
Bitmap tmp1 = processingFilter.Apply(currentFrame);

将tmp1和原始图像的红色段合并后,我们可以得到下面的结果:



可能这看起来没有上面的那张图好,但是这种方法对于程序的优化起了重大的作用。

结论

这里我只是简单讲了思想,想要将这些思想用到真正的程序中去的话,你需要优化很多东西。为了简单我用了image processing library 。它不是一个Video处理库 。但是,这个库使我很快的能够找到不同的region 。在源程序中,有一个小的优化例子。

翻译到此结束,Download source - 114 Kb
我下载了源码,运行后,发现真的很酷,可以链接到网上的好多free camera,监测那边的情况,一有动作,就立刻会显示出来:



看见了吧,连电视机的内动的画面都能发现。不过由于网络的延迟,看了不是很爽。
顺便提一下,截图程序用的是Maxwolf的




文章来源:http://blog.handsbrain.com/leezjs/archive/2005/08/12/9365.aspx
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: