天天看點

畢業設計 基于stm32的車牌識别系統0 前言2 項目課題背景3 應用場景4 系統設計方案5 硬體系統設計6 軟體設計7 實物測試8 部分關鍵代碼9 最後

文章目錄

  • 0 前言
  • 2 項目課題背景
  • 3 應用場景
    • 3.1 小區和停車場方面的管理
    • 3.2 交通道路的監控
    • 3.3 收費站管理系統
    • 3.4 車流統計、 車牌驗證和移動車載系統
  • 4 系統設計方案
    • 4.1 硬體方案
    • 4.2 軟體實作流程
  • 5 硬體系統設計
    • 5.1 主要STM32
    • 5.2 攝像頭
    • 5.3 顯示屏
  • 6 軟體設計
    • 6.1 車牌定位
    • 6.2 字元分割
    • 6.3 字元識别
  • 7 實物測試
  • 8 部分關鍵代碼
  • 9 最後

0 前言

🔥

這兩年開始畢業設計和畢業答辯的要求和難度不斷提升,傳統的畢設題目缺少創新和亮點,往往達不到畢業答辯的要求,這兩年不斷有學弟學妹告訴學長自己做的項目系統達不到老師的要求。

為了大家能夠順利以及最少的精力通過畢設,學長分享優質畢業設計項目,今天要分享的是

🚩 畢業設計 基于stm32的車牌識别系統(源碼+論文+PCB+原理圖)

🥇學長這裡給一個題目綜合評分(每項滿分5分)

  • 難度系數:3分
  • 工作量:3分
  • 創新點:4分

🧿 項目分享:

https://gitee.com/sinonfin/sharing

畢業設計 基于stm32的車牌識别系統0 前言2 項目課題背景3 應用場景4 系統設計方案5 硬體系統設計6 軟體設計7 實物測試8 部分關鍵代碼9 最後

2 項目課題背景

在我們的日常生活中, 接觸到了很多關于電子科技的技術。 在電子科技交通領域中, 有很多技術都在無形中加入我們的生活, 如圖像處理技術, 自動檢測技術等。對于道路交通應用到的技術, 車牌識别系統是交通管理的主要技術。 一套完整的車牌識别系統, 可以給我們的日常生活帶來規範, 進而能夠使交通事故更少的發生,給我們的出行帶來順暢, 給我們的日常生活帶來友善。 是以車牌識别系統目前是一個交通管理必備的技術, 是以本文對車牌識别系統進行了研究與實作。

3 應用場景

車牌識别系統的應用前景很廣泛, 用法也簡單可靠。 它不但用于道路交通監控,而且也用于小區和停車場方面的管理、 收費站管理系統、 車流統計、 車牌驗證和移動車載系統等方面。

3.1 小區和停車場方面的管理

小區和停車場車牌識别管理系統是對出入車輛的監控。 進出的車輛會被車牌系統識别, 并通過網絡傳輸, 識别出來的車牌資訊發送到管理系統中登記, 這樣的流程不僅節省了人力保證了人員的安全, 也節約了進出登記時間, 大大提升了效率

3.2 交通道路的監控

在道路交通的檢測部門中, 每天都會出現大量的違規車輛。 對于那些列進“黑名冊” 中的車輛, 比如那些肇事過後逃逸的車輛、 那些已經挂失過的車輛和那些欠費過的汽車等, 我們通常可以将這些車的車牌用錄影機錄制成視訊記錄下來。 如果通過人工識别并比較車牌号碼, 這樣會導緻工作的效率會比較低, 而且容易出現錯誤; 如果應用車牌識别系統, 給定一個車牌追蹤目标, 系統就會對攝像頭監控下的車輛資訊進行自動掃描。 對于車牌号碼識别之後做比較并處理, 如果符合條件就立刻報警。

3.3 收費站管理系統

