opencv+tesseract實現驗證碼識別的示例

一、需要識別的內容

需要識別的驗證碼內容如下  驗證碼下載下載地址。

二、直接調用tesseract來完成識別(識別率很差)

識別的圖片內容為:

在window系統鐘打開cmd命令窗口,執行識別命令如下:

tesseract.exe 01.png output.txt -l eng

識別結果為:519}       該識別準確率遠遠達不到預期

三、訓練數據樣本,提升識別率

1、下載10份樣本(樣本數量越多,識別率越高),然後通過jTessBoxEditor來進行樣本數據矯正(該步驟耗時較長)。

 2、打開 jTessBoxEditor,將所有的樣本數據生成一個總的tif文件(tif就是所有圖片的集合)。操作如下:

1)jTessBoxEditor->Tools->Merge TIFF

2 )全選所有的樣本文件,之後生成的tif命名為 jtbnum.font.exp0.tif

3)進行數據識別調整,如下圖:

 四、生成樣本庫字體

將所有的樣本識別內容都調整正確後(調整的參數保存在jtbnum.font.exp0.box文件鐘),我們需要將我們生成的樣本文件封裝成我們的 jtbnum.traineddata 字體庫,生成方式如下:

1)創建 font_properties 文件,內容為 font 0 0 0 0 0

2)在同級目錄創建 run.bat 文件 內容如下

rem 執行改批處理前先要目錄下創建font_properties文件  
  
echo Run Tesseract for Training..  
tesseract.exe jtbnum.font.exp0.tif jtbnum.font.exp0 nobatch box.train  
  
echo Compute the Character Set..  
unicharset_extractor.exe jtbnum.font.exp0.box  
mftraining -F font_properties -U unicharset -O jtbnum.unicharset jtbnum.font.exp0.tr  
  
echo Clustering..  
cntraining.exe jtbnum.font.exp0.tr  
  
echo Rename Files..  
 
del jtbnum.normproto
rename normproto jtbnum.normproto
 
del jtbnum.inttemp
rename inttemp jtbnum.inttemp
 
del jtbnum.pffmtable
rename pffmtable jtbnum.pffmtable
 
del jtbnum.shapetable
rename shapetable jtbnum.shapetable
  
echo Create Tessdata..  
combine_tessdata.exe jtbnum. 
 
pause

 3)雙擊執行 run.bat 文件,系統執行完成後,將會生成 jtbnum.traineddata 文件。

4)將 jtbnum.traineddata 拷貝到tesseract安裝目錄下的tessdata文件夾下。

5)測試識別率:

 識別的圖片內容為:

tesseract.exe 01.png output.txt -l jtbnum

 識別結果為:51915       識別結果已經很準確率,但是驗證碼圖片中的雜質沒有清除,導致會識別出多餘內容來。

五、通過Opencv清除圖片的多餘雜質(Java實現)

if(!hasLoad){
            System.load(opencvPath+"/build/java/x64/opencv_java440.dll");
            hasLoad = true;
        }
 
        byte [] bytes = Base64Utils.decodeFromString(base64);
        String path = savePath+"/"+System.currentTimeMillis()+".png";
        try {
            OutputStream outputStream = new FileOutputStream(new File(path));
            outputStream.write(bytes);
            outputStream.flush();
            outputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
 
        Mat image0 = Imgcodecs.imread(path);
        Mat image1 = new Mat();
        //灰度處理
        Imgproc.cvtColor(image0, image1, Imgproc.COLOR_BGR2GRAY);
        Imgproc.adaptiveThreshold(image1,image1,255,Imgproc.ADAPTIVE_THRESH_MEAN_C,Imgproc.THRESH_BINARY,11, 2);
        Core.bitwise_not(image1,image1);
        Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(2, 2), new Point(-1, -1));
        Mat temp = new Mat();
        Imgproc.erode(image1, temp, kernel);
        Imgproc.dilate(temp, temp, kernel);
        String newPath = path.substring(0,path.lastIndexOf(".")) +"_1.png";
        Imgcodecs.imwrite(newPath,temp);

圖片處理結果如下(雜質已經清除):

5)測試識別率:

 識別的圖片內容為:

tesseract.exe 01.png output.txt -l jtbnum

 識別結果為:5191       識別已經很精確

到此這篇關於opencv+tesseract實現驗證碼識別的示例的文章就介紹到這瞭,更多相關opencv tesseract 驗證碼識別內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: