视频监控开发文档(设计报告)

视频监控系统

The elevator monitoring system

队伍编号:B-SD-20140091:

参赛学校:青岛理工大学琴岛学院

作者:王国佩、王军、贺强

指导教师:江艳飞

组别:□工程硕士组?本科组□高职组

参选奖项:?标准赛项□恩智浦专项□风河专项

摘要

随着电子信息技术、网络技术、图像处理等技术的飞速发展,嵌入式视频监控技术应运而生。基于嵌入式技术的视频监控以其高灵活性、高集成性、低成本性、便捷性以及其具有较好的稳定性和实时性等优点必将取代传统的视频监控模式。

本监控系统采用三星公司的S3C2410微处理器芯片为核心的ARM9 开发板为硬件平台,根据视频数据采集以及压缩处理的需要选择摄像头和微处理器,搭建好硬件平台,首先完成了嵌入式系统的交叉开发环境搭建,然后完成了在开发板上操作系统内核、文件系统和设备驱动的移植,在其上搭建LINUX 系统的网络视频服务器,并运用了多线程技术,可同时为多个客户端提供实图像频数据,运用Socket通信将采集到的图像数据发送给客户机端。

本项目的客户端,主要是实现把采集的视频数据在客户端界面显示。此客户端以Qt为开发平台,,采用socket通信编程,集数据连接、数据传输、数据显示于一体,具有登录验证界面,界面设计简洁大方,功能清晰。进而实现显示实时图像和拍照的功能。

关键词:嵌入式系统;ARM9;S3C2410;V4L;Qt

Abstract

With the rapid development of technology such as electronic information technology, network technology and photoshop thechnology, linux video monitoring technology arises at the historic moment. Because the video monitoring used linux technology has the advantages of high flexibility, high integrity, low cost, more conveniency, good stability and instantaneity, which decide that the traditional vedio monitoring mode will be replaced.

This monitoring system uses ARM9 demoboard which is the core of SAMSUNG S3C2410 microprocessor chip as hardware platform. To build hardware platform, choosing camera and microprocessor should be based on the needs of video data acquisition and compression processing. Firstly, the paper completed the cross development environment of linux system. And then the paper completed the operating system kernel, file system, and the transplantation of device drivers on the development board, on the basis of which built the network video server of linux system and also used the multithreading technology which can provide the real images for multiple clients at the same time. Finally, this paper finished the video collection under Linux based on V4L.

The objective of the client, mainly the acquisition of video data in the client interface display.This client for Qt development platform, and USES the socket communication programming, data connection, data transmission and data display at an organic whole, have login authentication interface, interface design is concise and easy, clear function.To realize the function display real-time images and pictures.

Key words: Embedded Operating System ARM9 S3C2410 V4L Qt

目录

第1章绪论 (1)

第2章系统方案 (2)

2.1系统总体方案介绍 (2)

2.2 Linux 内核的移植 (2)

2.3 Linux 根文件系统制作 (3)

2.4 Linux 设备驱动移植 (5)

2.4.1 Linux设备驱动的简介 (5)

2.4.2 摄像头设备驱动移植 (6)

2.5 服务器端软件设计 (7)

2.5.1基于V4L的视频采集软件设计 (7)

2.5.2视频采集软件设计流程 (8)

2.5.3 服务端的SOCKET设计 (10)

2.6 客户端软件设计 (11)

2.6.1客户端UI界面设计 (11)

2.6.2 SOCKET通讯 (12)

2.6.3 图像的调取 (15)

第3章功能与指标 (16)

3.1功能 (16)

3.2指标 (16)

第4章实现原理 (17)

4.1 V4L (17)

4.2 socket (17)

4.3 QT (18)

第5章硬件框图 (19)

5.1 S3C2410 ARM体系结构框图 (19)

5.2 博创S3C2410/PXA270开发箱硬件架构 (20)

5.3 USB数字摄像头的结构框图 (20)

第6章特色 (22)

结论 (23)

参考文献 (25)

第1章绪论

