Camera Vision - video surveillance on C#

http://www.codeproject.com/KB/audio-video/cameraviewer.aspx

 

 

开发的资源 


介绍:
纵观当今的监控系统的发展趋势,能很容易发现基于IP的解决方案正在迅速的普及。有许多的制造商,提供广泛的IP视频射像和视频服务器,意味着个人的IP射像监控系统正在普及。更进一步,许多公司提供将CCTV视频监控制系统转换成基于IP的系统的解决方案,巩固现有的设备和构造。对于这些公司提供的不仅是硬件设备,还有软件,有许多其它公司针对于IP视频监控系统的软件开发,为小型企业提供完整的解决方案,同时也对个人提供这类服务。
在这里,我将分享一些关于我用各种IP射像头和视频服务器进行相关开发的经验。提供的信息是关于如何用程序来使用射像头,对于个人来说可能只是一个简单的程序,或其他更加复杂的程序或直接和一些视频监控软件进行工作。
作为演示程序,我使用了C#,它允许射像头和多射像头一样的同时进行拍摄。该程序允许同步成像,不仅是几个视频服务器上的几个射像头,而且允许许多不同的种类的射像头在同一时刻进行拍照。该程序支持的视频资源是:

不断更新JPEG图片资源;
MJPEG(动态JPEG)视频流;
一些Axis射像头和视频服务器(205, 206, 2100, 2110, 2120, 2130R, 2400, 2401, 2460); 
D-Link射像头(仅支持JPEG);
Panasonic射像头;
PiXORD射像头;
StarDot射像头(NetCam, Express 6); 
本地设备,可以支持DirectShow;
MMS (Microsoft Media Services)流;
IP射像头是什么?
IP射像头的特征是可以提供数字信号输出,并可以直接连接在以太网上通过IP网络进行各种操作。为了达到这个目的,IP射像头不仅拥有射像头,而且还需要一台计算机,通常运行的是Linux。计算机的意图是:

将图象压缩成数字图象(一些射像头/服务器 处理CUP外还拥有一个附加的微型压缩处理器);
可以通过IP网络访问图片(通常这些射像头运行在服务器之上,其不只提供访问数字图象的功能,而且还可以通过HTTP来设置射像头的参数)。
视频服务器是非常复杂的设备,通常不带射像头。而是会和若干个视频输入连接设备连接(一般是1到6个),用户可以连接各种射像头。作为IP射像头,视频服务器也将射像头图象转换成数字图象并通过网络提供访问。另外提供建立视频党案的选项(基于这些原因,视频服务器作为一种硬件设备)。
实际上通过网络来访问射像头和服务器是非常有用的。它允许监控不仅是在你安装了射像头的区域中,而且还允许在世界上所有使用监控软件并拥有IP功能的地点进行监控,象浏览器(如以下图片)。象在工作站上工作,或是PDA或其他的手提电话。IP视频方案不仅仅使用在监控和视频备案方面。这种射像头/服务器的视频输出技术可以方便的和许多软件综合在一起:
动态勘测/跟踪(基于完整的视频框架,或相关领域);
交通控制和图形识别
跟踪行人并识别身份;
等。


视频格式:
最简单的视频格式,几乎所有的射像头/服务器都能支持,不应该只被称为一种视频格式。该格式仅是通常的JPEG格式。许多射像头允许通过一个URL来访问一个图片(由射像头的制造商备案的)。例如,一个Axis的射像头允许通过以下URL来访问一个图象:http://webcam.mmhk.cz/axis-cgi/jpg/image.cgi
这种功能有优点也有缺点。缺点是每当你想射像头服务器发送一个HTTP请求就可以得到一张当前图象的图片,由于一些附加数据会损失一些时间(如HTTP头)。优点是监控软件可以方便的控制自身最大数量的刷新率--可以用任意速度访问URL来得到下一祯(每秒或每分钟15次,如果网络和射像头的速度允许)。
第二种流行的格式是MJPEG(动态JPEG)。这种格式不仅仅是下载一张JPEG的图片,而是一个JPEG的流。对一个普通的JPEG格式,客户软件发送HTTP请求到一个指定的射像头URL,如:http://146.176.65.10/axis-cgi/mjpg/video.cgi。但是。在这里射像头将不只是返回一个单一的JPEG,而是一个带有JPEG格式界定的流,该流有HTTP的头标记。当客户不想继续得到视频数据时将关闭和射像头的连接。
MJPEG方式看上去很不错,因为它有个明显的优点--发送HTTP请求就一次并且可以连续的从射像头接受数据。但是用这种方式,你不能方便的控制刷新率。访问一个MJPEG网址,你的射像头将给你一系列预先定义的刷新率。如果你想改变,你需要在URL中增加一些额外的参数。这听起来不是问题,但是实际上,这样会导致一些问题。我先解释一个最普遍的问题。假设你向射像头要求(或默认设置)15个FPS。但是,碰巧,在你和射像头之间的某处速度减慢而使FPS下降为5。假设你的射像头有30祯的缓冲区,这样你的射像头每2秒处理30祯,,但是你在6秒钟内处理完它们,这意味着你将在4秒钟后看到最后一祯--这通常会变的很慢。当然这只是举例来说,射像头会不停刷新缓冲,或做一些其它的事来避免这类等待。但是,我确实遇到过一件事。某人一次进入一个有射像头的屋子,在那呆了一会,然后去了另一间屋子,并在监控程序上看到了他自己的画面(该程序是由射像头制造商提供的)。

