python-opencv提取圖片中的表格直線--Apple的學(xué)習(xí)筆記

一,傳統(tǒng)方法

1.1

二值化后,用canny邊緣提取,然后用霍夫變換獲得直線為一般方法。比如在圖片中車道線提取上的應(yīng)用。

1.2

二值化后,用橫向和豎向的細(xì)長(zhǎng)的條去腐蝕膨脹可以得到橫線和豎線,拼在一起就是完整的表格框架。比如圖片中表格的提取。

總結(jié)

一開始我用傳統(tǒng)的第一個(gè)方法,python代碼實(shí)現(xiàn)后發(fā)現(xiàn)canny后是輪廓,一條橫線和一條垂線有交點(diǎn),交點(diǎn)處就變成鏤空的十字架,導(dǎo)致線不連續(xù)。后來(lái)了解到膨脹腐蝕即可解決問題,效果更歐豪。如下python實(shí)例代碼為膨脹腐蝕方法。

二,深度學(xué)習(xí)方法(比如車道線識(shí)別)

Lanenet算法等學(xué)完深度學(xué)習(xí)再分析

三,傳統(tǒng)方法理論知識(shí)點(diǎn)說(shuō)明

3.1 二值法

把圖片變成只有2個(gè)值的灰白圖。

3.2 canny方法

用于提取邊緣?;诓檎业姆椒ㄍㄟ^尋找圖像一階導(dǎo)數(shù)中的最大和最小值來(lái)檢測(cè)邊界,通常是將邊界定位在梯度最大的方向。因?yàn)檫吘壓头沁吘壍南袼貢?huì)有明顯突變?;诹愦┰降姆椒ㄍㄟ^尋找圖像二階導(dǎo)數(shù)零穿越來(lái)尋找邊界,通常是Laplacian過零點(diǎn)或者非線性差分表示的過零點(diǎn)。因?yàn)檫@是求駐點(diǎn)或極值的方法,也可以找到突變點(diǎn)。

3.3 霍夫變換

利用同一直線上的點(diǎn),他們的斜率和截距相同,所以轉(zhuǎn)換為K,b坐標(biāo)系中,則多個(gè)直線上的點(diǎn),他們的K,b是相同的,所以每個(gè)點(diǎn)會(huì)轉(zhuǎn)換為一條直線并且相交與k,b點(diǎn)。但是x=1這類垂線無(wú)斜率,所以引入了r,theta極坐標(biāo)系。同理函數(shù)會(huì)相交某點(diǎn)。
相交的某點(diǎn)的函數(shù)線越多,說(shuō)明極坐標(biāo)函數(shù)對(duì)應(yīng)的這些直線上的點(diǎn)越多。
如下為笛卡爾坐標(biāo)系的x,y,取直線上的3個(gè)點(diǎn),則會(huì)在極坐標(biāo)系中轉(zhuǎn)換為3條函數(shù),并且相交于一點(diǎn)。


3.3.png

3.4 膨脹和腐蝕

膨脹是取像素值高的點(diǎn),腐蝕相反,是取像素值低的點(diǎn)。
膨脹的實(shí)現(xiàn)方法是在核區(qū)間內(nèi),取最大值。腐蝕相反。所以若要堅(jiān)持橫豎表格,則核區(qū)間大小一般就使用橫線或垂線。
原圖如下:


3.4.png

腐蝕(erode)后可以明顯的看到圖像字母變細(xì)了
膨脹(dilate)后明顯的看到圖像字母變粗了

四,傳統(tǒng)方法實(shí)實(shí)戰(zhàn)取表格框

4.1 python opencv代碼

此篇主要實(shí)現(xiàn)提取表格框,后續(xù)章節(jié)會(huì)實(shí)現(xiàn)提取單元格內(nèi)容。

import cv2
import numpy as np

image = cv2.imread('cell.jpg', 1)
#二值化
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
binary = cv2.adaptiveThreshold(~gray, 255, 
             cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 15, -10)
# cv2.imshow("cell", binary)
# cv2.waitKey(0)

rows,cols=binary.shape
scale = 20
#識(shí)別橫線
kernel  = cv2.getStructuringElement(cv2.MORPH_RECT,(cols//scale,1))
eroded = cv2.erode(binary,kernel,iterations = 1)
#cv2.imshow("Eroded Image",eroded)
dilatedcol = cv2.dilate(eroded,kernel,iterations = 1)
cv2.imshow("Dilated Image",dilatedcol)
cv2.waitKey(0)

#識(shí)別豎線
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(1,rows//scale))
eroded = cv2.erode(binary,kernel,iterations = 1)
dilatedrow = cv2.dilate(eroded,kernel,iterations = 1)
cv2.imshow("Dilated Image",dilatedrow)
cv2.waitKey(0)

#標(biāo)識(shí)交點(diǎn)
bitwiseAnd = cv2.bitwise_and(dilatedcol,dilatedrow)
cv2.imshow("bitwiseAnd Image",bitwiseAnd)
cv2.waitKey(0)

#標(biāo)識(shí)表格
merge = cv2.add(dilatedcol,dilatedrow)
cv2.imshow("add Image",merge)
cv2.waitKey(0)

4.2 效果如下

原圖


cell.jpg

過程中生成的圖


1.png
2.png
3.png
4.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容