圖片識(shí)別
Caffe,全稱Convolutional Architecture for Fast Feature Embedding,是一個(gè)計(jì)算CNN相關(guān)算法的框架。
Docker
Docker 是一個(gè)開源的應(yīng)用容器引擎,讓開發(fā)者可以打包他們的應(yīng)用以及依賴包到一個(gè)可移植的容器中,然后發(fā)布到任何流行的linux機(jī)器上,也可實(shí)現(xiàn)虛擬化。容器是完全使用沙箱機(jī)制,相互之間不會(huì)有任何接口。
AWS
AWS BPM業(yè)務(wù)流程管理開發(fā)平臺(tái)是一個(gè)易于部署和使用的業(yè)務(wù)流程管理基礎(chǔ)平臺(tái)軟件,AWS平臺(tái)提供了從業(yè)務(wù)流程梳理、建模到運(yùn)行、監(jiān)控、優(yōu)化的全周期管理和面向角色的BPM Total Solution。
OpenCV
它輕量級(jí)而且高效——由一系列 C 函數(shù)和少量 C++ 類構(gòu)成,同時(shí)提供了Python、Ruby、MATLAB等語言的接口,實(shí)現(xiàn)了圖像處理和計(jì)算機(jī)視覺方面的很多通用算法。 OpenCV用C++語言編寫,它的主要接口也是C++語言,但是依然保留了大量的C語言接口。該庫(kù)也有大量的Python, Java and MATLAB/OCTAVE (版本2.5)的接口。
OpenCV自帶例子中,提供了boost,mlp,knearest,nbayes,svm,rtrees這些機(jī)器學(xué)習(xí)方法,進(jìn)行訓(xùn)練和識(shí)別。
處理的步驟和方式都類似。這些例子的識(shí)別率不是很高,OCR識(shí)別率在90%以上才有較好的使用意義,所以,OCR還需要更多特征和分析方法,來提高識(shí)別率,tesseract是一個(gè)不錯(cuò)的開源OCR引擎。
數(shù)字識(shí)別的步驟
ROI抽取、訓(xùn)練、識(shí)別
1.ROI抽取即將感興趣的區(qū)域從原始圖像中分離,該步驟包括二值化,噪點(diǎn)的消除等。直接將整個(gè)圖像作為特征數(shù)據(jù)維度太高,計(jì)算量太大,可進(jìn)行降維處理,拿到字符的ROI圖像,二值化。將圖像分塊,然后統(tǒng)計(jì)每個(gè)小塊中非0像素的個(gè)數(shù),這樣形成了一個(gè)較小的矩陣,這矩陣就是新的特征。
灰度圖
2.訓(xùn)練
3.識(shí)別即通過一些分類器將第一步中的結(jié)果進(jìn)行分類,事實(shí)上屬于機(jī)器學(xué)習(xí)的一個(gè)典型應(yīng)用
訓(xùn)練和識(shí)別一般采用同一種方法,目前普遍使用KNN、SVM。
數(shù)據(jù)之美:在自然語言與機(jī)器翻譯領(lǐng)域,簡(jiǎn)單模型加上大量有效樣本數(shù)據(jù),比復(fù)雜模型加小樣本數(shù)據(jù),有效的多。收集有效的、大量的樣本庫(kù)很重要。
CNN
CNN的分類模型與傳統(tǒng)模型的不同點(diǎn)在于其可以直接將一幅二維圖像輸入模型中,接著在輸出端即給出分類結(jié)果。其優(yōu)勢(shì)在于不需復(fù)雜的預(yù)處理,將特征抽取,模式分類完全放入一個(gè)黑匣子中,通過不斷的優(yōu)化來獲得網(wǎng)絡(luò)所需參數(shù),在輸出層給出所需分類,網(wǎng)絡(luò)核心就是網(wǎng)絡(luò)的結(jié)構(gòu)設(shè)計(jì)與網(wǎng)絡(luò)的求解。這種求解結(jié)構(gòu)比以往多種算法性能更高。
tesseract
google支持的開源的OCR圖文識(shí)別開源項(xiàng)目
1.tesseract 圖片名 輸出文件名 -l 字庫(kù)文件 -psm pagesegmode 配置文件
2.tesseract code.jpg result -l chi_sim -psm 7 nobatch
3.-l chi_sim 表示用簡(jiǎn)體中文字庫(kù)(需要下載中文字庫(kù)文件,解壓后,存放到tessdata目錄下去,字庫(kù)文件擴(kuò)展名為 .raineddata 簡(jiǎn)體中文字庫(kù)文件名為: chi_sim.traineddata)
4.-psm 7 表示告訴tesseract code.jpg圖片是一行文本 這個(gè)參數(shù)可以減少識(shí)別錯(cuò)誤率. 默認(rèn)為 3
5.configfile 參數(shù)值為tessdata\configs 和 tessdata\tessconfigs 目錄下的文件名
cv2.imshow()
使用函數(shù)cv2.imshow() 顯示圖像。窗口會(huì)自動(dòng)調(diào)整為圖像大小。第一個(gè)參數(shù)是窗口的名字,其次才是我們的圖像。你可以創(chuàng)建多個(gè)窗口,只要你喜歡,但是必須給他們不同的名字。
cv2.waitKey()
一個(gè)鍵盤綁定函數(shù)。需要指出的是它的時(shí)間尺度是毫
秒級(jí)。函數(shù)等待特定的幾毫秒,看是否有鍵盤輸入。特定的幾毫秒之內(nèi),如果按下任意鍵,這個(gè)函數(shù)會(huì)返回按鍵的ASCII 碼值,程序?qū)?huì)繼續(xù)運(yùn)行。如果沒有鍵盤輸入,返回值為-1,如果我們?cè)O(shè)置這個(gè)函數(shù)的參數(shù)為0,那它將會(huì)無限期的等待鍵盤輸入。
cv2.imshow('image',img)
cv2.waitKey(0)
cv2.GaussianBlur(InputArray src, OutputArray dst, Size ksize, double sigmaX, double sigmaY=0, int borderType=BORDER_DEFAULT )
功能:對(duì)輸入的圖像src進(jìn)行高斯濾波后用dst輸出
參數(shù):src和dst當(dāng)然分別是輸入圖像和輸出圖像。Ksize為高斯濾波器模板大小,sigmaX和sigmaY分別為高斯濾波在橫線和豎向的濾波系數(shù)。borderType為邊緣擴(kuò)展點(diǎn)插值類型。
.shape讀取矩陣的長(zhǎng)度
cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
獲得原圖像的副本,轉(zhuǎn)換成灰度圖
cv2.Sobel(src, ddepth, dx, dy[, dst[, ksize[, scale[, delta[, borderType]]]]])
Sobel算子是一種帶方向的過濾器
前四個(gè)是必須的參數(shù):
第一個(gè)參數(shù)是需要處理的圖像;
第二個(gè)參數(shù)是圖像的深度,-1表示采用的是與原圖像相同的深度。目標(biāo)圖像的深度必須大于等于原圖像的深度;
dx和dy表示的是求導(dǎo)的階數(shù),0表示這個(gè)方向上沒有求導(dǎo),一般為0、1、2。
其后是可選的參數(shù):
dst不用解釋了;
ksize是Sobel算子的大小,必須為1、3、5、7。
scale是縮放導(dǎo)數(shù)的比例常數(shù),默認(rèn)情況下沒有伸縮系數(shù);
delta是一個(gè)可選的增量,將會(huì)加到最終的dst中,同樣,默認(rèn)情況下沒有額外的值加到dst中;
borderType是判斷圖像邊界的模式。這個(gè)參數(shù)默認(rèn)值為cv2.BORDER_DEFAULT。
cv2.CV_16S
16位有符號(hào)的數(shù)據(jù)類型
Sobel函數(shù)求完導(dǎo)數(shù)后會(huì)有負(fù)值,還有會(huì)大于255的值。而原圖像是uint8,即8位無符號(hào)數(shù),所以Sobel建立的圖像位數(shù)不夠,會(huì)有截?cái)唷R虼艘褂?6位有符號(hào)的數(shù)據(jù)類型,即cv2.CV_16S。
cv2.convertScaleAbs(src[, dst[, alpha[, beta]]])
經(jīng)過處理后,別忘了用convertScaleAbs()函數(shù)將其轉(zhuǎn)回原來的uint8形式。否則將無法顯示圖像,而只是一副灰色的窗口
其中可選參數(shù)alpha是伸縮系數(shù),beta是加到結(jié)果上的一個(gè)值。結(jié)果返回uint8類型的圖片。
cv2.addWeighted(src1, alpha, src2, beta, gamma[, dst[, dtype]])
由于Sobel算子是在兩個(gè)方向計(jì)算的,最后還需要用cv2.addWeighted(...)函數(shù)將其組合起來
其中alpha是第一幅圖片中元素的權(quán)重,beta是第二個(gè)的權(quán)重,gamma是加到最后結(jié)果上的一個(gè)值。
np.absolute
x = np.array([-1.2, 1.2])
np.absolute(x)
array([ 1.2, 1.2])
np.absolute(1.2 + 1j)
1.5620499351813308
np.unit8
無符號(hào)整數(shù),0 至 255
np.sum(axis = 1)
每一行的元素相加
cv2.threshold
將得到的結(jié)果二值化
cv2.getStructuringElement(cv2.MORPH_RECT,(13,7))
定義結(jié)構(gòu)元素
用OpenCV-Python內(nèi)置的常量定義橢圓(MORPH_ELLIPSE)和十字形結(jié)構(gòu)(MORPH_CROSS)元素要簡(jiǎn)單一些,如果定義矩形(MORPH_RECT)和自定義結(jié)構(gòu)元素,則兩者差不多。
腐蝕和膨脹
<pre>
import cv2
import numpy as np
img = cv2.imread('D:/binary.bmp',0)
OpenCV定義的結(jié)構(gòu)元素
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(3, 3))
腐蝕圖像
eroded = cv2.erode(img,kernel)
顯示腐蝕后的圖像
cv2.imshow("Eroded Image",eroded);
膨脹圖像
dilated = cv2.dilate(img,kernel)
顯示膨脹后的圖像
cv2.imshow("Dilated Image",dilated);
原圖像
cv2.imshow("Origin", img)
NumPy定義的結(jié)構(gòu)元素
NpKernel = np.uint8(np.ones((3,3)))
Nperoded = cv2.erode(img,NpKernel)
顯示腐蝕后的圖像
cv2.imshow("Eroded by NumPy kernel",Nperoded);
cv2.waitKey(0)
cv2.destroyAllWindows()
</pre>
腐蝕和膨脹的處理很簡(jiǎn)單,只需設(shè)置好結(jié)構(gòu)元素,然后分別調(diào)用cv2.erode(...)和cv2.dilate(...)函數(shù)即可,其中第一個(gè)參數(shù)是需要處理的圖像,第二個(gè)是結(jié)構(gòu)元素。返回處理好的圖像。
開運(yùn)算和閉運(yùn)算 cv2.morphologyEx
形態(tài)學(xué)基本處理:開運(yùn)算和閉運(yùn)算就是將腐蝕和膨脹按照一定的次序進(jìn)行處理。但這兩者并不是可逆的,即先開后閉并不能得到原先的圖像。
<pre>
coding=utf-8
import cv2
import numpy as np
img = cv2.imread('D:/binary.bmp',0)
定義結(jié)構(gòu)元素
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(5, 5))
閉運(yùn)算
closed = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
顯示腐蝕后的圖像
cv2.imshow("Close",closed);
開運(yùn)算
opened = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
顯示腐蝕后的圖像
cv2.imshow("Open", opened);
cv2.waitKey(0)
cv2.destroyAllWindows()
</pre>
<font color=blue >閉運(yùn)算用來連接被誤分為許多小塊的對(duì)象,開運(yùn)算用于移除由圖像噪音形成的斑點(diǎn),</font>因此,某些情況下可以連續(xù)運(yùn)用這兩種運(yùn)算。如對(duì)一副二值圖連續(xù)使用閉運(yùn)算和開運(yùn)算,將獲得圖像中的主要對(duì)象。同樣,如果想消除圖像中的噪聲(即圖像中的“小點(diǎn)”),也可以對(duì)圖像先用開運(yùn)算后用閉運(yùn)算,不過這樣也會(huì)消除一些破碎的對(duì)象。
cv2.findContours(image, mode, method[, contours[, hierarchy[, offset ]]])
<font color=blue>尋找檢測(cè)物體的輪廓 </font>
注:cv2.findContours()函數(shù)接受的參數(shù)為二值圖,即黑白的(不是灰度圖),所以讀取的圖像要先轉(zhuǎn)成灰度的,再轉(zhuǎn)成二值圖
<font color=#00ffff>參數(shù):</font>
第一個(gè)參數(shù)是尋找輪廓的圖像;
第二個(gè)參數(shù)表示輪廓的檢索模式,有四種(本文介紹的都是新的cv2接口):
cv2.RETR_EXTERNAL表示只檢測(cè)外輪廓
cv2.RETR_LIST檢測(cè)的輪廓不建立等級(jí)關(guān)系
cv2.RETR_CCOMP建立兩個(gè)等級(jí)的輪廓,上面的一層為外邊界,里面的一層為內(nèi)孔的邊界信息。如果內(nèi)孔內(nèi)還有一個(gè)連通物體,這個(gè)物體的邊界也在頂層。
cv2.RETR_TREE建立一個(gè)等級(jí)樹結(jié)構(gòu)的輪廓。
第三個(gè)參數(shù)method為輪廓的近似辦法
cv2.CHAIN_APPROX_NONE存儲(chǔ)所有的輪廓點(diǎn),相鄰的兩個(gè)點(diǎn)的像素位置差不超過1,即max(abs(x1-x2),abs(y2-y1))==1
cv2.CHAIN_APPROX_SIMPLE壓縮水平方向,垂直方向,對(duì)角線方向的元素,只保留該方向的終點(diǎn)坐標(biāo),例如一個(gè)矩形輪廓只需4個(gè)點(diǎn)來保存輪廓信息
cv2.CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS使用teh-Chinl chain 近似算法
<font color=#00ffff>返回值:</font>
返回兩個(gè)值:contours,hierarchy。一個(gè)是輪廓本身(list),還有一個(gè)是每條輪廓對(duì)應(yīng)的屬性。
list中每個(gè)元素都是圖像中的一個(gè)輪廓,用numpy中的ndarray表示。這個(gè)概念非常重要。
該函數(shù)還可返回一個(gè)可選的hiararchy結(jié)果,這是一個(gè)ndarray,其中的元素個(gè)數(shù)和輪廓個(gè)數(shù)相同,每個(gè)輪廓contours[i]對(duì)應(yīng)4個(gè)hierarchy元素hierarchy[i][0] ~hierarchy[i][3],分別表示后一個(gè)輪廓、前一個(gè)輪廓、父輪廓、內(nèi)嵌輪廓的索引編號(hào),如果沒有對(duì)應(yīng)項(xiàng),則該值為負(fù)數(shù)。
cv2.drawContours(image, contours, contourIdx, color[, thickness[, lineType[, hierarchy[, maxLevel[, offset ]]]]])
第一個(gè)參數(shù)是指明在哪幅圖像上繪制輪廓;
第二個(gè)參數(shù)是輪廓本身,在Python中是一個(gè)list。
第三個(gè)參數(shù)指定繪制輪廓list中的哪條輪廓,如果是-1,則繪制其中的所有輪廓。后面的參數(shù)很簡(jiǎn)單。其中thickness表明輪廓線的寬度,如果是-1(cv2.FILLED),則為填充模式。繪制參數(shù)將在以后獨(dú)立詳細(xì)介紹。
void approxPolyDP(InputArray curve, OutputArray approxCurve, double epsilon, bool closed);
InputArray curve:輸入的點(diǎn)集
OutputArray approxCurve:輸出的點(diǎn)集,當(dāng)前點(diǎn)集是能最小包容指定點(diǎn)集的。draw出來即是一個(gè)多邊形;
double epsilon:指定的精度,也即是原始曲線與近似曲線之間的最大距離。
bool closed:若為true,則說明近似曲線是閉合的,它的首位都是相連,反之,若為false,則斷開。
IplImage *image = cvLoadImage("I:\OpenCV Learning\picture\sumpalace.jpg");
cvShowImage("image1",image);
//將ROI區(qū)域圖像保存在image中:左上角x、左上角y、矩形長(zhǎng)、寬
cvSetImageROI(image,cvRect(200,200,600,200));
cvShowImage("imageROI",image);
//執(zhí)行cvSetImageROI()之后顯示image圖像是只顯示ROI標(biāo)識(shí)的一部分,即改變了指針image,
//但是它仍舊保留有原來圖像的信息,在執(zhí)行這一句cvResetImageROI(image),之后,image指示原來的圖像信息。
cvResetImageROI(image);
cvShowImage("image2",image);
cvWaitKey(0);
return 0;
}
jTessBoxEditor
import cv2
img = cv2.imread("lenna.png")
crop_img = img[200:400, 100:300] # Crop from x, y, w, h -> 100, 200, 300, 400
NOTE: its img[y: y + h, x: x + w] and not img[x: x + w, y: y + h]
cv2.imshow("cropped", crop_img)
cv2.waitKey(0)
jTessBoxEditor訓(xùn)練步驟
- 工具jTessBoxEditor,下載地址為 http://sourceforge.net/projects/vietocr/files/jTessBoxEditor/
- tif文面命名格式[lang].[fontname].exp[num].tif
tesseract chi.fontname.exp0.tif chi.fontname.exp0 batch.nochop makebox
運(yùn)行以上命令也會(huì)產(chǎn)生一個(gè)box文件。產(chǎn)生box文件的過程是必須的,也是最重要的,沒有box文件以下的內(nèi)容都無法進(jìn)行。
需要記住的是生成的.box要和這個(gè).tif文件同在一個(gè)目錄下。
- 文字校正。運(yùn)行jTessBoxEditor工具,打開chi.黑體.exp0.tif文件(必須將上一步生成的.box和.tif樣本文件放在同一目錄),如上圖所示。可以看出有些字符識(shí)別的不正確,可以通過該工具手動(dòng)對(duì)每張圖片中識(shí)別錯(cuò)誤的字符進(jìn)行校正。校正完成后保存即可。
- 產(chǎn)生字符特征文件
tesseract chi.fontname.exp0.tif chi.fontname.exp0 nobatch box.train - 計(jì)算字符集
unicharset_extractor chi.fontname.exp0.box - 定義字體特征文件,---Tesseract-OCR3.01以上的版本在訓(xùn)練之前需要?jiǎng)?chuàng)建一個(gè)名稱為font_properties.txt的字體特征文件
手工建立一個(gè)文件font_properties.txt
內(nèi)容如:fontname 0 0 0 0 0
注意:fontname為字體名稱,italic為斜體,bold為黑體字,fixed為默認(rèn)字體,serif為襯線字體,fraktur德文黑字體,1和0代表有和無. - 聚集字符特征
shapeclustering -F font_properties.txt -U unicharset chi.fontname.exp0.tr
使用上一步產(chǎn)生的字符集文件unicharset,來生成當(dāng)前新語言的字符集文件chi.unicharset。同時(shí)還會(huì)產(chǎn)生圖形原型文件inttemp和每個(gè)字符所對(duì)應(yīng)的字符mftraining -F font_properties.txt -U unicharset -O chi.unicharset chi.fontname.exp0.tr
特征數(shù)文件pffmtable。最重要的就是這個(gè)inttemp文件了,他包含了所有需要產(chǎn)生的字的圖形原型。
這一步產(chǎn)生字符形狀正?;卣魑募ormproto。cntraining chi.fontname.exp0.tr - 把目錄下的unicharset、inttemp、pffmtable、shapetable、normproto這五個(gè)文件前面都加上chi.
combine_tessdata chi.
11. 然后把chi.traineddata放到tessdata目錄