许多型号的射像头支持除了JPEG和MJPEG以外的格式。有的支持MPEG-2,还有的支持MPEG-4。当然,一些射像头不只支持视频,同时也支持声音,并且是双向的。
说的更多一点,谈一下关于访问一些射像头--访问单一的JPEG祯,和MJPEG流(MPEG格式也介绍了)。更多的射像头制造商提供了API和SDK,你可以在他们的网站上了解更多有关的信息。
访问JPEG和MJPEG:
从一个JPEG资源(射像头)显示数据是很简单的--你只需要向射像头建立HTTP请求,下载返回的数据,解压成位图文件。这里有一个从IP射像头快速获得一个JPEG祯的例子:
string sourceURL = "http://webcam.mmhk.cz/axis-cgi/jpg/image.cgi";
byte[] buffer = new byte[100000];
int read, total = 0;

//建立HTTP请求
HttpWebRequest req = (HttpWebRequest) WebRequest.Create( sourceURL );

//得到响应
WebResponse resp = req.GetResponse( );

//得到响应流
Stream stream = resp.GetResponseStream( );

//读取流数据
while ( ( read = stream.Read( buffer, total, 1000 ) ) != 0 )
{
    total += read;
}

//得到位图
Bitmap bmp = (Bitmap) Bitmap.FromStream( 
              new MemoryStream( buffer, 0, total ) );


But, don't forget that most cameras are not free with open access like in the sample above. Most probably, you will want to protect your camera with a password, which should be specified somehow: 
不要忘记许多射像头不是向以上代码中那样可以自由访问的。通常是,你将用密码保护你的射像头,这将不知不觉被指定:

//建立HTTP请求
HttpWebRequest req = 
   (HttpWebRequest) WebRequest.Create( sourceURL );

//设置登陆和密码
req.Credentials = new NetworkCredential( login, password );
...


访问MJPEG资源是很复杂的。首先,我们先看一下响应目录类型。如下:
multipart/x-mixed-replace; boundary=--myboundary


也许,他们看上去并不一致,但是它们的类型是多部分/混合拼成,并有明显的分界。这里分界符是"--myboundary"。现在看一个实际的流数据:
--myboundary
Content-Type: image/jpeg

... image binary data ...

--myboundary
Content-Type: image/jpeg

... image binary data ...

--myboundary
Content-Type: image/jpeg

...


将全部总结一下,访问MJPEG资源的步奏已经很清晰了:
解析响应目录类型分解为指定值;
读取流的初始部分,搜索第一个分界;
读取分界的值,然后是下个分解;
解压图片到缓冲区中;
处理图片(显示,或其它);
继续重复3-5步。
事实上,访问一个MJPEG资源的思路并不象开始我讲的那么复杂,但是处理起来也不是象处理JPEG资源那么容易。
Axis射像头和视频服务器:
Axis射像头和视频服务器看上去是我遇到的最好的IP视频射像头。从用户的观点上看,这些射像头提供了很好的视频质量和刷新率,并且安装和设置简单。从开发者的角度来看,这些设备是比较不错的--这家公司是我遇到的在IP射像头方面提供最好的开发文党的。公司提供了完整的文党和用HTTP访问射像头的SDK。
以下是访问Axis IP 射像头/服务器端的JPEG和MJPEG流的URL:
JPEG:
http://<servername>/axis-cgi/jpg/image.cgi
MJPEG:
http://<servername>/axis-cgi/mjpg/video.cgi