随着科技的发展和社会的进步,视频监控不断应用到社会的各行各业,日益受到人们的关注。如银行系统可以通过网络视频监控对各个营业网点以及ATM机远程监控,以便及时发现异常情况并予以处理。视频监控业务具有悠久的历史,在传统上广泛应用于安防领域。

目前国内还较多地使用本地模拟图像监控系统,主要是由模拟摄像头构成的闭路监控系统。虽然本地模拟图像监控系统能够保证采集得到的图像清晰、不失帧,但在许多方面都存在着明显的局限:第一、系统的可扩展性差,由于电视或计算机与摄像头的接口数目是有限的,因此扩展性差,无法形成复杂的监控网络;第二、无法利用现有的网络,必须重新铺设专用线路,极大地浪费了资金。

伴随着计算机技术、图像处理技术和网络技术的发展,出现了新型的基于嵌入式技术的有线网络数字视频监控系统。它有很多突出优点:系统提供友好的用户接口,采用多级权限控制,定制用户组,授权用户只能进行相应操作。用户可以实时监控视频信号、查看视频设备状态等。因此基于嵌入式技术的网络视频监控系统将有良好的应用与发展前景。

本文研究的目的就是实现视频的实时采集,网络传输和终端显示,利用S3C2410这个高性价比ARM 处理器进行数据采集,通过SOCKET通讯传输监控数据,最终在客户端显示监控图像。

本文研究的意义在于将嵌入式技术应用到视频监控网络环境中,解决现有监控系统的弊端,实现多客户端同时监控,通过网络传输,可以利用先有的网络进行资源共享,不受地域的限制。也可以用于普通家庭的安全监控系统。

本论文完成的是基于ARM9的微处理器和USB数字摄像头的嵌入式视频采集模块的设计,即视频监控前端。选用以ARM9为核心的S3C2410处理器嵌入式平台,研究开发基于V4L的视频采集程序。本课题的最终目标是成功开发出具有性能高、功耗低等优点的监控系统。

论文组织结构如下:

以ARM9为核心的S3C2410处理器的体系结构,搭建好视频采集系统的硬件开发平台;视频采集系统软件开发环境搭建,包括Linux内核和文件系统的移植,Linux下摄像头驱动程序的开发;视频采集的软件设计,利用Linux的Video4Linux(V4L)的接口函数(API),编写系统应用软件,开发高速视频数据的采集程序,通过SOCKET通讯将数据从网络上传输,最后搭建QT平台,构建程序,完成服务端到客户端的设计。

第2章系统方案

2.1系统总体方案介绍

视频监控系统由监控前端,监控终端和网络传输三部分组成。监控前端用摄像头进行视频数据的采集,进行处理后,通过网络传输到监控终端,由监控终端的应用程序进行视频数据的解码和存储显示,实现远程视频监控的作用。

本文选用Samsung公司的以ARM9为核心的S3C2410处理器嵌入式平台,它通过开发板上的USB接口接收中星微zc301摄像头采集的视频数据。

项目分成下面几大部分进行:Linux内核定制并移植、根文件系统的制作、摄像头驱动的设计移植、服务器端软件设计以及客户端软件设计。

2.2 Linux 内核的移植

Linux操作系统具有源代码开放性、可移植性、运算的高性能性和易维护性等种种特性,因此它已经成为嵌入式开发中的首选。在所有的操作系统中,Linux是一个发展最快的、应用最为广泛的操作系统。本文选用的是linux-2.6.12这个Linux操作系统。

虽然Linux具有内核小、效率高、源代码开放和内核直接提供网络支持等优点,但嵌入式系统的硬件资源毕竟有限,因此不能直接把能在PC机上运行的Linux作为嵌入式系统中的操作系统,需要针对具体的硬件平台和要实现的特定功能,对各种功能模块进行裁剪,如一些不会用到的外设支持、驱动程序、协议、网络支持、文件格式等。Linux内核具有很好的模块性和伸缩性,在资源要求严格的情况下经过合理的裁减可获得明显的效果。因此在对Linux内核移植之前,必须先对其进行内核的裁剪。

