(1)拷入程序后在屏幕上显示选择界面,点击开启后进入载入界面,载入的界面显示“智能安防监控系统”,和加载条;(2)当加载界面加载完成后,界面自动进入主界面;主界面要求功能模块显示“退出”按钮和“安防监控系统”,退出按钮是退出整个智能安防监控系统,而安防监控系统按钮则是进入监控操作界面;(3)当进入监控操作界面后,有四个功能按钮模块,分别是:开启(打开摄像头)、拍照、回显(显示已经拍的照片)、退出(退回到主界面);(4)当退出整个智能安防监控系统后,想再次使用安防监控系统时,只需在界面上点击重启系统按钮;(5)详细流程如下图2-1所示:
图2-1 流程图
1
3 详细设计
3.1 LCD显示模块首先通过open打开LCD屏幕驱动(/dev/fb0),然后通过read读取bmp图片数据。期间需要把24bmp的数据转换成32位的LCD数据,通过write将转换的32位数据写入屏幕驱动里面,之后关闭lcd和bmp。
最后将此模块封装成函数show_bmp(),以便调用。
3.2 屏幕触摸模块首先打开触摸屏的设备驱动 /dev/input/event0,然后通过read从驱动读取触摸信息,之后自己定义结构体保存触摸信息,并分析触摸信息和使用触摸屏信息。
最后将此模块封装成函数get_xy(),以便调用。
3.3 多线程控制通过pthread创建多线程,创建一条线程实时监控。
3.4 开启、关闭摄像头和拍照功能函数代码流程:
A.初始化摄像头
linuxapi_v4l2_device_init("/dev/video7")
/dev/video7:摄像头名字
ls /dev/video* //先查看具体的video设备文件
/dev/video0 /dev/video2 /dev/video4 /dev/video6
/dev/video1 /dev/video3 /dev/video5 /dev/video7
B.控制摄像头去采集数据
linuxapi_v4l2_start_capturing();
C.获取摄像头采集回来的数据画面(一帧的画面保存640*480)
typedef stuct Frame_Buffer{
char buf[1843200];//储存图像信息
int length; //图像数据的长度
}Frame_Buffer;
Frame_Buffer fram_buf;
linuxapi_v4l2_get_fream(&fram_buf);
D.显示采集回来的jpg图片画面
lcd_draw_jpg(80, 0, NULL, freambuf.buf, freambuf.length, 0);
x 起点,y起点 保存的图像数据 数据的长度
E.代码编译(获取code整个文件夹)
arm-linux-gcc *.c -o real_time_video -I ./libjpeg -L ./libjpeg -lapi_v4l2_arm -lpthread -ljpeg
F.运行失败的话
cd /lib
libapi_v4l2_arm.so //采集摄像头数据
libjpeg.so.8 //显示采集回来的jpg图片画面
3.5 主函数及控制监控操作界面代码
int camera()
{
char pathname[20];
show_bmp(0,0,800,480,"6.bmp",1);//进入监控
while(1)
{
get_xy();
if(x>640&&x<800&&y>360&&y<480) //返回主界面
{ c=1;
break;
}
if(x>640&&x<800&&y>0&&y<120) //开启摄像头
{
//创建一条线程实时监控
pthread_t pid;
pthread_create(&pid, NULL, get_real_time, NULL);
}
if(x>640&&x<800&&y>120&&y<240) //拍照
{
get_picture_flag =1;
}
if(x>640&&x<800&&y>240&&y<360) //回显
{
c=1;
sleep(1);
lcd_open();
printf(&quot;hello\n&quot;);
sprintf(pathname,&quot;/getjpg/%d.jpg&quot;,jpg--);
lcd_draw_jpg(0, 0, pathname,NULL, freambuf.length, 0);
lcd_close();
} /*回显功能*/
}}
int main(int argc,char**argv)
{ show_bmp(0,0,800,480,&quot;8.bmp&quot;,1);
while(1){
get_xy();
if(x>0&&x<250&&y>0&&y<100){
show_bmp(0,0,800,480,&quot;1.bmp&quot;,1);
show_bmp(100,400,600,20,&quot;2.bmp&quot;,1);
sleep(1);//延时函数 */
show_bmp(100,400,600,20,&quot;3.bmp&quot;,2);
while(1)
{
show_bmp(0,0,800,480,&quot;4.bmp&quot;,1); //主界面
get_xy();
if(x>640&&x<800&&y>360&&y<800) //退出安防系统
{
show_bmp(0,0,800,480,&quot;7.bmp&quot;,1);
break;
}
if(x>290&&x<510&&y>180&&y<300) //进入安防系统
{
camera();
x=0,y=0;
}}}}
return 0;}复制代码4 调试与测试
(1)在本次课设中,在编写摄像头模块时,出现了开启摄像头后点击退出但是摄像头没有关闭,始终处于开启的状态;后经过仔细排查,发现启动摄像头后就一直处于死循环,而 /* 停止摄像头*/
linux_v4l2_stop_capturing();/* 卸载摄像头*/
linux_v4l2_device_uinit();
lcd_close();
这三句代码在死循环外面一直没有执行,所以摄像头一直处于开启状态;最后我在死循环内写了一个条件,定义一个整型变量C,当按下“退出”按钮后,给C赋值1,而循环内用if 语句判断当C=1时,执行break跳出循环
(2)摄像头与主菜单循环切换:在摄像头与主菜单的切换过程中,最开始只能通过主菜单进入摄像头功能一次,当退出到主菜单再次进入时摄像头设备会不能正常显示,解决办法当从摄像头功能切换回主菜单时,卸载掉摄像头模块,之后就能正常循环工作。
(3)客户端配置:在客户端配置时,忘记配置通信端口号,导致通讯连接失败。
总 结
操作各个模块,虽然单个的使用还是相对来说比较简单的,但是要把他们全部融合在一起,还是,花大量的时间和精力,去克服其中的一些困难。
本次课程设计基于arm6818开发板和Linux环境下实现的交叉编译进行设计,编译和运行。有如下不足之处:
按键判断不够灵敏,按键有时存在误判现象;
拍照后获取的照片在后期显示会出现裂纹,需进行多次刷屏才能清晰;
视频实时传输未能完成。
可拓展点:可以在摄像头传输的功能传输上进行延展,通过云平台等网络工具,将视频数据传输到网络平台中,然后通过手机app软件进行接收,实现对房间的实时监控,还可以加上人脸识别功能,自动捕获识别,当小偷进入房间时,自动抓拍,传输到主人手机上,并提示报警等。
通过嵌入式实践让我们更加清楚的了解嵌入式的应用及其重要性,更加近距离的了解其工作过程及实现方式。此次嵌入式课设同时也培养了我们团队合作以及解决问题的能力,在以后的工作中会更好的处理问题。
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <pthread.h>
#include <strings.h>
#include <linux/input.h>
#include &quot;lcd.h&quot;
#include &quot;api_v4l2.h&quot;
#include <sys/mman.h> //头文件
int x=0,y=0;//获取到的坐标
int get_picture_flag = 0;//设置拍照变量
int uinit =0;//退出变量
int ts_x, ts_y;
FrameBuffer freambuf;
int c;
int jpg;
int show_bmp(int x0,int y0,int w,int h,char *name,int flag)//位置 大小 图片路径
{
//1.打开lcd屏幕驱动文件 open
int lcd_fd=open(&quot;/dev/fb0&quot;,O_RDWR);
if(lcd_fd<0)
{
printf(&quot;open fail\n&quot;);
return -1;
}
printf(&quot;open ok\n&quot;);
//2.申请共享内存 mmap
char *p=mmap(NULL,800*480*4 ,PROT_READ|PROT_WRITE,MAP_SHARED,lcd_fd,0);
//3读取bmp图片数据 read
int bmp_fd=open(name,O_RDWR);
if(bmp_fd<0)
{
printf(&quot;open fail\n&quot;);
return -1;
}
printf(&quot;open ok\n&quot;);
char bmp_buf[w*h*3];
bzero(bmp_buf,w*h*3);
lseek(bmp_fd,54,SEEK_SET);
int ret=read(bmp_fd,bmp_buf,w*h*3);
if(ret<0)
{
printf(&quot;read from bmp fail\n&quot;);
return -1;
}
printf(&quot;read from bmp ok\n&quot;);
//4.处理对应的颜色数据 24位bmp 转32 位 lcd 直接把转换好的数据赋值到内存里就可以了
int x;//列
int y;//行
for(x=x0;x<(w+x0);x++)
{
for(y=y0;y<(h+y0);y++)
{
p[y*800*4+x*4+0]=bmp_buf[(h-1-(y-y0))*w*3+(x-x0)*3+0]; //B
p[y*800*4+x*4+1]=bmp_buf[(h-1-(y-y0))*w*3+(x-x0)*3+1]; //G
p[y*800*4+x*4+2]=bmp_buf[(h-1-(y-y0))*w*3+(x-x0)*3+2]; //R
p[y*800*4+x*4+3]=0; //A
}
if(flag==2)
usleep(5000);
}
//5.关闭驱动文件 close
close(lcd_fd);
close(bmp_fd);
munmap(p, 800*480*4);//释放内存
}
//获取触摸屏坐标
int get_xy()
{
//1.打开触摸屏的驱动文件(/dev/input/event0) open
int ts_fd=open(&quot;/dev/input/event0&quot;,O_RDWR);
if(ts_fd<0)
{
printf(&quot;open ts fail\n&quot;);
return -1;
}
printf(&quot;open ts ok\n&quot;);
//2.从驱动文件读取触摸后的数据并保存到输入子系统 read
struct input_event xy;
while(1)
{
read(ts_fd,&xy,sizeof(xy));
//3.分析获取到的触摸数据 x y
if(xy.type==EV_ABS)
{
if(xy.code==ABS_X)
{
x=xy.value;
}
if(xy.code==ABS_Y)
{
y=xy.value;
}
/* if(xy.code==ABS_PRESSURE)
{
break;
} */
}
if(xy.type==EV_KEY)
{
if(xy.code==BTN_TOUCH&&xy.value==0)
break;
}
}
printf(&quot;x %d y %d\n&quot;,x,y);
}
void *get_real_time()
{
int fd;
static int jpg_num = 0;
char pic_name[20];
/* 打开LCD屏幕*/
lcd_open();
/* 初始化摄像头设备*/
linux_v4l2_device_init(&quot;/dev/video7&quot;);
/* 启动摄像头*/
linux_v4l2_start_capturing();
while(1)
{
// 实时监控
/* 获取摄像头数据 存放jpg文件流*/
linux_v4l2_get_fream(&freambuf);
if(get_picture_flag ==1)
{
get_picture_flag = 0;
x=0;
y=0;
//新建jpg
sprintf(pic_name,&quot;/getjpg/%d.jpg&quot;,jpg_num++);
jpg=jpg_num;
int jpg_fd=open(pic_name,O_RDWR|O_CREAT,0777);
//把获取的数据存放进去
write(jpg_fd, freambuf.buf, freambuf.length);
printf(&quot;拍照成功%d&quot;,jpg_num);
} /*拍照功能*/
/* 显示摄像头图像*/
lcd_draw_jpg(0, 0, NULL, freambuf.buf, freambuf.length, 0);
if(c==1)
{c=0;
break;
}
}
/* 停止摄像头*/
linux_v4l2_stop_capturing();
/* 卸载摄像头*/
linux_v4l2_device_uinit();
lcd_close();
}
int camera()
{
char pathname[20];
show_bmp(0,0,800,480,&quot;6.bmp&quot;,1);//进入监控
while(1)
{
get_xy();
if(x>640&&x<800&&y>360&&y<480) //返回主界面
{ c=1;
break;
}
if(x>640&&x<800&&y>0&&y<120) //开启摄像头
{
//创建一条线程实时监控
pthread_t pid;
pthread_create(&pid, NULL, get_real_time, NULL);
}
if(x>640&&x<800&&y>120&&y<240) //拍照
{
get_picture_flag =1;
}
if(x>640&&x<800&&y>240&&y<360) //回显
{
c=1;
sleep(1);
lcd_open();
printf(&quot;hello\n&quot;);
sprintf(pathname,&quot;/getjpg/%d.jpg&quot;,jpg--);
lcd_draw_jpg(0, 0, pathname,NULL, freambuf.length, 0);
lcd_close();
} /*回显功能*/
}
}
int main(int argc,char**argv)
{ show_bmp(0,0,800,480,&quot;8.bmp&quot;,1);
while(1){
get_xy();
if(x>0&&x<250&&y>0&&y<100){
show_bmp(0,0,800,480,&quot;1.bmp&quot;,1);
//sleep(1);//延时函数
show_bmp(100,400,600,20,&quot;2.bmp&quot;,1);
sleep(1);//延时函数 */
//usleep(1);//秒
show_bmp(100,400,600,20,&quot;3.bmp&quot;,2);
// show_bmp(0,0,800,480,&quot;4.bmp&quot;,1);
while(1)
{
show_bmp(0,0,800,480,&quot;4.bmp&quot;,1); //主界面
get_xy();
if(x>640&&x<800&&y>360&&y<800) //退出安防系统
{
show_bmp(0,0,800,480,&quot;7.bmp&quot;,1);
break;
}
if(x>290&&x<510&&y>180&&y<300) //进入安防系统
{
camera();
x=0,y=0;
}
}
}}
return 0;
}
复制代码
完整的Word格式文档51黑下载地址:
报告和代码.rar
(8.88 MB, 下载次数: 14)
2019-6-12 14:27 上传
点击文件名下载附件
基于arm的智能监控系统 |