两个URL是允许一些参数的,会影响显示效果。最普通的参数是定义(指定视频输出的大小),射像头(指定视频服务器上的射像头数量),刷新率(只在MJPEG时):
Samples:
http://<servername>/axis-cgi/jpg/image.cgi?resolution=320x240
http://<servername>/axis-cgi/mjpg/video.cgi?camera=2
http://<servername>/axis-cgi/mjpg/video.cgi?camera=2&des_fps=5

获得完整的HTTP API 和所有参数的列表,向Axis的网站提交请求。
StarDot 射像头和视频服务器:
看上去StarDot 射像头和视频服务器没有提供广泛的IP射像头和视频服务器,并且近两年也没变化。他们现有的全部是一个IP射像头的模型和一个视频服务器的模型。对于我来说,认为它们只有一个优点就是可以将对射像头的支持提高的6个。其它方面和Axis比没有任何竞争力。例如,刷新率非常的低(对于安全性没保障)并且射像头不支持MJPEG。相关开发人员的评论也很少。
U访问他们产品的URL格式很简单:
StarDot NetCam:
http://<servername>/netcam.jpg
StarDot Express 6 (video server)
http://<servername>/jpeg.cgi?<cameranumber>
http://<servername>/jpeg.cgi?3       

PiXORD射像头:
PiXORD的产品由各种不同模型的IP射像头组成,看起来确实是个不错的射像头,提供很好的质量和刷新率并支持MJPEG流。公司提供产品的SDK,但必须用户注册后才能得到。
以下是访问他们IP射像头的URL格式:
JPEG:
http://<servername>/images<channel><resolution>
http://<servername>/images1sif
MJPEG:
http://<servername>/getimage?camera=<channel>[&fmt=<resolution>][&delay=<delay>]
http://<servername>/getimage?camera=1&fmt=sif&delay=10

Panasonic射像头:
我没过多的接触Panasonic射像头,只是在网上找到几个射像头,你也可以在提供的例子中找到。
访问Panasonic射像头的URL格式:
JPEG:
http://<servername>/SnapshotJPEG[?Resolution=<resolution>][&Quality=<quality>]
http://<servername>/SnapshotJPEG?Resolution=320x240&Quality=Standard
MJPEG:
http://<servername>/nphMotionJpeg[?Resolution=<resolution>][&Quality=<quality>]
http://<servername>/nphMotionJpeg?Resolution=320x240&Quality=Standard


At this moment, I know only one way to access D-Link cameras (JPEG format):
D-Link射像头:
D-Link的IP视频射像头范围很广,并且是第一个开始在射像头上使用MPEG-4的公司。事实上,这些射像头是把MPEG做为首要应用的-不再支持其他类型。其中他们的大部分射像头支持声音处理,一些甚至支持双向处理。从用户的观点来看,非常容易安装和设置。支持很多的设置。从开发者的角度来看,这些射像头并不容易使用。公司不希望共享大部分的开发资料,也很难找到一些开发者的资料。这使得开发一些用户自己的监控软件变的非常困难。另外,之前我提到的某人从一个房间进入另一个房间看见自己图象的用的就是D-Link射像头。
访问D-Link射像头(JPEG格式)的URL:
http://<servername>/cgi-bin/video.jpg