首先,配置内核,把内核中多余的源代码屏蔽掉。Linux内核配置系统可以生成内核配置菜单,方便内核配置。配置系统主要包含Makefile、Kconfig和配置工具,可以生成配置界面。Linux内核配置命令有:make config、make menuconfig和make xconfig,分别是字符界面、ncurses光标菜单和X-window 图形窗口的配置界面。本论文选用make menuconfig界面。在各级子菜单项中,选择相应的配置时,有3种选择,它们代表的含义为:[*]—表示将该功能编译进内核,[ ]—表示不将该功能编译,[M]—表示将该功能编译成可以在需要时动态插入到内核中的模块。

执行make menuconfig命令,具体配置选择如下:

1)在Loadable module support中选择Enable loadable module support使内核支持模块动态加

载。

2)在System Type中添加对系统平台的支持。对于不同的体系结构,显示不同的提示信息。ARM体系结构显示“ARM system type”。

3)在Device Drivers中选择所需要的设备驱动程序。在Memory technology device子菜单中添加对MTD设备的支持,在Multimedia Devices子菜单中添加对摄像头的支持。

其他选项可以直接使用其缺省值,配置完成后保存退出,再通过如下步骤完成内核编译:分别是建立内核依赖关系和创建内核镜像文件。命令如下:

1)make dep,创建内核依赖关系;

由于内核源码树中的大多数文件都与一些头文件有依赖关系。因此要顺利建立内核。内核源码树中的每一个Makefile就必须知道这些依赖关系。建立依赖关系往往发生在第一次编译内核的时候,它会在内核源码树中每个子目录中产生一个隐藏文件“.depend”文件,这个文件中包含了当前目录下每个文件所依赖的头文件列表。

2)make zImage,生成内核镜像文件;

这里建立的为压缩的内核映像。通常在Linux中,内核映像分为压缩的内核映像和未压缩的内核映像。其中,压缩的内核映像即zImage,位于/arch/arm/boot目录,而未压缩的内核映像通常名为vmlinux,位于源码树的根目录下。到这一步就完成了内核源代码的编译,把生成的zlmgae内核映像文件,下载到目标平台的Flash中,就完成了Linux内核的移植。

2.3 Linux 根文件系统制作

由于嵌入式系统一般采用FLASH作为存储介质,内存和外存资源都需要节约使用。FLASH具有独特的物理特性,必须使用专门的嵌入式文件系统。目前FLASH支持的文件系统主要有JFFS2,YAFFS2,RAMFS,CRAMFS和ROMFS等等。本系统采用的是YAFFS文件系统。

Yaffs(Yet Another Flash File System)文件系统是专门针对NAND闪存设计的嵌入式文件系统。yaffs中,文件是以固定大小的数据块进行存储的,块的大小可以是512字节、1024字节或者2048字节。这种实现依赖于它能够将一个数据块头和每个数据块关联起来。每个文件(包括目录)都有一个数据块头与之相对应,数据块头中保存了ECC(Error Correction Code)和文件系统的组织信息,用于错误检测和坏块处理。充分考虑了NAND Flash的特点,yaffs把这个数据块头存储在Flash的16字节备用空间中。当文件系统被挂载时,只须扫描存储器的备用空间就能将文件系统信息读入内存,并且驻留在内存中,不仅加快了文件系统的加载速度,也提高了文件的访问速度,但是增加了内存的消耗。

制作步骤如下:

1)创建一个名字为rootfs的文件夹,在其中创建如下文件夹

etc bin var dev home lib mnt proc root sbin sys tmp usr opt 共14个文件夹2)解压Busybox

3)进入源目录,修改Makefile,执行#make menuconfig 进行配置

4)配置选项大部分都是保持默认的,只需要注意选择以下这几个选项,其他的选项都不用动:Busybox Setting --->

Build Options --->

[*]Build Busybox as a static binary(no shared libs)

[*]Build with Large File Support (for accessing files > 2GB)

Installation Options --->

(./_install) Busybox installation prefix

