0 前言
??
這兩年開始畢業(yè)設(shè)計和畢業(yè)答辯的要求和難度不斷提升,傳統(tǒng)的畢設(shè)題目缺少創(chuàng)新和亮點,往往達(dá)不到畢業(yè)答辯的要求,這兩年不斷有學(xué)弟學(xué)妹告訴學(xué)長自己做的項目系統(tǒng)達(dá)不到老師的要求。
為了大家能夠順利以及最少的精力通過畢設(shè),學(xué)長分享優(yōu)質(zhì)畢業(yè)設(shè)計項目,今天要分享的是
?? 畢業(yè)設(shè)計 stm32人臉識別快遞柜系統(tǒng)(源碼+硬件+論文)
??學(xué)長這里給一個題目綜合評分(每項滿分5分)
- 難度系數(shù):3分
- 工作量:3分
- 創(chuàng)新點:5分
?? 項目分享:見文末!文章來源地址http://www.zghlxwxcb.cn/news/detail-846181.html
實物演示效果
畢業(yè)設(shè)計 stm32人臉識別快遞柜系統(tǒng) - 單片機(jī) 嵌入式 物聯(lián)網(wǎng)
1 主要功能
系統(tǒng)軟件設(shè)計由柜門門禁系統(tǒng)程序和人臉識別系統(tǒng)程序兩部分組成。柜門門禁部分程序主要由系統(tǒng)主程序、底層驅(qū)動程序以及功能模塊子程序組成。人臉識別系統(tǒng)部分程序主要由UI界面程序、人臉檢測、人臉錄入數(shù)據(jù)庫和保存以及人臉比對等組成。
上位機(jī)設(shè)計方案
(1)錄入名字。當(dāng)有新的成員需要錄入人臉系統(tǒng)時,會給他錄入名字,作為人臉庫的文件名,且錄入成功后,人臉再次出現(xiàn)時,攝像頭錄像視頻會顯示名字,并且打開柜門門禁,如果是陌生人則不顯示名字,因為其不在人臉庫中;
(2)人臉圖象錄入。攝像頭會打開,只需拍照新成員的各個角度的人臉即可,用于快遞柜的人臉比對;
(3)保存人臉特征。錄入的人臉需要保存的人臉庫中,攝像頭拍到的人臉才能與人臉庫比對;
(4)遠(yuǎn)程服務(wù)器連接。連接才能與嵌入式模塊聯(lián)通,顯示屏模塊才能實時顯示;
(5)發(fā)送姓名信息。錄入成功可發(fā)送該人臉的名字信息;
(6)打開人臉門禁。點擊界面中的按鈕,然后系統(tǒng)便會跳出識別界面,然后打開攝像頭,啟動并運行編寫好的程序,用電腦自帶的攝像頭進(jìn)行人臉識別和檢測比對,成功則發(fā)送數(shù)據(jù)到顯示屏并打開繼電器(柜門鎖),否則顯示陌生人等信息,不打開繼電器(柜門鎖)。
2 硬件設(shè)計(原理圖)
3 核心軟件設(shè)計
主程序流程
系統(tǒng)軟硬件配置好以后,首先對系統(tǒng)進(jìn)行初始化,確定整個系統(tǒng)正常運行。打開人臉門禁,當(dāng)攝像頭檢測到人臉時,會通過WIFI上傳至上位機(jī),在上位機(jī)中再將采集到的人臉信息與本地已錄入的人臉信息進(jìn)行匹配,在信息匹配完成后再將結(jié)果通過WIFI上傳給單片機(jī),由單片機(jī)控制繼電器模擬門禁的打開和關(guān)閉。
上位機(jī)部分設(shè)計
上位機(jī)需要實現(xiàn)的功能為與下位機(jī)建立TCP連接以接收下位機(jī)上傳的人臉圖像數(shù)據(jù),再利用人臉識別技術(shù)完成識別任務(wù)。本文選用了基于Python的OpenCV開源計算機(jī)視覺庫、Dlib開源機(jī)器學(xué)習(xí)庫、Numpy開源數(shù)值計算庫、Pillow開源圖像處理庫、Pandas開源數(shù)據(jù)分析庫進(jìn)行上位機(jī)軟件程序的設(shè)計
篇幅有限,不過多復(fù)述詳細(xì)設(shè)計細(xì)節(jié),詳細(xì)的設(shè)計分享在論文中。。。
部分關(guān)鍵代碼
//#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重要參數(shù)
//_lcd_dev lcddev;
//寫寄存器函數(shù)
//regval:寄存器值
void LCD_WR_REG(u16 regval)
{
SPILCD_CS_RESET; //LCD_CS=0
SPILCD_RS_RESET;
SPI_WriteByte(SPI2,regval&0x00FF);
SPILCD_CS_SET; //LCD_CS=1
}
//寫LCD數(shù)據(jù)
//data:要寫入的值
void LCD_WR_DATA(u16 data)
{
SPILCD_CS_RESET; //LCD_CS=0
SPILCD_RS_SET;
SPI_WriteByte(SPI2,data>>8);
SPI_WriteByte(SPI2,data);
SPILCD_CS_SET; //LCD_CS=1
}
void LCD_WR_DATA8(u8 da) //寫8位數(shù)據(jù)
{
SPILCD_CS_RESET; //LCD_CS=0
SPILCD_RS_SET;
SPI_WriteByte(SPI2,da);
SPILCD_CS_SET; //LCD_CS=1
}
//寫寄存器
//LCD_Reg:寄存器地址
//LCD_RegValue:要寫入的數(shù)據(jù)
void LCD_WR_REG_DATA(u8 LCD_Reg, u16 LCD_RegValue)
{
LCD_WR_REG(LCD_Reg);
LCD_WR_DATA(LCD_RegValue);
}
//開始寫GRAM
void LCD_WriteRAM_Prepare(void)
{
LCD_WR_REG(0x2c);
}
//當(dāng)mdk -O1時間優(yōu)化時需要設(shè)置
//延時i
//設(shè)置光標(biāo)位置
//Xpos:橫坐標(biāo)
//Ypos:縱坐標(biāo)
void LCD_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);
}
/*************************************************
函數(shù)名:LCD_Set_Region
功能:設(shè)置lcd顯示區(qū)域,在此區(qū)域?qū)扅c數(shù)據(jù)自動換行
入口參數(shù):xy起點和終點
返回值:無
*************************************************/
void Lcd_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:坐標(biāo)
//POINT_COLOR:此點的顏色
void LCD_DrawPoint(u16 x,u16 y)
{
LCD_SetCursor(x,y); //設(shè)置光標(biāo)位置
LCD_WriteRAM_Prepare(); //開始寫入GRAM
LCD_WR_DATA(POINT_COLOR);
}
/*************************************************
函數(shù)名:LCD_Set_XY
功能:設(shè)置lcd顯示起始點
入口參數(shù):xy坐標(biāo)
返回值:無
*************************************************/
void Lcd_SetXY(u16 x,u16 y)
{
Lcd_SetRegion(x,y,x,y);
}
/*************************************************
函數(shù)名:LCD_DrawPoint
功能:畫一個點
入口參數(shù):無
返回值:無
*************************************************/
void Gui_DrawPoint(u16 x,u16 y,u16 Data)
{
Lcd_SetRegion(x,y,x+1,y+1);
LCD_WR_DATA(Data);
}
void Lcd_Reset(void)
{
// LCD_RST_CLR;
delay_ms(100);
// LCD_RST_SET;
delay_ms(50);
}
//初始化lcd
void LCD_Init(void)
{
Lcd_Reset();
//LCD Init For 1.44Inch LCD Panel with ST7735R.
LCD_WR_REG(0x11);//Sleep exit
delay_ms (120);
//ST7735R Frame Rate
LCD_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 inversion
LCD_WR_DATA8(0x07);
//ST7735R Power Sequence
LCD_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); //VCOM
LCD_WR_DATA8(0x0E);
LCD_WR_REG(0x36); //MX, MY, RGB mode
LCD_WR_DATA8(0xC8);
//ST7735R Gamma Sequence
LCD_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 command
LCD_WR_DATA8(0x01);
LCD_WR_REG(0xF6); //Disable ram power save mode
LCD_WR_DATA8(0x00);
LCD_WR_REG(0x3A); //65k mode
LCD_WR_DATA8(0x05);
LCD_WR_REG(0x29);//Display on
}
//清屏函數(shù)
//color:要清屏的填充色
void Lcd_Clear(u16 Color)
{
unsigned int i,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);
}
}
}
//在指定區(qū)域內(nèi)填充單個顏色
//(sx,sy),(ex,ey):填充矩形對角坐標(biāo),區(qū)域大小為:(ex-sx+1)*(ey-sy+1)
//color:要填充的顏色
void LCD_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); //設(shè)置光標(biāo)位置
LCD_WriteRAM_Prepare(); //開始寫入GRAM
for(j=0;j<xlen;j++)LCD_WR_DATA(color); //設(shè)置光標(biāo)位置
}
}
//畫線
//x1,y1:起點坐標(biāo)
//x2,y2:終點坐標(biāo)
void LCD_DrawLine(u16 x1, u16 y1, u16 x2, u16 y2)
{
u16 t;
int xerr=0,yerr=0,delta_x,delta_y,distance;
int incx,incy,uRow,uCol;
delta_x=x2-x1; //計算坐標(biāo)增量
delta_y=y2-y1;
uRow=x1;
uCol=y1;
if(delta_x>0)incx=1; //設(shè)置單步方向
else if(delta_x==0)incx=0;//垂直線
else {incx=-1;delta_x=-delta_x;}
if(delta_y>0)incy=1;
else if(delta_y==0)incy=0;//水平線
else{incy=-1;delta_y=-delta_y;}
if( delta_x>delta_y)distance=delta_x; //選取基本增量坐標(biāo)軸
else distance=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):矩形的對角坐標(biāo)
void LCD_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大小)
void showhanzi16(unsigned int x,unsigned int y,unsigned char index)
{
unsigned char i,j,k;
const unsigned char *temp=hanzi16;
temp+=index*32;
for(j=0;j<16;j++)
{
LCD_SetCursor(x,y+j);
LCD_WriteRAM_Prepare(); //開始寫入GRAM
for(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++;
}
}
}
void LCD_Fast_DrawPoint(u16 x,u16 y,u16 color){
//Lcd_SetRegion(x,y,x,y);
LCD_SetCursor(x,y); //設(shè)置光標(biāo)位置
LCD_WriteRAM_Prepare(); //開始寫入GRAM
LCD_WR_DATA(color);
}
//在指定位置顯示一個字符
//x,y:起始坐標(biāo)
//num:要顯示的字符:" "--->"~"
//size:字體大小 12/16
//mode:疊加方式(1)還是非疊加方式(0)
void LCD_ShowChar(u16 x,u16 y,u8 num,u8 size,u8 mode)
{
u8 temp,t1,t;
u16 y0=y;
u16 colortemp=POINT_COLOR;
//設(shè)置窗口
num=num-' ';//得到偏移后的值
if(!mode) //非疊加方式
{
for(t=0;t<size;t++)
{
if(size==12)temp=asc2_1206[num][t]; //調(diào)用1206字體
else temp=asc2_1608[num][t]; //調(diào)用1608字體
for(t1=0;t1<8;t1++)
{
if(temp&0x80)POINT_COLOR=colortemp;
else POINT_COLOR=BACK_COLOR;
LCD_DrawPoint(x,y);
temp<<=1;
y++;
if(y>=Y_MAX_PIXEL){POINT_COLOR=colortemp;return;}//超區(qū)域了
if((y-y0)==size)
{
y=y0;
x++;
if(x>=X_MAX_PIXEL){POINT_COLOR=colortemp;return;}//超區(qū)域了
break;
}
}
}
}else//疊加方式
{
for(t=0;t<size;t++)
{
if(size==12)temp=asc2_1206[num][t]; //調(diào)用1206字體
else temp=asc2_1608[num][t]; //調(diào)用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;}//超區(qū)域了
if((y-y0)==size)
{
y=y0;
x++;
if(x>=X_MAX_PIXEL){POINT_COLOR=colortemp;return;}//超區(qū)域了
break;
}
}
}
}
POINT_COLOR=colortemp;
}
//m^n函數(shù)
//返回值:m^n次方.
u32 LCD_Pow(u8 m,u8 n)
{
u32 result=1;
while(n--)result*=m;
return result;
}
//顯示數(shù)字,高位為0,則不顯示
//x,y :起點坐標(biāo)
//len :數(shù)字的位數(shù)
//size:字體大小
//color:顏色
//num:數(shù)值(0~4294967295);
void LCD_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;
}else enshow=1;
}
LCD_ShowChar(x+(size/2)*t,y,temp+'0',size,0);
}
}
//顯示字符串
//x,y:起點坐標(biāo)
//width,height:區(qū)域大小
//size:字體大小
//*p:字符串起始地址
void LCD_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;
volatile uint8_t now_Count=0;
void Load_Drow_Dialog(void)
{
Lcd_Clear(WHITE);//清屏
POINT_COLOR=BLUE;//設(shè)置字體為藍(lán)色
LCD_ShowString(X_MAX_PIXEL-24,0,200,16,16,"RST");//顯示清屏區(qū)域
POINT_COLOR=RED;//設(shè)置畫筆藍(lán)色
}
void xianshi(void)//顯示信息
{
Lcd_Clear(WHITE);//清屏
POINT_COLOR=BLUE;//設(shè)置字體為藍(lán)色
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 實現(xiàn)效果
實物演示效果
畢業(yè)設(shè)計 stm32人臉識別快遞柜系統(tǒng) - 單片機(jī) 嵌入式 物聯(lián)網(wǎng)
5 最后
包含內(nèi)容
配套詳細(xì)論文
文章來源:http://www.zghlxwxcb.cn/news/detail-846181.html
?? 項目分享:見文末!
到了這里,關(guān)于嵌入式畢設(shè)分享 stm32人臉識別快遞柜系統(tǒng)(源碼+硬件+論文)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!