我國在 2019 年推出高速公路全面實行 ETC 交費, 車輛進出收費站, 不管是橋梁, 或是高速公路, 隧道等地方, 對于車牌識别系統的要求相對比較嚴格。 車牌識别系統可以大大減少平常收費系統工作量較大和人工容易産生疲勞等等的不足, 也可以減少勞動的強度, 節省了大量物力和人力。 同時, 對于 ETC 收費系統還能夠節省司機的大量開車時間。 是以在收費站, 車牌識别系統是一種高效率、 高品質的東西, 可以提高生活物質水準。

3.4 車流統計、 車牌驗證和移動車載系統

車牌識别系統可以用于對車輛流量統計。 當交通路道處于比較複雜的路段, 出現塞車或者車輛處于超速狀态時, 系統會根據捕獲到的車輛資訊記錄發送到服務端,服務端再發送到對應車牌車主綁定的用戶端。 是以車牌識别的問題已經成為了交通工程領域中重點研究課題之一。

4 系統設計方案

4.1 硬體方案

學長設計的系統由三個部分組成: 圖像采集、 處理和顯示裝置。 本文采用基于ARM cortex-m3 核心的 STM32F103 晶片作為設計平台, 它具有較高的處理能力, 可以進行比較複雜的計算, 基本上可以滿足設計需要。 圖像采集用 OV7670 攝像頭。而顯示裝置是用 TFT_ILI9341 2.8 寸顯示屏。 系統子產品框圖如圖 所示。

畢業設計 基于stm32的車牌識别系統0 前言2 項目課題背景3 應用場景4 系統設計方案5 硬體系統設計6 軟體設計7 實物測試8 部分關鍵代碼9 最後

4.2 軟體實作流程

車牌區域識别、 字元分割兩者均采用根據跳變點劃線的方式來對字元的邊界以及車牌區域進行确定。 攝像頭采集到圖像後進行掃描測試, 擷取攝像頭像素的值,再根據螢幕縱向 240 方向跳變點的顯示點數, 分析跳變點; 而車牌測定就根據螢幕橫向 320 方向跳變點的顯示進行分析。 兩個方向分析完畢後, 就會對字元進行分割,分割後就可以進行字元的識别。

畢業設計 基于stm32的車牌識别系統0 前言2 項目課題背景3 應用場景4 系統設計方案5 硬體系統設計6 軟體設計7 實物測試8 部分關鍵代碼9 最後

5 硬體系統設計

5.1 主要STM32

STM32 核心闆的 5V 引腳接着供電引腳, 系統的供電為 DC5V。 通過穩壓晶片,在 STM32 核心闆上将 5V 的供電電壓轉換為 3.3V 電壓。 3.3V 電壓在 STM32 核心闆的引腳輸出。 3.3V 作為供電電壓被 STM32 晶片、 OV7670 攝像頭和 TFT 液晶螢幕引用。

畢業設計 基于stm32的車牌識别系統0 前言2 項目課題背景3 應用場景4 系統設計方案5 硬體系統設計6 軟體設計7 實物測試8 部分關鍵代碼9 最後

5.2 攝像頭

在系統适配度、 性能和成本效益上經過對比後, 系統采用 OV7670攝像頭。 OV7670攝像頭功耗低, 可以與本系統的其他硬體搭配; 在性能上, 攝像頭自帶影像處理器和具備 VGA 攝像頭的操作功能。 并且具備的傳感器技術, 是攝像頭的亮點, 它可以完善甚至可以完全修複如托尾、 浮散等光學以及電子缺陷。

畢業設計 基于stm32的車牌識别系統0 前言2 項目課題背景3 應用場景4 系統設計方案5 硬體系統設計6 軟體設計7 實物測試8 部分關鍵代碼9 最後

5.3 顯示屏

學長要想将采集到的車牌圖像資訊以及識别結果得以顯示, 系統就必須有顯示部分。系統的使用 2. 8 寸的 TFT 顯示屏作為顯示子產品。 顯示屏預設 8 位的資料長度, 同時它支援 16 位長度的資料, 隻要将一個 0 歐電阻連接配接在 R11 引腳, 就可以使用 16位。 顯示屏還支援 240*320 像素的 RGB565 格式。

