日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

【毕业设计】stm32实现车牌识别系统 -物联网 嵌入式 单片机

發布時間:2024/3/26 windows 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【毕业设计】stm32实现车牌识别系统 -物联网 嵌入式 单片机 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 0 前言
  • 1 簡介
  • 2 主要器件
  • 3 實現效果
  • 4 設計原理
    • 4.1 **軟件總體過程:**
    • 4.2 具體解釋
  • 5 部分核心代碼
  • 6 最后


0 前言

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

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

🚩 基于stm32的實現車牌識別系統

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

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

🧿 選題指導, 項目分享:

https://gitee.com/dancheng-senior/project-sharing-1/blob/master/%E6%AF%95%E8%AE%BE%E6%8C%87%E5%AF%BC/README.md


1 簡介

本系統利用STM32單片機驅動攝像頭采集圖像,通過模式識別,匹配車牌的識別結果,并在屏幕上顯示。

2 主要器件

  • STM32F103RCT6 主控芯片
  • TFT液晶屏
  • OV7670攝像頭
  • 蜂鳴器
  • LED電路

3 實現效果

識別效果
攝像頭模塊

4 設計原理

4.1 軟件總體過程:

(1)OV7670帶FIFO攝像頭圖像采集,采用GPIO模擬攝像頭時序,通過讀取FIFO輸出值將圖像直接顯示在LCD屏上
(2)LCD屏相當于一個圖像緩存,同時也做顯示,通過讀取LCD屏上的像素值進行圖像處理;
(3)車牌定位處理,車牌定位常用二值化分割,腐蝕膨脹處理,連通域計算等操作,顯然這些算法在stm32f1上實現是很困難的,且處理速度太慢,因此,采用RGB轉HSV顏色空間變換和閾值選擇進行車牌定位,然后將車牌定位區域進行二值化處理,不是藍色車牌的部分就是字符區域;
(4)車牌字符分割處理,字符分割先采用行統計加列統計的方式,確定每行和每列的有效像素和,進一步確定字符區域;然后進行橫向統計分割,通過每一列的像素和閾值判斷字符的分界線和個數;
(5)車牌歸一化處理,歸一化處理先將每個字符提取出來,然后按照像素值進行橫向和縱向壓縮,最終處理成模板一樣大小的字符;并在液晶屏上保存字符的數據;
(6)模板匹配,將歸一化之后的字符,與模板中的字符通過像素值一一比較,確定相似度最高的字符就是目標值;

4.2 具體解釋

圖像采集
通過OV7670攝像頭進行圖像采集,采集的圖像大小為320*240像素,像素格式為RGB565。每個像素由兩字節組成,第一字節的高五位是Red,第一字節的低三位和第二字節的高三位組成Green,第二字節的低五位是Blue。

二值化
二值化就是讓圖像的像素點矩陣中的每個像素點的灰度值為0(黑色)或者255(白色),讓整個圖片呈現出只有黑色和白色的效果。二值化后的圖像中灰度值范圍是0或者255。這時需要設定一個閾值來對像素點進行設置。

常用二值化方法:

  • 取中值:設置閾值為127,灰度值小于127的為0,大于127的為255。這樣設置計算量小,計算快。缺點也嚴重:在不同的圖像中,顏色分布差別大,處理效果也不會很好。程序開始之前設置R,G,B的閾值,通過閾值判斷將像素設置為全黑(0x0000)或者全白(0xFFFF).同時根據色彩的變化記錄每一行的顏色跳變點,由此識別出車牌區域。
  • 取平均值:像素點平均值 = (像素點1灰度值 + 像素點2灰度值 + …… + 像素點n灰度值) / n
  • 雙峰法:此方法適用于具有明顯雙峰直方圖的圖像,不適合直方圖中雙峰差別很大或雙峰間的谷比較寬廣而平坦的圖像。該方法認為圖像由前景和背景組成,在灰度直方圖上,前景和背景會形成高峰,在雙峰之間的最低谷處就是閾值。
  • 識別車牌區域
    根據上一步的二值化,由于車牌區域跳變點多,由此可以得出車牌區域。分別記錄車牌區域的上下高度。然后通過RGB-HSV顏色轉換,識別出車牌區域的左右邊界。

    字符分割
    我國常見車牌以及排列順序大部分都是按照如下設計的:漢字、英文字母、點、英文字母、阿拉伯數字、阿拉伯數字、阿拉伯數字、阿拉伯數字?;谶@個規律,以及圖像采集高度一致,設計了如下的分割方法:

  • 在內存中開辟七個長為車牌長的七分之一和寬為車牌寬的區域
  • 從車牌圖像長邊的巾問向下開始掃描車牌圖像,并把掃描到的所有的點灰度值復制到0區域的第四個區域對應位置上。然后再從上向下掃描剛掃描過這一努的左邊或右邊,直到所掃描的這一峰上的所有點的灰度都是0時為止,并把這一豎認為是字符的分離處。
  • 切割第五到第七個字符。方法就是,切割完了第四個字符之后,再依次掃描剩下的空間,直到所掃描的這一豎上的所有點的灰度值不全為0時,認為是字符的開始并依次掃描直到所掃描的這一豎上的所有點的灰度值全為0時認為是字符的結束。
  • 切割第三到第四個字符。這兩個字符的切割方式與第五到第七個字符一樣。
  • 切割第一到第二個字符。當第三個字符切割完之后,我們將遇到一個點,我們也把它看作一個字符,只不過這個點掃描之后就不要了。掃描完這個點之后,我們來切割第二個字符,它的切割方式與前面一樣。切割完了第二個字符之后,再向左掃描,直到所掃描的這一豎上的所有點的灰度值不全為0時,認為是字符的開始,并依次掃描直到所掃描所有剩下的,并填到相應的位置,直到剩下的空間填滿。經過粗分割后,可以得到一些單個字符區域和多余的空間。下一步我們將把這些多余的空間去掉。這將更有利于下一步字符的識別。
  • 去除圖像上多余空間:車牌上的字符經過了粗切割所得到的是一些單的字符,但在分配空間時是按照車牌的寬和長的七分之一來分配的;所以這個空間可能大于字符應該占的空問。所以,要將多余空間去除。對于第一個字符從第一行開始向下掃描,把那些一行中所有的點的灰度值全為0的點去掉,直到掃描到有一行不全為0時為止。然后再從第一列開始向右掃描把那些一列中所有的點的灰度值全為0的點去掉,直到掃描到有一列不全為0時為止。接下來從最后一行開始向上掃描,把那些一行中所有的點的灰度值全為0的點去掉,直到掃描到有一行不全為0時為止。最后從最后一列開始向左掃描把那些一列中所有的點的灰度值全為0的點去掉,直到掃描到有一列不全為0時為止。重復上面的步驟完成剩下字符的切割。
  • 根據二值化的結果,以及記錄的跳變點位置,對字符進行分割,同時記錄字符的左右邊界。
  • 字符匹配
    對分割出來的字符進行歸一化處理,這里用到圖片的擴大算法,擴大之后逐一的去進行字符匹配。字符模板事前通過字模軟件轉換成二進制數據保存在數組中。最后根據匹配結果相似度最大的做為輸出結果。
    歸一化圖像就是要把原來各不相同的字符統一到同一尺寸。因為掃描進來的圖像中字符大小存在較大的差異,而相對來說,統一尺寸的字符識別的標準性更強,準確率自然也更高。具體算法如下:先得到原來字符的高度和寬度,與系統已存字模的數據作比較,得出要變換的系數,然后根據得到的系數按照插值的方法映射到原圖像中。

    5 部分核心代碼

    #define COLOR_RGB565_TO_R8(pixel) \ ({ \ __typeof__ (pixel) __pixel = (pixel); \ __pixel = (__pixel >> 8) & 0xF8; \ __pixel | (__pixel >> 5); \ })#define COLOR_RGB565_TO_G8(pixel) \ ({ \__typeof__ (pixel) __pixel = (pixel); \__pixel = (__pixel >> 3) & 0xFC; \__pixel | (__pixel >> 6); \ }) #define COLOR_RGB565_TO_B8(pixel) \ ({ \__typeof__ (pixel) __pixel = (pixel); \__pixel = (__pixel << 3) & 0xF8; \__pixel | (__pixel >> 5); \}) int8_t imlib_rgb565_to_l(uint16_t pixel) { float r_lin = xyz_table[COLOR_RGB565_TO_R8(pixel)]; float g_lin = xyz_table[COLOR_RGB565_TO_G8(pixel)]; float b_lin = xyz_table[COLOR_RGB565_TO_B8(pixel)];float y = ((r_lin * 0.2126f) + (g_lin * 0.7152f) + (b_lin * 0.0722f)) * (1.0f / 100.000f);y = (y>0.008856f) ? fast_cbrtf(y) : ((y * 7.787037f) + 0.137931f); return fast_floorf(116 * y) - 16; }int8_t imlib_rgb565_to_a(uint16_t pixel) { float r_lin = xyz_table[COLOR_RGB565_TO_R8(pixel)]; float g_lin = xyz_table[COLOR_RGB565_TO_G8(pixel)]; float b_lin = xyz_table[COLOR_RGB565_TO_B8(pixel)];float x = ((r_lin * 0.4124f) + (g_lin * 0.3576f) + (b_lin * 0.1805f)) * (1.0f / 095.047f); float y = ((r_lin * 0.2126f) + (g_lin * 0.7152f) + (b_lin * 0.0722f)) * (1.0f / 100.000f);x = (x>0.008856f) ? fast_cbrtf(x) : ((x * 7.787037f) + 0.137931f); y = (y>0.008856f) ? fast_cbrtf(y) : ((y * 7.787037f) + 0.137931f); return fast_floorf(500 * (x-y)); }int8_t imlib_rgb565_to_b(uint16_t pixel) { float r_lin = xyz_table[COLOR_RGB565_TO_R8(pixel)]; float g_lin = xyz_table[COLOR_RGB565_TO_G8(pixel)]; float b_lin = xyz_table[COLOR_RGB565_TO_B8(pixel)]; float y = ((r_lin * 0.2126f) + (g_lin * 0.7152f) + (b_lin * 0.0722f)) * (1.0f / 100.000f); float z = ((r_lin * 0.0193f) + (g_lin * 0.1192f) + (b_lin * 0.9505f)) * (1.0f / 108.883f); y = (y>0.008856f) ? fast_cbrtf(y) : ((y * 7.787037f) + 0.137931f); z = (z>0.008856f) ? fast_cbrtf(z) : ((z * 7.787037f) + 0.137931f); return fast_floorf(200 * (y-z)); } unsigned short xrIntFloat_16=(Src_width<<8)/Dst_width+1; //擴大倍數 unsigned short yrIntFloat_16=(Src_height<<8)/Dst_height+1; unsigned char* pDstLine=Dst_y8; unsigned short srcy_16=0; for (y=0;y<Dst_height;++y) { unsigned char* pSrcLine=((unsigned char*)((unsigned char*)Src_y8+Src_width*(srcy_16>>8))); unsigned short srcx_16=0; for (x=0;x<Dst_width;++x) { pDstLine[x]=pSrcLine[srcx_16>>8]; srcx_16+=xrIntFloat_16; } srcy_16+=yrIntFloat_16; pDstLine+=Dst_width; } }

    模板匹配算法

    /** * @function 歐幾里得距離計算,用于圖片相似度計算 * @param[in] src1和src2,必須是相同大小灰度圖片 * @param[out] 歐幾里得距離 * @retval ERROR -1 錯誤 * @par 2021年5月28日 zhengmf */ float Euclidean_Distance(unsigned char *Src1,unsigned char *Src2,int length,float Euclideandis) {if(Src1==NULL||Src2==NULL){return -1;}int sum=0;int i=0;for(i=0;i<length;i++){sum+=(int)pow((*Src1-*Src2),2);Src1++;Src2++;}Euclideandis=(float)sqrt(sum);return Euclideandis; }/** * @function 余弦相似度計算,用于圖片相似度計算 * @param[in] src1和src2,必須是相同大小灰度圖片 * @param[out] 余弦相似度 * @retval 0 相似度小于0 * @retval ERROR -1 錯誤 * @retval CosineSimilar * @par 2021年5月28日 zhengmf */ float Cosine_Similarity(unsigned char *Src1,unsigned char *Src2,int length,float CosineSimilar) {if(Src1==NULL||Src2==NULL){return -1;}int sum=0,sum1=0,sum2=0;float temp0=0,temp1=0;int i=0;for(i=0;i<length;i++){sum+=(int)(*Src1)*(*Src2);sum1+=(int)pow((*Src1),2);sum2+=(int)pow((*Src2),2);Src1++;Src2++;}if(sum<=0){return 0;}temp0=(float)(sqrt(sum1));temp1=(float)(sqrt(sum2));CosineSimilar=(float)((sum/temp0)/temp1);return CosineSimilar; }/** * @function 皮爾遜相似度計算,用于圖片相似度計算 * @param[in] src1和src2,必須是相同大小灰度圖片 * @param[out] 皮爾遜相似度 * @retval ERROR -1 錯誤 * @par 2021年5月28日 zhengmf */ float Pearson_Correlation(unsigned char *Src1,unsigned char *Src2,int length,float PearsonSimilar) {if(Src1==NULL||Src2==NULL){return -1;}unsigned char aver1=0,aver2=0;int sum=0,sum1=0,sum2=0;float temp0=0,temp1=0;int i=0;for(i=0;i<length;i++){sum1+=*Src1;sum2+=*Src2;Src1++;Src2++;}aver1=(unsigned char)(sum1/length);aver2=(unsigned char)(sum2/length);sum1=0;sum2=0;for(i=0;i<length;i++){sum+=(int)(*Src1-aver1)*(*Src2-aver2);sum1+=(int)pow((*Src1-aver1),2);sum2+=(int)pow((*Src2-aver2),2);Src1++;Src2++;}if(sum<=0){return 0;}temp0=(float)(sqrt(sum1));temp1=(float)(sqrt(sum2));PearsonSimilar=(float)((sum/temp0)/temp1); return PearsonSimilar; }

    6 最后

    總結

    以上是生活随笔為你收集整理的【毕业设计】stm32实现车牌识别系统 -物联网 嵌入式 单片机的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。