Python+opencv 實現(xiàn)圖片文字的分割的方法示例
實現(xiàn)步驟:
1、通過水平投影對圖形進行水平分割,獲取每一行的圖像;
2、通過垂直投影對分割的每一行圖像進行垂直分割,最終確定每一個字符的坐標位置,分割出每一個字符;
先簡單介紹一下投影法:分別在水平和垂直方向?qū)︻A處理(二值化)的圖像某一種像素進行統(tǒng)計,對于二值化圖像非黑即白,我們通過對其中的白點或者黑點進行統(tǒng)計,根據(jù)統(tǒng)計結果就可以判斷出每一行的上下邊界以及每一列的左右邊界,從而實現(xiàn)分割的目的。
下面通過Python+opencv來實現(xiàn)該功能
首先來實現(xiàn)水平投影:
import cv2
import numpy as np
'''水平投影'''
def getHProjection(image):
hProjection = np.zeros(image.shape,np.uint8)
#圖像高與寬
(h,w)=image.shape
#長度與圖像高度一致的數(shù)組
h_ = [0]*h
#循環(huán)統(tǒng)計每一行白色像素的個數(shù)
for y in range(h):
for x in range(w):
if image[y,x] == 255:
h_[y]+=1
#繪制水平投影圖像
for y in range(h):
for x in range(h_[y]):
hProjection[y,x] = 255
cv2.imshow('hProjection2',hProjection)
return h_
if __name__ == "__main__":
#讀入原始圖像
origineImage = cv2.imread('test.jpg')
# 圖像灰度化
#image = cv2.imread('test.jpg',0)
image = cv2.cvtColor(origineImage,cv2.COLOR_BGR2GRAY)
cv2.imshow('gray',image)
# 將圖片二值化
retval, img = cv2.threshold(image,127,255,cv2.THRESH_BINARY_INV)
cv2.imshow('binary',img)
#水平投影
H = getHProjection(img)

通過上面的水平投影,根據(jù)其白色小山峰的起始位置就可以界定出每一行的起始位置,從而把每一行分割出來。

獲得每一行圖像之后,可以對其進行垂直投影
def getVProjection(image):
vProjection = np.zeros(image.shape,np.uint8);
#圖像高與寬
(h,w) = image.shape
#長度與圖像寬度一致的數(shù)組
w_ = [0]*w
#循環(huán)統(tǒng)計每一列白色像素的個數(shù)
for x in range(w):
for y in range(h):
if image[y,x] == 255:
w_[x]+=1
#繪制垂直平投影圖像
for x in range(w):
for y in range(h-w_[x],h):
vProjection[y,x] = 255
cv2.imshow('vProjection',vProjection)
return w_

通過垂直投影可以獲得每一個字符左右的起始位置,這樣也就可以獲得到每一個字符的具體坐標位置,即一個矩形框的位置。
下面是實現(xiàn)的全部代碼:
import cv2
import numpy as np
'''水平投影'''
def getHProjection(image):
hProjection = np.zeros(image.shape,np.uint8)
#圖像高與寬
(h,w)=image.shape
#長度與圖像高度一致的數(shù)組
h_ = [0]*h
#循環(huán)統(tǒng)計每一行白色像素的個數(shù)
for y in range(h):
for x in range(w):
if image[y,x] == 255:
h_[y]+=1
#繪制水平投影圖像
for y in range(h):
for x in range(h_[y]):
hProjection[y,x] = 255
cv2.imshow('hProjection2',hProjection)
return h_
def getVProjection(image):
vProjection = np.zeros(image.shape,np.uint8);
#圖像高與寬
(h,w) = image.shape
#長度與圖像寬度一致的數(shù)組
w_ = [0]*w
#循環(huán)統(tǒng)計每一列白色像素的個數(shù)
for x in range(w):
for y in range(h):
if image[y,x] == 255:
w_[x]+=1
#繪制垂直平投影圖像
for x in range(w):
for y in range(h-w_[x],h):
vProjection[y,x] = 255
#cv2.imshow('vProjection',vProjection)
return w_
if __name__ == "__main__":
#讀入原始圖像
origineImage = cv2.imread('test.jpg')
# 圖像灰度化
#image = cv2.imread('test.jpg',0)
image = cv2.cvtColor(origineImage,cv2.COLOR_BGR2GRAY)
cv2.imshow('gray',image)
# 將圖片二值化
retval, img = cv2.threshold(image,127,255,cv2.THRESH_BINARY_INV)
cv2.imshow('binary',img)
#圖像高與寬
(h,w)=img.shape
Position = []
#水平投影
H = getHProjection(img)
start = 0
H_Start = []
H_End = []
#根據(jù)水平投影獲取垂直分割位置
for i in range(len(H)):
if H[i] > 0 and start ==0:
H_Start.append(i)
start = 1
if H[i] <= 0 and start == 1:
H_End.append(i)
start = 0
#分割行,分割之后再進行列分割并保存分割位置
for i in range(len(H_Start)):
#獲取行圖像
cropImg = img[H_Start[i]:H_End[i], 0:w]
#cv2.imshow('cropImg',cropImg)
#對行圖像進行垂直投影
W = getVProjection(cropImg)
Wstart = 0
Wend = 0
W_Start = 0
W_End = 0
for j in range(len(W)):
if W[j] > 0 and Wstart ==0:
W_Start =j
Wstart = 1
Wend=0
if W[j] <= 0 and Wstart == 1:
W_End =j
Wstart = 0
Wend=1
if Wend == 1:
Position.append([W_Start,H_Start[i],W_End,H_End[i]])
Wend =0
#根據(jù)確定的位置分割字符
for m in range(len(Position)):
cv2.rectangle(origineImage, (Position[m][0],Position[m][1]), (Position[m][2],Position[m][3]), (0 ,229 ,238), 1)
cv2.imshow('image',origineImage)
cv2.waitKey(0)

從分割的結果上看,基本上實現(xiàn)了圖片中文字的分割。但由于中文結構復雜性,對于一些文字的分割并不理想,比如“葉”、“桃”等字會出現(xiàn)過度分割現(xiàn)象;對于有粘連的兩個字會出現(xiàn)分割不夠的現(xiàn)象,比如上圖中的“念想”。不過可以從圖像預處理(腐蝕),邊界判斷閾值的調(diào)整等方面進行優(yōu)化。
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
python3實現(xiàn)網(wǎng)頁版raspberry pi(樹莓派)小車控制
這篇文章主要為大家詳細介紹了python3實現(xiàn)網(wǎng)頁版raspberry pi(樹莓派)小車控制,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2020-02-02
python?字符串模糊匹配Fuzzywuzzy的實現(xiàn)
本文主要介紹了python?字符串模糊匹配Fuzzywuzzy的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-07-07
python paramiko連接ssh實現(xiàn)命令
這篇文章主要為大家介紹了python paramiko連接ssh實現(xiàn)的命令詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-07-07
python保存字典數(shù)據(jù)到csv文件的完整代碼
在實際數(shù)據(jù)分析過程中,我們分析用Python來處理數(shù)據(jù)(海量的數(shù)據(jù)),我們都是把這個數(shù)據(jù)轉換為Python的對象的,比如最為常見的字典,下面這篇文章主要給大家介紹了關于python保存字典數(shù)據(jù)到csv的相關資料,需要的朋友可以參考下2022-06-06

