別實(shí)戰(zhàn):邊緣檢測(cè)定位與模板匹配字符識(shí)別)
簡(jiǎn)介這套資源是基于MATLAB實(shí)現(xiàn)的車牌識(shí)別完整源碼包主要面向計(jì)算機(jī)視覺(jué)初學(xué)者、圖像處理課程學(xué)生以及畢業(yè)設(shè)計(jì)人員。項(xiàng)目圍繞車牌識(shí)別全流程組織包含圖像灰度化與二值化、中值濾波去噪、Canny邊緣檢測(cè)、霍夫變換定位、連通域分析、垂直投影字符切割、特征提取與分類識(shí)別等關(guān)鍵代碼模塊并配有主程序main.m及形態(tài)學(xué)、傾斜校正、裁剪、投影、字符識(shí)別等獨(dú)立腳本。壓縮包共69個(gè)文件含44個(gè)bmp字符模板、14個(gè)jpg測(cè)試圖片、10個(gè)m源碼文件及1個(gè)說(shuō)明txt整體大小4.51MB目錄區(qū)分“字符模板”“測(cè)試圖片”“源代碼”等模塊便于按步驟對(duì)照學(xué)習(xí)。已有539人瀏覽學(xué)習(xí)。這套代碼覆蓋面完整讀者既可以整體運(yùn)行查看識(shí)別效果也可以分步調(diào)試?yán)斫饷總€(gè)算法的MATLAB實(shí)現(xiàn)方法還能利用模板庫(kù)自行擴(kuò)展不同省份字符。對(duì)完成課程設(shè)計(jì)或入門(mén)圖像處理與模式識(shí)別均有較強(qiáng)參考價(jià)值。1. 基于MATLAB的車牌識(shí)別識(shí)別率瓶頸在定位不在字符基于MATLAB的車牌識(shí)別聽(tīng)起來(lái)是被做爛的題目但真拿一張路邊隨手拍的照片跑一遍你會(huì)發(fā)現(xiàn)多數(shù)開(kāi)源Demo連車牌在哪都找不準(zhǔn)。我拆這個(gè)資源包時(shí)印象最深的一點(diǎn)是整個(gè)流程中定位環(huán)節(jié)占了近一半的代碼量字符識(shí)別反而是最短的一段。這套實(shí)現(xiàn)做的事情很直接——輸入一張包含車牌的普通圖像輸出車牌字符串覆蓋灰度化、邊緣檢測(cè)、形態(tài)學(xué)定位、字符分割、模板匹配一條完整鏈路。它適合正在做圖像處理課程設(shè)計(jì)、畢設(shè)選了這個(gè)方向、以及想不依賴深度學(xué)習(xí)框架快速搭一個(gè)可解釋識(shí)別基線的讀者。跑通之后你再替換成深度學(xué)習(xí)識(shí)別器前面的定位分割模塊仍能直接復(fù)用。2. 車牌定位Sobel邊緣與形態(tài)學(xué)閉運(yùn)算的雙重篩選車牌定位是整個(gè)識(shí)別流程里最值得細(xì)看的模塊因?yàn)楹罄m(xù)分割和識(shí)別的誤差基本都在這里開(kāi)始累積。一個(gè)直覺(jué)是“先把彩色圖轉(zhuǎn)成二值圖再找矩形”實(shí)際做一遍就會(huì)發(fā)現(xiàn)戶外光照、車身反光、路牌干擾都會(huì)讓簡(jiǎn)單二值化直接翻車。這里把定位分成兩層篩選先用邊緣檢測(cè)提取車牌邊框特征再用形態(tài)學(xué)閉運(yùn)算把散碎邊緣連成候選塊最后用幾何約束過(guò)濾非車牌區(qū)域。2.1 灰度化與Sobel邊緣檢測(cè)為什么不用Canny大多數(shù)輸入圖像是彩色照片。直接對(duì)彩色圖做形態(tài)學(xué)處理有兩個(gè)問(wèn)題三個(gè)顏色分量的噪聲會(huì)疊加亮度差異對(duì)結(jié)果的影響沒(méi)有灰度圖直觀。因此第一步永遠(yuǎn)是灰度化把后續(xù)所有操作的輸入維度降低。% 讀取原圖 img imread(plate_sample.jpg); % 彩色轉(zhuǎn)灰度 gray rgb2gray(img); % 水平方向的Sobel邊緣檢測(cè)靈敏度閾值0.15 bwEdge edge(gray, sobel, 0.15);三個(gè)步驟分別對(duì)應(yīng)讀取、降維、提取邊緣。這里用edge(gray, sobel, 0.15)第三個(gè)參數(shù)是靈敏度閾值值越大被判定為邊緣的像素越少值越小邊緣越密集。閾值0.15是一個(gè)經(jīng)驗(yàn)起點(diǎn)實(shí)際調(diào)試時(shí)按0.05的步長(zhǎng)從0.1掃到0.3再用可視化疊加確認(rèn)效果會(huì)比死記一個(gè)閾值可靠得多。為什么選Sobel而不是Canny車牌上下邊框的水平邊緣非常連續(xù)Sobel對(duì)水平梯度的響應(yīng)強(qiáng)、邊緣線條粗、斷裂少后續(xù)閉運(yùn)算更容易縫合Canny的滯后雙閾值對(duì)參數(shù)更敏感戶外環(huán)境下容易把車身紋理、樹(shù)葉陰影也判定成邊緣產(chǎn)生大量碎片。邊緣圖里的碎片越多閉運(yùn)算越容易把干擾區(qū)域和車牌區(qū)域合并在一起定位框隨之整體偏移。一個(gè)容易被忽略的細(xì)節(jié)是Sobel默認(rèn)提取整幅圖像所有方向的邊緣實(shí)際車牌區(qū)域主要依賴水平邊框所以也可以用fspecial自定義一個(gè)水平方向的Sobel核來(lái)實(shí)現(xiàn)定向提取。這會(huì)讓邊緣圖更干凈代價(jià)是丟失垂直邊框信息折中做法是先用默認(rèn)方向提取讓形態(tài)學(xué)閉運(yùn)算去做連接。2.2 形態(tài)學(xué)閉運(yùn)算與孔洞填充把散點(diǎn)連成候選塊邊緣圖是一堆散碎的短線段車牌區(qū)域的長(zhǎng)邊框和字符紋理被道路標(biāo)線、車身裝飾條打斷是常事。形態(tài)學(xué)閉運(yùn)算就是干這個(gè)的先膨脹再腐蝕。膨脹把相鄰邊緣點(diǎn)縫合起來(lái)腐蝕再把擴(kuò)張出去的多余毛刺收回來(lái)整體面積變化不大但內(nèi)部連通性大幅提升。% 定義矩形結(jié)構(gòu)元素寬45、高15 se strel(rectangle, [45, 15]); % 閉運(yùn)算 bwClose imclose(bwEdge, se); % 填充內(nèi)部孔洞讓車牌區(qū)域變?yōu)閷?shí)心塊 bwFill imfill(bwClose, holes);結(jié)構(gòu)元素尺寸是閉運(yùn)算的唯一參數(shù)也是定位精度最敏感的參數(shù)。寬45、高15是按常規(guī)車牌尺寸推算的車牌物理尺寸約440mm×140mm寬高比約3.1:1字符間隙在寬度縮放到約600像素時(shí)大約為15像素左右。結(jié)構(gòu)元素太窄字符之間的縫隙縫合不上車牌區(qū)域會(huì)斷成兩塊太寬路牌、車燈、車身裝飾條會(huì)被誤并為同一個(gè)連通塊。如果不確定尺寸常見(jiàn)做法是對(duì)多個(gè)尺寸各做一次閉運(yùn)算把所有候選區(qū)域都交給下一層幾何篩選去淘汰而不是在一開(kāi)始就賭一個(gè)參數(shù)。孔洞填充在閉運(yùn)算之后針對(duì)的是車牌內(nèi)部字符與字符之間的空隙。填充之后車牌區(qū)域從“空心矩形框”變成“實(shí)心矩形塊”這就是后續(xù) regionprops 能正確計(jì)算長(zhǎng)寬比的前提。如果跳過(guò)這一步計(jì)算出的區(qū)域面積會(huì)明顯小于實(shí)際車牌面積下限閾值就不好設(shè)。2.3 連通域篩選用長(zhǎng)寬比和面積過(guò)濾非車牌區(qū)域閉運(yùn)算結(jié)束后圖中通常還殘留多個(gè)連通塊。接下來(lái)用幾何屬性做第二層篩選。車牌是一個(gè)寬高比穩(wěn)定的矩形這兩個(gè)約束能排除掉大部分干擾區(qū)域。% 標(biāo)記連通域 labeled bwlabel(bwFill); % 提取每個(gè)連通域的包圍框與面積 stats regionprops(labeled, BoundingBox, Area); for k 1:numel(stats) w stats(k).BoundingBox(3); h stats(k).BoundingBox(4); ratio w / h; area stats(k).Area; % 保留寬高比2.5~5.5、面積大于2000的候選塊 if ratio 2.5 ratio 5.5 area 2000 candidate stats(k).BoundingBox; % 從原圖中裁出候選區(qū)域交給后續(xù)分割 plate_region imcrop(gray, candidate); end end寬高比范圍為什么給到2.5到5.5而不是嚴(yán)格的3.1因?yàn)檐囕v停放角度、拍攝視角都會(huì)改變車牌在畫(huà)面中的投影比例車頭正對(duì)鏡頭時(shí)接近3.1斜向拍攝時(shí)可能被壓扁到2.4側(cè)向拍攝時(shí)可能拉長(zhǎng)到4以上。范圍太窄會(huì)把傾斜拍攝的車牌過(guò)濾掉范圍太寬會(huì)混入大量長(zhǎng)條形干擾物。面積閾值2000同樣不是通用值它依賴圖像分辨率。這里建議按“字符密集程度”來(lái)輔助判斷車牌區(qū)域內(nèi)部邊緣像素密度遠(yuǎn)高于周邊可以在篩選結(jié)果里再加一條邊緣密度條件。面積篩選之后還有一個(gè)可選的第三層校驗(yàn)候選區(qū)內(nèi)部字符紋理的方差。車牌的紋理特征是字符與底色交替出現(xiàn)灰度直方圖呈現(xiàn)雙峰結(jié)構(gòu)而車身面板、路牌是平滑區(qū)塊。用std2計(jì)算候選區(qū)灰度方差能過(guò)濾掉一部分外形像車牌、內(nèi)部卻是空白的干擾物。加上這一層之后定位的誤判率通常能再降一截。3. 字符分割垂直投影與連通域校驗(yàn)少一個(gè)都翻車定位裁出的車牌區(qū)域包含一串字符字符分割的任務(wù)是把它們逐個(gè)切出來(lái)。常見(jiàn)做法是垂直投影法統(tǒng)計(jì)每一列的黑色像素?cái)?shù)量字符之間存在空隙空隙處的像素?cái)?shù)會(huì)形成波谷從這個(gè)谷底切開(kāi)。但直接套投影法在漢字車牌上必然踩坑因?yàn)闈h字內(nèi)部筆畫(huà)密集投影波谷比字母數(shù)字復(fù)雜得多。3.1 垂直投影法按列像素密度切分字符先對(duì)車牌區(qū)域做二值化再統(tǒng)計(jì)每一列中前景像素的數(shù)量。字符區(qū)內(nèi)列像素值高字符間隙處列像素值接近零投影曲線會(huì)呈現(xiàn)連續(xù)的高峰—低谷形態(tài)。波谷位置就是候選分割點(diǎn)。% 車牌區(qū)域二值化灰度大于0.6置為1 plate_bw im2bw(plate_region, 0.6); % 統(tǒng)計(jì)每一列的前景像素?cái)?shù)假設(shè)前景為黑色像素 proj sum(plate_bw 0, 1); % 找到投影值為零的列位置 zero_cols find(proj 0);這里的im2bw(plate_region, 0.6)是固定閾值二值化0.6表示灰度歸一化到0~1區(qū)間后的分割閾值。如果車牌圖像亮度均勻0.6左右效果不錯(cuò)如果光照不均固定閾值會(huì)讓部分字符區(qū)域變白、背景變黑投影曲線失真。更穩(wěn)的替代方案是graythresh自動(dòng)計(jì)算Otsu閾值或者用imtophat做頂帽變換先校正亮度不均。投影值計(jì)算中plate_bw 0表示取黑色像素這是基于“白底黑字”車牌的二值化約定。二值化方向搞反了投影曲線就會(huì)變成倒置形態(tài)這是新手最常犯的錯(cuò)誤之一。3.2 連通域分析做二次校驗(yàn)兩個(gè)經(jīng)典分割錯(cuò)誤投影法對(duì)“京”“魯”這類結(jié)構(gòu)復(fù)雜的漢字非常不友好。漢字內(nèi)部筆畫(huà)密集投影到列方向時(shí)筆畫(huà)之間常常沒(méi)有清晰的零值空隙導(dǎo)致一個(gè)漢字被誤判成兩個(gè)字符。另一種情況恰好相反數(shù)字“1”寬度窄、面積小在投影圖中呈現(xiàn)的波峰不明顯容易被當(dāng)作噪聲丟棄。% 對(duì)二值圖做連通域標(biāo)記 cc bwconncomp(plate_bw 0); stats_char regionprops(cc, BoundingBox, Area); % 按包圍框左邊界排序 boxes reshape({stats_char.BoundingBox}, [], 1); positions cellfun((b) b(1), boxes); [~, order] sort(positions); sorted_boxes boxes(order);這段代碼的作用是把二值圖中所有連通的字符塊找出來(lái)按水平位置從左到右排序再按位置和寬度依次排列成字符串順序。連通域方式天然規(guī)避了“漢字被投影切碎”的問(wèn)題——漢字筆畫(huà)雖然密集但在二維空間里仍然是連通的整體會(huì)形成一個(gè)大的連通塊。需要補(bǔ)的校驗(yàn)條件有兩個(gè)連通塊的高度要達(dá)到車牌區(qū)域高度的50%以上寬度不能小于整體寬度的5%否則判定為噪聲或邊框殘留。一個(gè)常見(jiàn)的隱藏坑是二值化后車牌邊框和字符粘連。如果車牌邊緣框沒(méi)有被完全去掉邊框會(huì)與第一個(gè)字符或最后一個(gè)字符形成一個(gè)連通塊導(dǎo)致分割結(jié)果出現(xiàn)“7個(gè)字符加上一條邊框”。解決方式是在連通域分析之前用imclearborder清除與圖像邊界相連的對(duì)象或者在投影分割前先對(duì)車牌區(qū)域做一次腐蝕操作把邊框與字符的連接點(diǎn)斷開(kāi)。3.3 尺寸歸一化分割完必須做的統(tǒng)一化處理切割出的字符寬度、高度各不相同模板匹配要求輸入尺寸一致因此每一張字符圖都要?dú)w一化到統(tǒng)一尺寸。常見(jiàn)做法是縮放到48×24像素這個(gè)尺寸能保留足夠的筆畫(huà)細(xì)節(jié)又不會(huì)讓匹配計(jì)算量過(guò)大。% 將單個(gè)字符圖像歸一化為48×24 char_norm imresize(char_img, [48, 24], bilinear); % 統(tǒng)一轉(zhuǎn)成二值圖消除灰度差異 char_bw im2bw(char_norm, 0.5);尺寸歸一化有兩個(gè)細(xì)節(jié)。第一縮放算法的選擇雙線性插值計(jì)算平滑適合字符這種筆畫(huà)型圖像最近鄰插值會(huì)保留鋸齒對(duì)筆畫(huà)細(xì)節(jié)不利。第二二值化閾值統(tǒng)一使用0.5是為了讓模板匹配階段只比較筆畫(huà)的形狀特征而不是比較灰度深淺。如果字符圖像本身是白底黑字統(tǒng)一二值化之后再送入匹配。對(duì)于含有邊框噪聲的字符塊可以在歸一化后加一步開(kāi)運(yùn)算把細(xì)小的毛刺去掉。4. 字符識(shí)別模板匹配池設(shè)計(jì)與拒識(shí)閾值怎么定字符識(shí)別這層在這套MATLAB實(shí)現(xiàn)里用的是模板匹配。模板匹配的思路非常樸素把分割出的字符與模板庫(kù)中的每一個(gè)模板做相似度計(jì)算取相似度最高者作為識(shí)別結(jié)果。樸素不代表簡(jiǎn)單模板庫(kù)怎么構(gòu)建、匹配算法怎么選、閾值怎么設(shè)直接決定識(shí)別的上限。4.1 構(gòu)建模板庫(kù)樣本來(lái)源與命名規(guī)范模板庫(kù)的質(zhì)量決定匹配識(shí)別的質(zhì)量這是整個(gè)識(shí)別模塊最容易被低估的部分。模板來(lái)源有兩個(gè)方向一是從同一拍攝設(shè)備采集的清晰車牌中手動(dòng)切割字符二是對(duì)已有的字符圖像做幾何變換生成多尺度變體。% 模板文件夾結(jié)構(gòu)示意 % templates/ % hans/ Wangzi/ shuzi/... % 讀取模板 template_dir templates/; files dir(fullfile(template_dir, *.bmp)); for i 1:numel(files) [~, name, ~] fileparts(files(i).name); template_img imread(fullfile(template_dir, files(i).name)); template_bw im2bw(template_img, 0.5); templates.(name) template_bw; end命名規(guī)范建議采用“字符名稱_編號(hào)”的格式比如“京_01.bmp”“A_03.bmp”。這樣在匹配結(jié)束后可以直接從變量字段名提取識(shí)別結(jié)果避免維護(hù)額外的映射表。每個(gè)字符的模板建議準(zhǔn)備5到10個(gè)變體樣本覆蓋不同光照、不同粗細(xì)的印刷體字形。同一個(gè)字符不同模板之間匹配分?jǐn)?shù)取最高值。4.2 漢字的特殊處理第一字符單獨(dú)匹配不混池車牌字符串的排列規(guī)則是“漢字字母數(shù)字”其中第一個(gè)字符固定為漢字。如果把漢字和字母數(shù)字混在同一個(gè)模板池里匹配寬度差異和結(jié)構(gòu)差異會(huì)造成分?jǐn)?shù)偏向識(shí)別率反而不如分組匹配。% 識(shí)別第一個(gè)字符只用漢字模板池 char1_score zeros(1, numel(han_templates)); for k 1:numel(han_templates) char1_score(k) match_score(char_bw_1, han_templates{k}); end [~, idx1] max(char1_score); char1 han_labels{idx1}; % 識(shí)別后續(xù)字符字母數(shù)字模板池 for j 2:7 % ... 同上邏輯從 alnum_templates 中選最高分 end這里的關(guān)鍵是分池匹配。第一個(gè)字符只與漢字模板比較后六個(gè)字符只與字母數(shù)字模板比較。漢字和字母數(shù)字在字形結(jié)構(gòu)上差異顯著混池匹配偶爾會(huì)出現(xiàn)“某個(gè)字母恰好比某個(gè)漢字更相似”的誤判分池后這個(gè)概率被徹底排除。漢字識(shí)別還有一個(gè)進(jìn)階技巧對(duì)候選前三名做局部區(qū)域二次比對(duì)。漢字中“魯”和“遼”、“滬”和“護(hù)”字形高度接近整體匹配分?jǐn)?shù)可能只差零點(diǎn)幾此時(shí)截取字符的右下角區(qū)域做局部匹配局部差異會(huì)被放大能有效區(qū)分相似字形。4.3 匹配分?jǐn)?shù)與拒識(shí)閾值識(shí)別不出時(shí)要敢于不認(rèn)模板匹配的輸出是一組相似度分?jǐn)?shù)但分?jǐn)?shù)本身沒(méi)有絕對(duì)意義。同一字符在不同光照條件下提取出的二值圖可能差很多導(dǎo)致最高分僅有0.5與此對(duì)應(yīng)一個(gè)噪聲塊也可能和某個(gè)模板意外相似到0.7。因此拒識(shí)閾值要按“最低可接受分?jǐn)?shù)”反推。% 將最佳匹配分?jǐn)?shù)轉(zhuǎn)為置信度并判斷閾值 best_scores zeros(1, 7); % ... 在匹配循環(huán)中填充 best_scores if best_scores(j) 0.6 result_char{j} ?; % 拒識(shí) else result_char{j} best_label; end閾值0.6是底線實(shí)際項(xiàng)目里通過(guò)一批測(cè)試集的分?jǐn)?shù)分布來(lái)標(biāo)定收集300張車牌圖片統(tǒng)計(jì)所有正確匹配的分?jǐn)?shù)取最低值向下偏移0.05作為拒識(shí)閾值。識(shí)別不出時(shí)輸出“?”不要強(qiáng)行給一個(gè)低置信的答案這樣才能保證整體識(shí)別結(jié)果的可靠度。5. 常見(jiàn)問(wèn)題排查五個(gè)翻車點(diǎn)與對(duì)應(yīng)修改方案這里整理五條拆解和調(diào)試這套MATLAB車牌識(shí)別資源時(shí)最常遇到的踩坑記錄。每一條都是現(xiàn)象、原因、解決三個(gè)層次對(duì)應(yīng)到具體代碼行和參數(shù)。5.1 定位框總是切掉車牌的一部分現(xiàn)象輸出候選框時(shí)車牌左邊或右邊被切掉分割出來(lái)的字符數(shù)量不對(duì)。原因形態(tài)學(xué)閉運(yùn)算的結(jié)構(gòu)元素尺寸偏小車牌邊緣與字符區(qū)域之間的縫隙沒(méi)有被完全縫合整個(gè)車牌被拆成多個(gè)連通塊篩選時(shí)只留下了面積最大的那一塊。解決把strel(rectangle, [45, 15])的寬度加到60甚至80重新做閉運(yùn)算和區(qū)域篩選或者對(duì)多個(gè)尺寸做閉運(yùn)算后合并候選區(qū)域。5.2 二值化之后車牌反白投影曲線全部倒置現(xiàn)象分割階段投影圖中的波峰波谷與預(yù)期完全相反字符區(qū)域的數(shù)據(jù)反而接近零。原因二值化約定方向與sum(plate_bw 0, 1)不一致原本是黑底白字的車牌轉(zhuǎn)換成了白底黑字統(tǒng)計(jì)黑色像素時(shí)統(tǒng)計(jì)到的是背景。解決先查看plate_bw中字符區(qū)域的值是多少要么把二值化取反plate_bw ~plate_bw要么把統(tǒng)計(jì)條件改為sum(plate_bw 1, 1)保證統(tǒng)計(jì)的是字符像素。5.3 分割出來(lái)只有四個(gè)字符中間的字母丟了現(xiàn)象車牌印刷清晰但分割結(jié)果缺少“·”分隔符后面的字母或數(shù)字連通域分析也沒(méi)有找到。原因字符寬度過(guò)窄被當(dāng)作噪聲過(guò)濾或者字符與邊框粘連開(kāi)運(yùn)算處理時(shí)整個(gè)字符被腐蝕掉。解決檢查連通域篩選的寬度閾值把最小寬度從5%降到3%以下對(duì)二值化后的車牌區(qū)域用imdilate輕微膨脹一次把斷裂筆畫(huà)連上再做連通域分析。5.4 漢字識(shí)別結(jié)果全錯(cuò)字母數(shù)字基本對(duì)現(xiàn)象前六個(gè)字符識(shí)別正常但第一個(gè)漢字永遠(yuǎn)不對(duì)。原因模板庫(kù)中漢字樣本與測(cè)試圖像字體差異太大或者漢字模板在歸一化時(shí)保持了原始尺寸沒(méi)有統(tǒng)一縮放到48×24。解決漢字模板統(tǒng)一用imresize(漢字, [48, 24], bilinear)做歸一化同時(shí)保證模板和分割字符使用相同的二值化閾值0.5如果字體差異確實(shí)太大補(bǔ)充該字體的模板樣本。5.5 數(shù)字8經(jīng)常被識(shí)別成3字母G和6混淆現(xiàn)象單獨(dú)跑每個(gè)字符的匹配分?jǐn)?shù)都超過(guò)0.7但結(jié)果就是錯(cuò)。原因模板匹配對(duì)筆畫(huà)粗細(xì)和閉合程度敏感字符“8”和“3”在二值化后輪廓相似尤其當(dāng)字符筆畫(huà)偏細(xì)時(shí)“8”的下半環(huán)容易被腐蝕成開(kāi)放結(jié)構(gòu)。解決在匹配前對(duì)字符做統(tǒng)一細(xì)化處理把圖像線寬歸一化到固定粗細(xì)或者改用歸一化互相關(guān)系數(shù)normxcorr2替代簡(jiǎn)單的像素差匹配減少灰度絕對(duì)差異的影響。6. 腳本化批量驗(yàn)證把識(shí)別率從“玄學(xué)”變成可統(tǒng)計(jì)單張圖片跑出結(jié)果只能叫“能運(yùn)行”不能叫“可用”。我一般會(huì)把識(shí)別流程封裝成一個(gè)函數(shù)再寫(xiě)一個(gè)批量腳本跑整個(gè)測(cè)試集用統(tǒng)計(jì)數(shù)字判斷識(shí)別率到底是多少。封裝函數(shù)的意義在于所有參數(shù)集中管理調(diào)參只改一處不用每次打開(kāi)主腳本翻半天。function result plate_recognition(imgPath) % 統(tǒng)一封裝輸入圖像路徑輸出識(shí)別結(jié)果 % result.success: 是否識(shí)別成功(1/0) % result.plate: 識(shí)別出的車牌字符串 % result.confidence: 7個(gè)字符置信度的均值 img imread(imgPath); % ... 定位、分割、識(shí)別流程返回 result end批量驗(yàn)證腳本遍歷測(cè)試集目錄對(duì)每張圖調(diào)用函數(shù)并把每張圖的識(shí)別結(jié)果、置信度、是否成功寫(xiě)入表格。這里刻意保留成功和失敗樣本的完整記錄不能只統(tǒng)計(jì)成功率數(shù)字不然永遠(yuǎn)不知道失敗樣本長(zhǎng)什么樣。files dir(testset/*.jpg); results table(); for i 1:numel(files) [~, name, ~] fileparts(files(i).name); r plate_recognition(fullfile(files(i).folder, files(i).name)); results [results; {name, r.plate, r.success, r.confidence}]; end % 統(tǒng)計(jì)整體成功率 success_rate sum(results.Var3) / height(results); disp([識(shí)別成功率: , num2str(success_rate)]);跑完一輪之后我會(huì)把所有失敗樣本的關(guān)鍵參數(shù)記錄成一致性表格是哪一步失敗的定位、分割、識(shí)別、該步當(dāng)時(shí)的閾值參數(shù)、失敗原因描述。參數(shù)自檢的價(jià)值在這個(gè)環(huán)節(jié)才真正體現(xiàn)出來(lái)——如果三張失敗圖都是定位階段被長(zhǎng)寬比篩掉的那就是寬高比范圍的問(wèn)題如果都是識(shí)別置信度低那就是模板庫(kù)覆蓋不足。從那以后我每次拿到一組新測(cè)試集都會(huì)強(qiáng)制自己走一遍這張自檢表再談識(shí)別率。希望幫到你。本文還有配套的精品資源點(diǎn)擊獲取