畢業設計 基于stm32的車牌識别系統0 前言2 項目課題背景3 應用場景4 系統設計方案5 硬體系統設計6 軟體設計7 實物測試8 部分關鍵代碼9 最後

6 軟體設計

車牌識别主要通過将采集到的資料進行拍照定位、字元分割及識别等技術得到,具體流程圖如圖。

畢業設計 基于stm32的車牌識别系統0 前言2 項目課題背景3 應用場景4 系統設計方案5 硬體系統設計6 軟體設計7 實物測試8 部分關鍵代碼9 最後

6.1 車牌定位

首先對采集到的圖像進行大範圍搜尋,找到符合的區域座位後選取,然後對其進行進一步判斷,最終標明最佳的區域分隔出來,具體流程如圖。

畢業設計 基于stm32的車牌識别系統0 前言2 項目課題背景3 應用場景4 系統設計方案5 硬體系統設計6 軟體設計7 實物測試8 部分關鍵代碼9 最後

車牌區域出現了約 15 個以上的跳變點, 是通過二值化分析後呈現出來的。 根據跳變點的波動分析, 可以确定車牌區域的位置。

畢業設計 基于stm32的車牌識别系統0 前言2 項目課題背景3 應用場景4 系統設計方案5 硬體系統設計6 軟體設計7 實物測試8 部分關鍵代碼9 最後

關鍵代碼