Busybox Library Tuning --->

[*] vi-style line editing commands

[*] Fancy shell prompts

5)配置完成以后,执行make和make install

然后就会在本目录下生成_install文件夹,里面包含几个文件夹/bin/sbin

/usr linuxrc

把这些文件全部复制到刚建好的rootfs目录下,

6)在dev目录下,创建两个设备节点:

mknod console c 5 1

mknod null c 1 3

7)然后进入自己建立的etc目录

拷贝Busybox-1.16/examples/bootfloopy/etc/* 到当前目录下。包括文件:fstab init.d inittab profile

8)修改inittab文件

9)修改init.d/rcS文件

10)修改profile文件

11)使用mkyaffs2image工具,制作文件系统镜像

2.4 Linux 设备驱动移植

2.4.1 Linux设备驱动的简介

嵌入式系统启动后,Linux系统会启用MMU,系统进入特权保护模式,普通的应用程序都运行在用户态,不能直接访问外设的I/O区域。这时若要对某一硬件外设进行读写,就要通过内核调用该硬件的驱动来实现。

驱动程序的作用在于向应用程序提供访问硬件设备的接口,驱动程序屏蔽了硬件实现上的细节操作,于是应用程序可以像操作普通文件一样对硬件设备进行操作。Linux以模块的形式加载设备类型,通常是一个模块对应一个设备驱动。模块是内核的一部分,它们一般没有被编译到内核中,而是分别被编译并链接成一组目标文件,可以被用户根据不同的需要动态载入正在运行的内核,或从正在运行的内核中卸载。

在Linux操作系统下有三类主要设备文件类型:字符设备(char device)、块设备(block device)和网络设备(network device)三种。用户正是通过设备文件与硬件打交道的,每个设备文件都有其文件属性,其中c表示是字符设备,b表示是块设备。另外每个文件都有2个设备号,第一个是主设备号,标识设备对应的驱动程序,现代的Linux内核允许多个驱动程序共享主设备号;第二个是从设备号,标识使用同一个设备驱动程序的不同硬件设备。设备文件的主设备号必须与设备驱动程序在登记时申请的设备号一致,否则用户进程将无法访问驱动程序。

设备驱动程序一般完成以下的功能:

1)对设备初始化和释放。

2)把数据从内核传送到硬件和从硬件读取数据。

3)读取应用程序传送给设备文件的数据和回送应用程序请求的数据。

4)检测和处理设备出现的错误。

2.4.2 摄像头设备驱动移植

由于Linux的开源性,本论文所采用的中星微zc301摄像头的驱动可以从网上获得,进行修改编译进内核后即可使用。这极大的缩短了本课题的完成时间,也为开发降低了成本。移植摄像头驱动的具体步骤如下:

1)首先下载zc(xxx)系列驱动源码gspcav

2)在/home/linux-2.6.12/drivers/usb目录下新建media目录,将gspca.tar.gz复制到media下并解压。为了使media编译进内核,需修改linux-2.6.12/drivers/usb目录下的Kconfig、Makefile 文件。

3)为添加gspcav1-20071224编译选项,在media下新建Kconfig、Makefile 文件。

4)修改 gspcav 的 Makefile

5)编译内核编译修改后的Linux内核,主要是另外选择这几个选项:

(1)Multimedia devices --->

Video For Linux

(2)USB support --->

Support for Host-side USB

--- USB Host Controller Drivers

OHCI HCD support

(3)USB Multimedia devices

USB SPCA5XX Sunplus/Vimicro/Sonix jpeg Cameras

保存修改,进行编译,把新生成的zImage烧进开发板,重启后插上中星微芯片的摄像头,命令行出现提示信息如图2-1所示信息说明移植的摄像头驱动已经能识别设备。

图2-1提示摄像头信息

2.5 服务器端软件设计

2.5.1基于V4L的视频采集软件设计

视频采集模块负责从USB接口的摄像头中读取视频流数据,读出的图像数据交由处理程序处理。本文使用Video4Linux接口函数访问USB摄像头设备,采用内存映射以及改进的双帧缓冲思想来实现视频的实时高速采集。

V4L(Video For Linux)是Linux环境下的一个是视频驱动标准,其目的是为上层应用提供一套统一标准的接口来访问视频设备,而这些接口的实现由驱动程序负责,因此要使得视频设备驱动能够具有对上层应用的透明性,就必须按照V4L的标准来组织代码,简而言之,视频设备驱动必须符合V4L标准。

V4L首先规定了在Linux文件系统中设备的位置和名称。在/dev目录下,名字为video0——video63的被认为是视频设备。驱动程序要实现该功能,必须在probe函数中实现对视频设备的注册。其次,V4L 规定了查询和设置设备参数的标准接口,其实是一些常量以及对应的结构体。V4L为应用程序提供了一系列的接口函数,通过这些函数,可以执行打开、读写、关闭等各种基本的操作。本文主要针对USB摄像头设备文件/dev/video0,进行视频图像采集方面的程序设计。

要实现视频采集,首先完成v41_struct数据结构的定义,如设备基本信息,图像属性,各个信号源属性等。接下来介绍文中使用到的数据结构。

struct vdIn包含设备的基本信息,如设备名称、支持的最大最小分辨率、信号源信息、信道数等。

int fd; // 设备文件描述符

char *videodevice ; // 设备,视频捕捉接口文件

struct video_mmap vmmap;

struct video_capability videocap; // 包含设备的基本信息(设备名称、支持的最大最小分辨率、信号源信息等)

int mmapsize;

struct video_mbuf videombuf; //映射的帧信息,实际是映射到摄像头存储缓冲区的帧信息,包括帧的大小(size),最多支持的帧数(frames)每帧相对基址的偏移(offset)。

struct video_picture videopict; // 采集到的图像的各种属性

struct video_window videowin; // 包含capture area的信息

struct video_channel videochan; // 各个信号源的属性

struct video_param videoparam;

int cameratype ; // 是否能capture,彩色还是黑白,是否能裁剪等等

char *cameraname; // 设备名称

char bridge[9];

int sizenative;

int sizeothers;

int palette;

int norme ;

int channel ; //信号源的个数

int grabMethod ;

unsigned char *pFramebuffer; // 指向内存映射的指针

unsigned char *ptframe[4]; // 指向压缩后的帧的指针数组

int framelock[4];

pthread_mutex_t grabmutex; // 视频采集线程和传输线程的互斥锁

int framesizeIn ; //视频帧的大小

volatile int frame_cour; // 指向压缩后的帧的指针数组下标

int bppIn; //采集的视频帧的BPP

int hdrwidth;

2.5.2视频采集软件设计流程

要完成基于V4L的USB摄像头的视频数据采集,首先需要使系统支持视频设备,即驱动的加载,然后需要获得相关的视频设备的属性信息和图像信息,并对采集窗口、颜色模式、帧状态初始化,最后才能进行视频图像的采集。

基于V4L的视频数据采集的流程如下:

1)打开视频设备;

2)读取设备信息;

3)更改设备当前设置;

4)进行视频采集,有两种方法:内存映射和直接从设备读取。本文采用内存映射;

5)对采集的视频进行处理;

6)关闭视频设备。

采集流程图如图2-2所示。

USB摄像头在Linux中的设备文件名为“/dev/video0”,视频采集程序的编写便是针对此设备名进行。完成视频图像采集的具体步骤如下:

1)打开视频设备

调用vd->fd = open (vd->videodevice,O_RDWR)函数。如果调用成功,返回设备文件描述符vd->fp;若打开失败则返回-1。视频设备成功打开后,就可以对设备文件进行读写操作了。

2)读取设备的基本信息

数ioctl (vd->fd, VIDIOCGCAP, &(vd->videocap))成功后可读取vd->capability各分量 , 读video_capability 中信息包括设备名称,支持最大最小分辨率,信号源信息等。

3)读取并设定图像信息

调用ioctl(vd->fd, VIDIOCGPICT, &(vd->picture));函数来读取图像的基本信息。如亮度brightness,对比度contrast,景深depth及调色板palette等。得到的信息保存在struct vdIn结构体里。在具体情况下,可以根据实际要求对图像信息进行必要的重新设置。具体方法是先给struct vdIn 结构体的成员中需要修改的变量进行重新赋值,然后ioctl(vd->fd,VIDIOCSPICT,&vd->pict)函数进行参数的重新设置,这里需要注意的是重新设置后切不可再次调用ioctl(cam_fp,VIDIOCGPICT,&vd->pict)函数,否则会恢复默认值,导致设置不成功。

4)读取并设定channel信息

调用ioctl(vd->fd,VIDIOCGCHAN,&(vd->channel))函数来读取信号源信息。如果是多通道的视频采集卡(这可以通过读取vd->capability.channels看出),就必须设定是通过哪个信道来采集视频。这可通过先给vd->channel结构体中的成员重新赋值,然后调用ioctl(vd->fd,VIDIOCSCHAN,&(vd->chan nel))函数来实现。

5)进行视频采集

完成以上设备初始化工作后,就可以进行视频图像采集了,这有两种方法:一种是read()直接读取;另外一种是mmap()内存映射。read()通过内核缓冲区来读取数据。而mmap()通过把设备文件映射到内存中,绕过了内核缓冲区。

编写完基于V4L的视频采集程序之后,就可以把它进行交叉编译下载到开发板上运行进行测试。

图2-2程序流程图

2.5.3 服务端的SOCKET设计

serv_sock = open_sock(serverport)函数通过执行socket(),bind(),listen()建立了一个TCP套接字服务

端并在指定端口上监听,等待客户端连接。setsockopt(server_handle,SOL_SOCKET,SO_REUSEADDR,&O_on, sizeof (int));是为了允许启动多个服务端。服务端一直监听等待客户端来连接,一旦有客户端connect()过来,服务端执行accept()建立连接后,就创建了发送图像数据到客户端的线程:pthread_create(&server_th, NULL, (void *)service, &new_sock)。客户端建立连接后,客户端会先将设置图像的信息发给服务端,首先读取客户端对图像的设置,把设置信息存放在message结构体里,然后是根据message里的信息对采集图像的显示属性(如亮度bright,对比度contrast等)进行设置,具体操作是通过ioctl()调用底层驱动来完成对摄像头抓拍图像的显示设置,设置完采集图像显示属性后,就开始执行发送这一帧图像给客户端的操作:先将让headerframe指向帧信息头,然后发送headerframe指向的信息头给客户端,再发送剩下的图像数据。这样就把完整的一帧图像发送给客户端,只要没有收到客户端退出的信号,以上的发送过程会循环执行,当收到客户端退出的信息后,它就退出循环,执行close_sock(sock)关闭套接字,终止线程。服务器发送图像线程终止后,只要服务进程没有退出则继续阻塞等待客户端的连接,重复上面的过程。

2.6 客户端软件设计

2.6.1客户端UI界面设计

通过QT 设计器,将所要用到的菜单、窗口进行设计实现。Qt 设计器支持一种基于工程的程序设计方法。首先创建一个工程(.pro后缀的文件),有了该工程文件就可以用利用QT提供的工具qmake 来生成makefiles用于编译链接。菜单、窗体设计被保存成XML格式的.ui文件并且被uic(用户界面编译器)转换成为C++头文件和源文件。利用QT设计器完成的菜单、窗体设计只是个界面架构。其完成的特定功能还需要编程实现。在窗体的.ui 文件中,可以通过增加新的功能函数实现其特有的功能。

主函数中,要先调用登录的界面进行验证,成功后调用主窗口

QApplication a(argc, argv);

Widget w;

logwind e;

if(e.exec()==QDialog::Accepted){

w.show();

return a.exec();}

return 0;

2.6.2 SOCKET通讯

所谓socket通常也称作"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求。socket用于描述IP地址和端口,是一个通信链的句柄。在Internet上的主机一般运行了多个服务软件,同时提供几种服务。每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务。根据连接启动的方式以及本地套接字要连接的目标,套接字之间的连接过程可以分为三个步骤:服务器监听(listen),客户端请求(connect),连接确认(connect返回值)。

服务器监听:是服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态。

客户端请求:是指由客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。(本次连接的ip固定为192.168.0.10 端口7070)连接确认:是指当服务器端套接字监听到或者说接收到客户端套接字的连接请求,它就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,连接就建立好了。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。

Server-Client模型的程序的开发原理如图2-3所示:

图2-3 Socket编程模型

服务器,使用Server_Socket监听指定的端口,端口可以随意指定(由于1024以下的端口通常属于保留端口,在一些操作系统中不可以随意使用,所以建议使用大于1024的端口),等待客户连接请求,客户连接后,会话产生;在完成会话后,关闭连接。

客户端,使用Socket对网络上某一个服务器的某一个端口发出连接请求,一旦连接成功,打开会话。客户端不需要指定打开的端口,通常临时的、动态的分配一个1024以上的端口。

Socket接口是TCP/IP网络的API,Socket接口定义了许多函数或例程,网络的Socket数据传输是一种特殊的I/O,Socket也是一种文件描述符。Socket也具有一个类似于打开文件的函数调用Socket(),该函数返回一个整型的Socket描述符,随后的连接建立、数据传输等操作都是通过该Socket实现的。

客户端Socket创建

int socket_creat()

{

struct sockaddr_in servaddr;

int client_handle;

if ((client_handle = socket (AF_INET, SOCK_STREAM, 0)) == -1)

{

qDebug("socket error");

}

qDebug("socket success");

servaddr.sin_family = AF_INET;

servaddr.sin_port = htons(7070);

servaddr.sin_addr.s_addr = inet_addr("192.168.0.10");

int res = connect(client_handle,(struct sockaddr*)&servaddr, sizeof (servaddr));

if(res == -1){

qDebug(" connect error");

//while(1);

}

qDebug(" connect success");

return client_handle;

}

整个GUI 系统只有一个GUI进程作为主进程,其他非GUI进程通过QThread在GUI进程中创建新的子进程实现相应的功能。该窗口实现类如下所示:

Mythread 头文件中

#ifndef MYTHREAD_H

#define MYTHREAD_H

#include"client.h"

#include

#include

class MyThread : public QThread

{

Q_OBJECT

public:

explicit MyThread(QObject *parent = 0);

void stop();

protected:

void run();

private:

volatile bool stopped;

signals:

void change();

public slots:

};

#endif // MYTHREAD_H

Mythread实现文件中

#include "mythread.h"

#include

#include"client.h"

Client client;

MyThread::MyThread(QObject *parent) :

QThread(parent)

{

stopped = false;

}

void MyThread::run()

{

client.read_jpg();

}

void MyThread::stop()

{

stopped = true;

}

2.6.3 图像的调取

在socket通讯时候,直接把图片写入buf指向的内存中,然后调用系统函数将图片显示出来。

QPixmap pixdata;

pixdata.loadFromData (buf,jpegsize);

ui->label_video->setPixmap(pixdata);

第3章功能与指标

3.1功能

启动服务器,服务器自动启动监控进程,启动摄像头采集数据,并等待发送到客户端,客户端先验证合法用户,通过验证后开始连接服务器,连接成功后可以接受数据,客户端中,单击开始按钮,开始接受数据,此时,监控的画面即是监控端实时传输的画面,当有关键图像出现时,可以单击拍照按钮,及时拍下图片,图片以时间为名字,存储在当前目录下的img目录中,方便之后查看。

3.2指标

响应时间:监控端,从上电开机,到开始监控,仅需30秒左右的时间;客户端,只要连接正常,单击开始后,即刻显示图像,没有延迟。

吞吐量:对客户端进行苛刻的多开,七个窗口以内,可以保证系统的稳定运行。

资源利用率:由于使用的内存操作,除去了硬盘的开销,cpu占有率也明显很低。

相关文档
最新文档