其它一些视频资源:
很多其它的视频资源可以用HTTP以外的方式访问。比如,可以方便的访问一个本地网络射像头通过USB端口,或远程访问视频流通过MMS(Microsoft Media Services)。最一般的方式用来访问这两类视频资源使用的是DirectShow。事例代码使用的就是这种技术,你可以在别的文章里了解更多内容。
程序代码:
程序的主要意图是使其具有灵活性和扩展性。程序本身可以和任何视频资源通信-可能是IP射像头或是服务器。可以是本地USB射像头,可以是远程服务器的MMS视频流,或是其它的视频资源。该程序可以同时和这些资源进行工作,在屏幕上显示。
另一个主要的特征是可以扩展功能。主程序模块不知道任何视频资源和如何定义它们;只知道怎样显示它们。全部特殊视频资源的通信逻辑隐藏在不同的几个模块中,并且程序并不紧密的将他们连接在一起。如果你有一个新的视频资源,并且你想要程序和其一起工作,你不需要改变任何程序本身的代码。只是建立一个新的模块并建立和视频资源的响应就可以了,然后将模块放置到程序的文件夹里。
处理该问题的关键是建立一个描述所有视频资源功能的类。该类就是IVideoSource。然后,在类中建立成员并封装所有和特殊视频资源通信解压缩图片的命令。为程序提供每个类的图表,带的代码不是程序的代码,但是可以分别编译,提供给程序模块,可以方便的加到程序中来扩展其功能。
每个视频资源模块包含了一个所提供视频的确定数字--类提供访问视频资源。大多数模块包含仅视频源,但其中一些拥有几个--可能提供组视频(所有视频源访问同一个制造商的射像头/服务器规定到同一个模块中,例如)。
所有这些视频源可以作为完整的类,用来在程序中访问不同的视频资源。但仍然有两个被遗忘的事情,使其具有扩展性和可配置性。首先,我们的视频源应该有自我描述性和自我配置性。出于该目的,两个类添加进来:IVideoSourceDescription 和 IVideoSourcePage。每个类,拥有成员,提供名称和对资源的描述,允许保存和调用配置和对视频资源的建立过程。IVideoSourcePage的成员提供了一个属性页以便对视频资源进行配置。这些增加的类同样和视频资源模块想联系。将所有包装到一起成为一个最简单的模块,包含仅一个视频资源,应该包含三个类:资源描述,资源定义,和视频自身处理。
最后使起工作还是要落实在程序方面--程序可以找到所有模块并搜集所有关于视频资源的信息。实际上通过镜像可以轻易完成。首先,程序搜索所有的程序文件夹中DLL文件。然后,试图作为汇编和媒举调用每个文件,搜索IVideoSourceDescription 类成员的类型。一旦一个类型被发现,将提供视频资源的名称,描述和相关信息。该模块的计算过程只在程序开始时调用一次,但程序可以方便的修改,用户也可以调用该过程(如果用户方便的添加一个新的视频模块,而不需要重新启动程序)。
一些低层技术:
.NET1.0和1.1的framework存在BUG,事实上并不是BUG,而是一个特征。但该特征导致了很大的问题,在MJPEG模式下和射像头进行通讯时。这个问题是一些MJPEG视频资源不会100%确认HTTP。如果说句不好听的--微软太吹毛求疵,在他们的早期的framework版本中过分的对HTTP协议强调标准了。一些射像头稍微丢失了一些HTTP头信息,.NET立刻拒绝继续工作,并包出网络异常,如下:
The underlying connection was closed: 
    The server committed an HTTP protocol violation.
幸运的是,这只是.NET的一个特征,以后可能会纠正。首先,你至少要用1.1的版本并安装第一个服务包。然后,你再建立一个程序配置文件,并将其放到程序文件夹里。以下是一个使MJPEG资源工作的最小环境:
<configuration>
    <startup>
        <supportedRuntime version="v1.1.4322" />
    </startup>
    <system.net>
        <settings>
            <httpWebRequest useUnsafeHeaderParsing="true" />
        </settings>
    </system.net>
</configuration>

另一个问题是.NET的HttpWebRequest类有一个作为连接组的特征。默认时,所有HTTP请求是建立在相同的连接组中的,但是每个连接组有一个并发连接的限制。所以,这就有个大问题,你不能同时监控制很多的射像头。好消息是问题也可以方便的解决--HttpWebRequest类有一个属性ConnectionGroupName,你可以安排你自己的连接组。
结论:
绑定程序演示了所有技术,允许监控很多不同的射像头。程序允许你监控一个单一的射像头,或在一个屏幕上监控几个射像头(在全屏下)。请不要把该程序作为一个完整的监控程序系统,着只是一个演示。是为了明白概念,但可以做为你自己程序的一个起点。尽管该程序可能出于个人原因而被使用。
你可以去找一些另外的这类程序代码,同样也是监控方面的 ,同样基于我在这里介绍的技术。
演示程序包含了许多自由射像头:Las Vegas, Stuttgart Airport,还有其它很多。你可以容易的发现更多方便访问的射像头,将它们添加到程序里,看看能不能监控。 

posted @ 2010-12-13 12:17  张兴业  阅读(440)  评论(0编辑  收藏  举报