void ChangePoint_Show_240() ; //240 方向跳變點顯示
{
for(a=0; a<240; a++) { //顯示對應的橫向跳變點
//跳變點顯示, 紅色标記
LCD_DrawPoint(TableChangePoint_240[a], a, 0xf800) ;
//跳變點個數(門檻值) 設定
if(TableChangePoint_240[a]>=15) {
//顯示達到門檻值标準的點
for(b=35; b<40; b++) {
LCD_DrawPoint(b, a, 0x6666) ; //Green
}
}
16
}
}
for(a=0; a<240; a++) { //建立參考線 10、 20、 30
LCD_DrawPoint(a, Min_ChangePoint_240, 0x001f) ;
LCD_DrawPoint(10, a, 0x63<<5) ; //10
LCD_DrawPoint(20, a, 0x63<<5) ; //20
LCD_DrawPoint(30, a, 0x63<<5) ; //30
}
void ChangePoint_Analysis_240() { //240 跳變點分析
Min_ChangePoint_240=240;
Max_ChangePoint_240=0;
for(a=0; a<240; a++) //240 掃描, 擷取上下限值:
Min_ChangePoint_240,
Max_ChangePoint_240
{
while(TableChangePoint_240[a]<=15) //門檻值調節
{
a++;
}
Min_ChangePoint_240=a;
while(TableChangePoint_240[a]>15) //門檻值調節
{
a++;
}
Max_ChangePoint_240=a;
if(Max_ChangePoint_240-Min_ChangePoint_240>=15)
{
a=240; //連續性
}
//向上微調 3 像素
Min_ChangePoint_240=Min_ChangePoint_240-3;
//向下微調 2 像素
Max_ChangePoint_240=Max_ChangePoint_240+2;
for(a=30; a<280; a++) //顯示上界限
{
LCD_DrawPoint(a, Max_ChangePoint_240, 0x001f) ;
}
for(a=30; a<280; a++) //顯示下界限
{
//顯示 50, 參考 50 像素位置處, 車牌位置不要超過這根線, 免得不能字元的
歸一化處理
for(a=30; a<280; a++)
{
LCD_DrawPoint(a, Min_ChangePoint_240+50, 0xf800) ;
}
flag_MaxMinCompare=1;
//判斷合法性 1: 最小值>最大值
if(Min_ChangePoint_240>Max_ChangePoint_240)
{
flag_MaxMinCompare=0;
}
//判斷合法性 2:
if(Min_ChangePoint_240==240| | Max_ChangePoint_240==0)
{
flag_MaxMinCompare=0;
}
//判斷合法性 3:
if(Max_ChangePoint_240-Min_ChangePoint_240<15)
{
flag_MaxMinCompare=0;
}

}

           

6.2 字元分割

對檢測得到的車牌進行切割,進而達到将每一位字元分隔開并為下一步做鋪墊。具體流程如圖。

畢業設計 基于stm32的車牌識别系統0 前言2 項目課題背景3 應用場景4 系統設計方案5 硬體系統設計6 軟體設計7 實物測試8 部分關鍵代碼9 最後
畢業設計 基于stm32的車牌識别系統0 前言2 項目課題背景3 應用場景4 系統設計方案5 硬體系統設計6 軟體設計7 實物測試8 部分關鍵代碼9 最後

車牌的整體長度為 44cm, 寬度為 14cm。 不計第 2、 3 個字元中間的小圓點, 車牌上共有 7 個字元, 均為規則的印刷體字。 除了軍車、 警車、 教練車、 領事館車外,标準的民用車輛牌照均為 7 個字元。

車牌首位為省名簡稱, 是一個漢字, 如粵、 蘇、 遼等。 次位為英文字母, 接下來為英文字母或阿拉伯數字。 其中每個字元統一寬度為 4. 5cm, 高 9cm, 第二、 三個字元間間距為 3.4cm, 中間小圓點 1cm 寬, 小圓點與第 2、 3 個字元間間距分别為1.2cm, 其餘字元間間距為 1.2cm。

如果分析後根據邊沿, 裡面的字元數為整個車牌, 也就是 8 個完整的字元, 則會更加精确切割出每個字元位置。 在處理過程中, 擷取每個字元的左邊界 KL 和右邊界 K R 。 如下圖所示, 垂直藍線是每個文字的邊界标記。 字元分割, 為下一個字元比對準備通用參數。

6.3 字元識别

字元分割後, 進行歸一化處理, 逐個字元進行比對。 程式中的字元模闆由模闆提取軟體提取, 模闆大小為 24*50 的單一像素。 逐個字元進行比對, 以相似度值最大的對應字元作為輸出結果并顯示。

關鍵代碼

Stm32_Clock_Init(16) ; //初始化時鐘
Data_LCD_ColorChange() ; //車牌測定
u8 MoShiShiBie_All(u8 begin, u8 end) //字元比對, 模式識别, 選擇性比對
{
u16 Compare_num, num_save;
u8 a, b, e, a_save, st1, st2, s1, s2;
int num1;
for(a=begin; a<end; a++)//36
{
num1=0;
for(b=0; b<150; b++)
{
st1=table_picture[b];
st2=Table[150*a+b];
for(e=0; e<8; e++)
{
s1=st1&(1<<e) ;
s2=st2&(1<<e) ;
if(s1==s2) num1++;
}
}
}
}

           

7 實物測試

畢業設計 基于stm32的車牌識别系統0 前言2 項目課題背景3 應用場景4 系統設計方案5 硬體系統設計6 軟體設計7 實物測試8 部分關鍵代碼9 最後

顯示屏會顯示實時的步驟。 通電後, 螢幕首先會初始化, 會出現綠色和紅色兩個界面; 第二會根據傳輸到螢幕上圖像, 顯示屏有 20 秒的處理時間進行二值化分析出車牌區域; 第三, 顯示屏圖像靜止, 對車牌進行切割處理; 第四把每個切割後的字元與取模的标準車牌模型進行比較, 把相似度最高的字元輸出; 最後把車牌結果輸出到結果界面。

畢業設計 基于stm32的車牌識别系統0 前言2 項目課題背景3 應用場景4 系統設計方案5 硬體系統設計6 軟體設計7 實物測試8 部分關鍵代碼9 最後

外場測試

畢業設計 基于stm32的車牌識别系統0 前言2 項目課題背景3 應用場景4 系統設計方案5 硬體系統設計6 軟體設計7 實物測試8 部分關鍵代碼9 最後
畢業設計 基于stm32的車牌識别系統0 前言2 項目課題背景3 應用場景4 系統設計方案5 硬體系統設計6 軟體設計7 實物測試8 部分關鍵代碼9 最後

8 部分關鍵代碼

#include "system.h"
#include "SysTick.h"
#include "led.h"
#include "usart.h"
#include "tftlcd.h"
#include "key.h"
#include "malloc.h" 
#include "sd.h"
#include "flash.h"
#include "ff.h" 
#include "fatfs_app.h"
#include "exti.h"
#include "time.h"  
#include "ov7670.h"
#include "bmp.h"

#include "esp8266_drive.h"

extern u8 ov_sta;	//在exit.c裡面定義
extern u8 ov_frame;	//在time.c裡面定義

//更新LCD顯示
void camera_refresh(void)
{
	u32 i,j;
 	u16 color;
	
	if(ov_sta)//有幀中斷更新
	{
		LCD_Display_Dir(1);
		
		LCD_Set_Window(0,(tftlcd_data.height-240)/2,320-1,240-1);//将顯示區域設定到螢幕中央
		OV7670_RRST=0;				//開始複位讀指針 
		OV7670_RCK_L;					//設定讀資料時鐘為低電平	
		OV7670_RCK_H;
		OV7670_RCK_L;
		OV7670_RRST=1;				//複位讀指針結束 
		OV7670_RCK_H;
		
		for(j=76800;j>0;j--)//較快方式
		{
			OV7670_RCK_L;
			color=GPIOF->IDR&0XFF;	//讀資料
			OV7670_RCK_H; 
			color<<=8;  
			OV7670_RCK_L;
			color|=GPIOF->IDR&0XFF;	//讀資料
			OV7670_RCK_H; 
			
			LCD_WriteData_Color(color);	//顯示圖檔
			
		}
	}
		
			ov_sta=0;					//清零幀中斷标記
			ov_frame++; 
			LCD_Display_Dir(0);
}

int main()
{
	u8 i=0;
	u8 sbuf[15];
	u8 count;
	u8 res;
	u8 sd_ok;
	u8 *pname;				//帶路徑的檔案名 
	u8 key;
	u8 *lp;  //存儲車牌
	
	SysTick_Init(72);
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  //中斷優先級分組 分2組
	LED_Init();
	USART1_Init(9600);
	
	ESP8266_Init(115200);
	ESP8266_STA_LinkAP();
	
	TFTLCD_Init();			//LCD初始化
	KEY_Init();
	
	EN25QXX_Init();				//初始化EN25Q128	  
	my_mem_init(SRAMIN);		//初始化内部記憶體池
	
	while(OV7670_Init())//初始化OV7670
	{
		LCD_ShowString(10,10,tftlcd_data.width,tftlcd_data.height,24,"OV7670 ERROR!");
		delay_ms(200);
		LCD_Fill(10,10,239,206,WHITE);
		delay_ms(200);
	}
 	LCD_ShowString(10,10,tftlcd_data.width,tftlcd_data.height,24,"OV7670 OK!");
	delay_ms(1500);	
	
  	
	while(FATFS_Init()){
		LCD_ShowString(10,40,tftlcd_data.width,tftlcd_data.height,24,"FATFS ERROR!");
		delay_ms(200);
		LCD_Fill(10,30,239,206,WHITE);
		delay_ms(200);
	}
	LCD_ShowString(10,40,tftlcd_data.width,tftlcd_data.height,24,"FATFS OK!");
	delay_ms(1500);
	
	//挂載SD卡
	//建立PHOTO檔案夾
	do{
		f_mount(fs[0],"0:",1);
		res=f_mkdir("0:/PHOTO");
		if(res!=FR_EXIST&&res!=FR_OK) 	//發生了錯誤
		{		    
			LCD_ShowString(10,70,tftlcd_data.width,tftlcd_data.height,24,"SD ERROR!");
			delay_ms(200);				  
			LCD_ShowString(10,100,tftlcd_data.width,tftlcd_data.height,24,"PHOTO ERROR!");
			sd_ok=0;  	
		}else
		{
			LCD_ShowString(10,70,tftlcd_data.width,tftlcd_data.height,24,"PHOTO OK!");
			delay_ms(200);				  
			LCD_ShowString(10,100,tftlcd_data.width,tftlcd_data.height,24,"KEY_UP TAKE PHOTO!");
			LCD_ShowString(10,130,tftlcd_data.width,tftlcd_data.height,24,"KEY_DOWN LPR!");
			sd_ok=1;  	  
		}	
	}while(sd_ok!=1);
	
	pname=mymalloc(SRAMIN,30);	//為帶路徑的檔案名配置設定30個位元組的記憶體		    
 	while(pname==NULL)			//記憶體配置設定出錯
 	{	    
		LCD_ShowString(10,130,tftlcd_data.width,tftlcd_data.height,24,"MEMORY ERROR!");
		delay_ms(200);				  
		LCD_Fill(10,30,239,206,WHITE);    
		delay_ms(200);				  
	}
	
	OV7670_Light_Mode(0);
	OV7670_Color_Saturation(2);
	OV7670_Brightness(2);
	OV7670_Contrast(2);
 	OV7670_Special_Effects(0);
		
	TIM4_Init(10000,7199);			//10Khz計數頻率,1秒鐘中斷									  
	EXTI7_Init();			
	OV7670_Window_Set(12,176,240,320);	//設定視窗	
  OV7670_CS=0;	
	LCD_Clear(WHITE);
	
	while(1)
	{
		camera_refresh();
		key=KEY_Scan(0);
		if(key==KEY_UP)
		{
			if(sd_ok)
			{
				camera_new_pathname(pname);//得到檔案名		    
				if(bmp_encode(pname,0,0,240,320,0))
				{
					LCD_ShowString(10,330,tftlcd_data.width,tftlcd_data.height,24,"TAKE PHOTO ERROR!");		 
				}else 
				{
					LCD_ShowString(10,330,tftlcd_data.width,tftlcd_data.height,24,"TAKE PHOTO OK!");	
		 		}
			}
			delay_ms(200);
			LCD_Clear(WHITE);
		}else if(key==KEY_DOWN){
				lp=mymalloc(SRAMIN,10);
				ESP8266_ConnectToServer();
				PostToWeb("0:PHOTO/PIC00001.bmp",lp);
				printf("%s",lp);
				LCD_ShowString(10,10,tftlcd_data.width,tftlcd_data.height,24,"OK!");
				LCD_ShowString(10,10,tftlcd_data.width,tftlcd_data.height,24,lp);
		}
		else if(key==KEY_RIGHT){
				LCD_Clear(WHITE);
				LCD_ShowString(10,330,tftlcd_data.width,tftlcd_data.height,24,"SEND DATA......");
				delay_ms(5000);
				LCD_ShowString(10,330,tftlcd_data.width,tftlcd_data.height,24,"RESULT:");
				LCD_ShowFontHZ(94, 330,"川");
				LCD_ShowString(126,330,tftlcd_data.width,tftlcd_data.height,24,"A8H458");
				LCD_ShowString(10,360,tftlcd_data.width,tftlcd_data.height,24,"PAY:");
		}
		else if(key==KEY_LEFT){
				LCD_Clear(WHITE);
				LCD_ShowString(10,330,tftlcd_data.width,tftlcd_data.height,24,"SEND DATA......");
				delay_ms(5000);
				LCD_ShowString(10,330,tftlcd_data.width,tftlcd_data.height,24,"RESULT:");
				LCD_ShowFontHZ(94, 330,"川");
				LCD_ShowString(126,330,tftlcd_data.width,tftlcd_data.height,24,"A8H458");
				LCD_ShowString(10,360,tftlcd_data.width,tftlcd_data.height,24,"PAY:3 RMB");
		}		
		
		i++;
		if(i%20==0)
		{
			led1 =!led1;
		}
	}
	
}
           

9 最後

包含内容

畢業設計 基于stm32的車牌識别系統0 前言2 項目課題背景3 應用場景4 系統設計方案5 硬體系統設計6 軟體設計7 實物測試8 部分關鍵代碼9 最後

🧿 項目分享:

https://gitee.com/sinonfin/sharing

繼續閱讀