文章目录
- 0 前言
- 1 主要功能
- 2 硬件设计(原理图)
- 3 核心软件设计
- 4 实现效果
- 5 最后
0 前言
🔥
这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。
为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天要分享的是
🚩毕业设计 stm32人脸识别快递柜系统(源码+硬件+论文)
🥇学长这里给一个题目综合评分(每项满分5分)
- 难度系数:3分
- 工作量:3分
- 创新点:5分
🧿项目分享:见文末!
实物演示效果
毕业设计 stm32人脸识别快递柜系统 - 单片机 嵌入式 物联网
1 主要功能
系统软件设计由柜门门禁系统程序和人脸识别系统程序两部分组成。柜门门禁部分程序主要由系统主程序、底层驱动程序以及功能模块子程序组成。人脸识别系统部分程序主要由UI界面程序、人脸检测、人脸录入数据库和保存以及人脸比对等组成。
上位机设计方案
(1)录入名字。当有新的成员需要录入人脸系统时,会给他录入名字,作为人脸库的文件名,且录入成功后,人脸再次出现时,摄像头录像视频会显示名字,并且打开柜门门禁,如果是陌生人则不显示名字,因为其不在人脸库中;
(2)人脸图象录入。摄像头会打开,只需拍照新成员的各个角度的人脸即可,用于快递柜的人脸比对;
(3)保存人脸特征。录入的人脸需要保存的人脸库中,摄像头拍到的人脸才能与人脸库比对;
(4)远程服务器连接。连接才能与嵌入式模块联通,显示屏模块才能实时显示;
(5)发送姓名信息。录入成功可发送该人脸的名字信息;
(6)打开人脸门禁。点击界面中的按钮,然后系统便会跳出识别界面,然后打开摄像头,启动并运行编写好的程序,用电脑自带的摄像头进行人脸识别和检测比对,成功则发送数据到显示屏并打开继电器(柜门锁),否则显示陌生人等信息,不打开继电器(柜门锁)。
2 硬件设计(原理图)
3 核心软件设计
主程序流程
系统软硬件配置好以后,首先对系统进行初始化,确定整个系统正常运行。打开人脸门禁,当摄像头检测到人脸时,会通过WIFI上传至上位机,在上位机中再将采集到的人脸信息与本地已录入的人脸信息进行匹配,在信息匹配完成后再将结果通过WIFI上传给单片机,由单片机控制继电器模拟门禁的打开和关闭。
上位机部分设计
上位机需要实现的功能为与下位机建立TCP连接以接收下位机上传的人脸图像数据,再利用人脸识别技术完成识别任务。本文选用了基于Python的OpenCV开源计算机视觉库、Dlib开源机器学习库、Numpy开源数值计算库、Pillow开源图像处理库、Pandas开源数据分析库进行上位机软件程序的设计
篇幅有限,不过多复述详细设计细节,详细的设计分享在论文中。。。
部分关键代码
//#include "usart.h"#include"delay.h"#include"spi.h"#include"usart.h"#include"string.h"#include"includes.h"#include"led.h"#include"GUI.h"#include"Picture.h"#include"dht11.h"#include"adc.h"#include"light.h"#include"font.h"//LCD的画笔颜色和背景色u16 POINT_COLOR=0x0000;//画笔颜色u16 BACK_COLOR=0xFFFF;//背景色//管理LCD重要参数//_lcd_dev lcddev;//写寄存器函数//regval:寄存器值voidLCD_WR_REG(u16 regval){SPILCD_CS_RESET;//LCD_CS=0SPILCD_RS_RESET;SPI_WriteByte(SPI2,regval&0x00FF);SPILCD_CS_SET;//LCD_CS=1}//写LCD数据//data:要写入的值voidLCD_WR_DATA(u16 data){SPILCD_CS_RESET;//LCD_CS=0SPILCD_RS_SET;SPI_WriteByte(SPI2,data>>8);SPI_WriteByte(SPI2,data);SPILCD_CS_SET;//LCD_CS=1}voidLCD_WR_DATA8(u8 da)//写8位数据{SPILCD_CS_RESET;//LCD_CS=0SPILCD_RS_SET;SPI_WriteByte(SPI2,da);SPILCD_CS_SET;//LCD_CS=1}//写寄存器//LCD_Reg:寄存器地址//LCD_RegValue:要写入的数据voidLCD_WR_REG_DATA(u8 LCD_Reg,u16 LCD_RegValue){LCD_WR_REG(LCD_Reg);LCD_WR_DATA(LCD_RegValue);}//开始写GRAMvoidLCD_WriteRAM_Prepare(void){LCD_WR_REG(0x2c);}//当mdk -O1时间优化时需要设置//延时i//设置光标位置//Xpos:横坐标//Ypos:纵坐标voidLCD_SetCursor(u16 Xpos,u16 Ypos){LCD_WR_REG(0x2a);LCD_WR_DATA8(Xpos>>8);LCD_WR_DATA8(Xpos&0XFF);LCD_WR_REG(0x2b);LCD_WR_DATA8(Ypos>>8);LCD_WR_DATA8(Ypos&0XFF);}/************************************************* 函数名:LCD_Set_Region 功能:设置lcd显示区域,在此区域写点数据自动换行 入口参数:xy起点和终点 返回值:无 *************************************************/voidLcd_SetRegion(u16 x_start,u16 y_start,u16 x_end,u16 y_end){LCD_WR_REG(0x2a);LCD_WR_DATA8(x_start>>8);LCD_WR_DATA8(0x00FF&x_start+2);;LCD_WR_DATA8(x_end>>8);LCD_WR_DATA8(0x00FF&x_end+2);LCD_WR_REG(0x2b);LCD_WR_DATA8(y_start>>8);LCD_WR_DATA8(0x00FF&y_start+3);LCD_WR_DATA8(y_end>>8);LCD_WR_DATA8(0x00FF&y_end+3);LCD_WR_REG(0x2c);}//画点//x,y:坐标//POINT_COLOR:此点的颜色voidLCD_DrawPoint(u16 x,u16 y){LCD_SetCursor(x,y);//设置光标位置LCD_WriteRAM_Prepare();//开始写入GRAMLCD_WR_DATA(POINT_COLOR);}/************************************************* 函数名:LCD_Set_XY 功能:设置lcd显示起始点 入口参数:xy坐标 返回值:无 *************************************************/voidLcd_SetXY(u16 x,u16 y){Lcd_SetRegion(x,y,x,y);}/************************************************* 函数名:LCD_DrawPoint 功能:画一个点 入口参数:无 返回值:无 *************************************************/voidGui_DrawPoint(u16 x,u16 y,u16 Data){Lcd_SetRegion(x,y,x+1,y+1);LCD_WR_DATA(Data);}voidLcd_Reset(void){// LCD_RST_CLR;delay_ms(100);// LCD_RST_SET;delay_ms(50);}//初始化lcdvoidLCD_Init(void){Lcd_Reset();//LCD Init For 1.44Inch LCD Panel with ST7735R.LCD_WR_REG(0x11);//Sleep exitdelay_ms(120);//ST7735R Frame RateLCD_WR_REG(0xB1);LCD_WR_DATA8(0x01);LCD_WR_DATA8(0x2C);LCD_WR_DATA8(0x2D);LCD_WR_REG(0xB2);LCD_WR_DATA8(0x01);LCD_WR_DATA8(0x2C);LCD_WR_DATA8(0x2D);LCD_WR_REG(0xB3);LCD_WR_DATA8(0x01);LCD_WR_DATA8(0x2C);LCD_WR_DATA8(0x2D);LCD_WR_DATA8(0x01);LCD_WR_DATA8(0x2C);LCD_WR_DATA8(0x2D);LCD_WR_REG(0xB4);//Column inversionLCD_WR_DATA8(0x07);//ST7735R Power SequenceLCD_WR_REG(0xC0);LCD_WR_DATA8(0xA2);LCD_WR_DATA8(0x02);LCD_WR_DATA8(0x84);LCD_WR_REG(0xC1);LCD_WR_DATA8(0xC5);LCD_WR_REG(0xC2);LCD_WR_DATA8(0x0A);LCD_WR_DATA8(0x00);LCD_WR_REG(0xC3);LCD_WR_DATA8(0x8A);LCD_WR_DATA8(0x2A);LCD_WR_REG(0xC4);LCD_WR_DATA8(0x8A);LCD_WR_DATA8(0xEE);LCD_WR_REG(0xC5);//VCOMLCD_WR_DATA8(0x0E);LCD_WR_REG(0x36);//MX, MY, RGB modeLCD_WR_DATA8(0xC8);//ST7735R Gamma SequenceLCD_WR_REG(0xe0);LCD_WR_DATA8(0x0f);LCD_WR_DATA8(0x1a);LCD_WR_DATA8(0x0f);LCD_WR_DATA8(0x18);LCD_WR_DATA8(0x2f);LCD_WR_DATA8(0x28);LCD_WR_DATA8(0x20);LCD_WR_DATA8(0x22);LCD_WR_DATA8(0x1f);LCD_WR_DATA8(0x1b);LCD_WR_DATA8(0x23);LCD_WR_DATA8(0x37);LCD_WR_DATA8(0x00);LCD_WR_DATA8(0x07);LCD_WR_DATA8(0x02);LCD_WR_DATA8(0x10);LCD_WR_REG(0xe1);LCD_WR_DATA8(0x0f);LCD_WR_DATA8(0x1b);LCD_WR_DATA8(0x0f);LCD_WR_DATA8(0x17);LCD_WR_DATA8(0x33);LCD_WR_DATA8(0x2c);LCD_WR_DATA8(0x29);LCD_WR_DATA8(0x2e);LCD_WR_DATA8(0x30);LCD_WR_DATA8(0x30);LCD_WR_DATA8(0x39);LCD_WR_DATA8(0x3f);LCD_WR_DATA8(0x00);LCD_WR_DATA8(0x07);LCD_WR_DATA8(0x03);LCD_WR_DATA8(0x10);LCD_WR_REG(0x2a);LCD_WR_DATA8(0x00);LCD_WR_DATA8(0x00);LCD_WR_DATA8(0x00);LCD_WR_DATA8(0x7f);LCD_WR_REG(0x2b);LCD_WR_DATA8(0x00);LCD_WR_DATA8(0x00);LCD_WR_DATA8(0x00);LCD_WR_DATA8(0x9f);LCD_WR_REG(0xF0);//Enable test commandLCD_WR_DATA8(0x01);LCD_WR_REG(0xF6);//Disable ram power save modeLCD_WR_DATA8(0x00);LCD_WR_REG(0x3A);//65k modeLCD_WR_DATA8(0x05);LCD_WR_REG(0x29);//Display on}//清屏函数//color:要清屏的填充色voidLcd_Clear(u16 Color){unsignedinti,m;Lcd_SetRegion(0,0,X_MAX_PIXEL-1,Y_MAX_PIXEL-1);//Lcd_WriteIndex(0x2C);for(i=0;i<X_MAX_PIXEL;i++){for(m=0;m<Y_MAX_PIXEL;m++){LCD_WR_DATA(Color);}}}//在指定区域内填充单个颜色//(sx,sy),(ex,ey):填充矩形对角坐标,区域大小为:(ex-sx+1)*(ey-sy+1)//color:要填充的颜色voidLCD_Fill(u16 sx,u16 sy,u16 ex,u16 ey,u16 color){u16 i,j;u16 xlen=0;xlen=ex-sx+1;for(i=sy;i<=ey;i++){LCD_SetCursor(sx,i);//设置光标位置LCD_WriteRAM_Prepare();//开始写入GRAMfor(j=0;j<xlen;j++)LCD_WR_DATA(color);//设置光标位置}}//画线//x1,y1:起点坐标//x2,y2:终点坐标voidLCD_DrawLine(u16 x1,u16 y1,u16 x2,u16 y2){u16 t;intxerr=0,yerr=0,delta_x,delta_y,distance;intincx,incy,uRow,uCol;delta_x=x2-x1;//计算坐标增量delta_y=y2-y1;uRow=x1;uCol=y1;if(delta_x>0)incx=1;//设置单步方向elseif(delta_x==0)incx=0;//垂直线else{incx=-1;delta_x=-delta_x;}if(delta_y>0)incy=1;elseif(delta_y==0)incy=0;//水平线else{incy=-1;delta_y=-delta_y;}if(delta_x>delta_y)distance=delta_x;//选取基本增量坐标轴elsedistance=delta_y;for(t=0;t<=distance+1;t++)//画线输出{LCD_DrawPoint(uRow,uCol);//画点xerr+=delta_x;yerr+=delta_y;if(xerr>distance){xerr-=distance;uRow+=incx;}if(yerr>distance){yerr-=distance;uCol+=incy;}}}//画矩形//(x1,y1),(x2,y2):矩形的对角坐标voidLCD_DrawRectangle(u16 x1,u16 y1,u16 x2,u16 y2){LCD_DrawLine(x1,y1,x2,y1);LCD_DrawLine(x1,y1,x1,y2);LCD_DrawLine(x1,y2,x2,y2);LCD_DrawLine(x2,y1,x2,y2);}//在指定位置显示一个汉字(16*16大小)voidshowhanzi16(unsignedintx,unsignedinty,unsignedcharindex){unsignedchari,j,k;constunsignedchar*temp=hanzi16;temp+=index*32;for(j=0;j<16;j++){LCD_SetCursor(x,y+j);LCD_WriteRAM_Prepare();//开始写入GRAMfor(k=0;k<2;k++){for(i=0;i<8;i++){if((*temp&(1<<i))!=0){LCD_WR_DATA(POINT_COLOR);}else{LCD_WR_DATA(BACK_COLOR);}}temp++;}}}voidLCD_Fast_DrawPoint(u16 x,u16 y,u16 color){//Lcd_SetRegion(x,y,x,y);LCD_SetCursor(x,y);//设置光标位置LCD_WriteRAM_Prepare();//开始写入GRAMLCD_WR_DATA(color);}//在指定位置显示一个字符//x,y:起始坐标//num:要显示的字符:" "--->"~"//size:字体大小 12/16//mode:叠加方式(1)还是非叠加方式(0)voidLCD_ShowChar(u16 x,u16 y,u8 num,u8 size,u8 mode){u8 temp,t1,t;u16 y0=y;u16 colortemp=POINT_COLOR;//设置窗口num=num-' ';//得到偏移后的值if(!mode)//非叠加方式{for(t=0;t<size;t++){if(size==12)temp=asc2_1206[num][t];//调用1206字体elsetemp=asc2_1608[num][t];//调用1608字体for(t1=0;t1<8;t1++){if(temp&0x80)POINT_COLOR=colortemp;elsePOINT_COLOR=BACK_COLOR;LCD_DrawPoint(x,y);temp<<=1;y++;if(y>=Y_MAX_PIXEL){POINT_COLOR=colortemp;return;}//超区域了if((y-y0)==size){y=y0;x++;if(x>=X_MAX_PIXEL){POINT_COLOR=colortemp;return;}//超区域了break;}}}}else//叠加方式{for(t=0;t<size;t++){if(size==12)temp=asc2_1206[num][t];//调用1206字体elsetemp=asc2_1608[num][t];//调用1608字体for(t1=0;t1<8;t1++){if(temp&0x80)LCD_DrawPoint(x,y);temp<<=1;y++;if(y>=Y_MAX_PIXEL){POINT_COLOR=colortemp;return;}//超区域了if((y-y0)==size){y=y0;x++;if(x>=X_MAX_PIXEL){POINT_COLOR=colortemp;return;}//超区域了break;}}}}POINT_COLOR=colortemp;}//m^n函数//返回值:m^n次方.u32LCD_Pow(u8 m,u8 n){u32 result=1;while(n--)result*=m;returnresult;}//显示数字,高位为0,则不显示//x,y :起点坐标//len :数字的位数//size:字体大小//color:颜色//num:数值(0~4294967295);voidLCD_ShowNum(u16 x,u16 y,u32 num,u8 len,u8 size){u8 t,temp;u8 enshow=0;for(t=0;t<len;t++){temp=(num/LCD_Pow(10,len-t-1))%10;if(enshow==0&&t<(len-1)){if(temp==0){LCD_ShowChar(x+(size/2)*t,y,' ',size,0);continue;}elseenshow=1;}LCD_ShowChar(x+(size/2)*t,y,temp+'0',size,0);}}//显示字符串//x,y:起点坐标//width,height:区域大小//size:字体大小//*p:字符串起始地址voidLCD_ShowString(u16 x,u16 y,u16 width,u16 height,u8 size,u8*p){u8 x0=x;width+=x;height+=y;while((*p<='~')&&(*p>=' '))//判断是不是非法字符!{if(x>=width){x=x0;y+=size;}if(y>=height)break;//退出LCD_ShowChar(x,y,*p,size,1);x+=size/2;p++;}}char*Name_data;volatileuint8_tnow_Count=0;voidLoad_Drow_Dialog(void){Lcd_Clear(WHITE);//清屏POINT_COLOR=BLUE;//设置字体为蓝色LCD_ShowString(X_MAX_PIXEL-24,0,200,16,16,"RST");//显示清屏区域POINT_COLOR=RED;//设置画笔蓝色}voidxianshi(void)//显示信息{Lcd_Clear(WHITE);//清屏POINT_COLOR=BLUE;//设置字体为蓝色BACK_COLOR=WHITE;// LCD_ShowString(20,20,240,12,12,"q746876041");showhanzi16(5,24,13);//showhanzi16(25,24,14);//showhanzi16(45,24,15);//showhanzi16(65,24,16);//showhanzi16(85,24,17);//showhanzi16(105,24,18);//}4 实现效果
实物演示效果
毕业设计 stm32人脸识别快递柜系统 - 单片机 嵌入式 物联网
5 最后
包含内容
配套详细论文
🧿项目分享:见文末!