python中超簡(jiǎn)單的字符分割算法記錄(車牌識(shí)別、儀表識(shí)別等)
背景
在諸如車牌識(shí)別,數(shù)字儀表識(shí)別等問題中,最關(guān)鍵的就是將單個(gè)的字符分割開來再分別進(jìn)行識(shí)別,如下圖。最近剛好用到,就自己寫了一個(gè)簡(jiǎn)單地算法進(jìn)行字符分割,來記錄一下。
圖像預(yù)處理
彩圖二值化以減小參數(shù)量,再進(jìn)行腐蝕膨脹去除噪點(diǎn)。
image = cv2.imread('F://demo.jpg', 0) # 讀取為灰度圖 _, image = cv2.threshold(image, 50, 255, cv2.THRESH_BINARY) # 二值化 kernel1 = cv2.getStructuringElement(cv2.MORPH_RECT, (7, 7)) # 腐蝕膨脹核 kernel2 = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5)) # 腐蝕膨脹核 image = cv2.erode(image, kernel=kernel1) # 腐蝕 image = cv2.dilate(image, kernel=kernel2) # 膨脹
確定字符區(qū)域
考慮最理想的情況,圖中的字符是端正沒有傾斜歪曲的。將像素灰度矩陣分別進(jìn)行列相加、行相加,則在得到的列和、行和數(shù)組中第一個(gè)非 0 元素索引到最后一個(gè)非 0 元素索引包裹的區(qū)間即就是字符區(qū)域。
h, w = image.shape # 原圖的高和寬 list1 = [] # 列和 list2 = [] # 行和 for i in range(w): list1.append(1 if image[:, i].sum() != 0 else 0) # 列求和,不為0置1 for i in range(h): list2.append(1 if image[i, :].sum() != 0 else 0) # 行求和,不為0置1 # 裁剪字符區(qū)域 # 求行的范圍 flag = 0 for i, e in enumerate(list1): if e != 0: if flag == 0: # 第一個(gè)不為0的位置記錄 start_w = i flag = 1 else: # 最后一個(gè)不為0的位置 end_w = i # 求列的范圍 flag = 0 for i, e in enumerate(list2): if e != 0: if flag == 0: # 第一個(gè)不為0的位置記錄 start_h = i flag = 1 else: # 最后一個(gè)不為0的位置 end_h = i print(start_w, end_w) # 行索引范圍 print(start_h, end_h) # 列索引范圍
分割單個(gè)字符
與分割全部字符區(qū)域同理,在行和數(shù)組中非 0 元素索引的范圍即是單個(gè)字符的區(qū)域。
l = ([i for i, e in enumerate(list1) if e != 0]) # 列和列表中不為0的索引 img_list = [] # 分割數(shù)字圖片存儲(chǔ)列表 temp = [] # 存儲(chǔ)某一個(gè)數(shù)字的所有行索引值 n = 0 # 數(shù)字圖片數(shù)量 for x in l: temp.append(x) if x+1 not in l: # 索引不連續(xù)的情況 if len(temp) != 1: start_w = min(temp) # 索引最小值 end_w = max(temp) # 索引最大值 img_list.append(image[start_h:end_h, start_w:end_w]) # 對(duì)該索引包括數(shù)字切片 n += 1 temp = [] print(n) # 字符數(shù)
完整源碼
import cv2 start_h, end_h, start_w, end_w = 0, 0, 0, 0 # 字符區(qū)域的高和寬起止 image = cv2.imread('F://001_1.jpg', 0) # 直接讀取為灰度圖 cv2.imshow('img_GRAY', image) _, image = cv2.threshold(image, 50, 255, cv2.THRESH_BINARY) # 二值化 cv2.imshow('img_BINARY', image) # 去噪點(diǎn) kernel1 = cv2.getStructuringElement(cv2.MORPH_RECT, (7, 7)) # 簡(jiǎn)單腐蝕膨脹核 kernel2 = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5)) # 簡(jiǎn)單腐蝕膨脹核 image = cv2.erode(image, kernel=kernel1) # 腐蝕 image = cv2.dilate(image, kernel=kernel2) # 膨脹 cv2.imshow('img_denoise', image) h, w = image.shape # 原圖的高和寬 # print(h, w) list1 = [] # 列和 list2 = [] # 行和 for i in range(w): list1.append(1 if image[:, i].sum() != 0 else 0) # 列求和,不為0置1 for i in range(h): list2.append(1 if image[i, :].sum() != 0 else 0) # 行求和,不為0置1 # print(len(list1)) # print(len(list2)) # 裁剪字符區(qū)域 # 求行的范圍 flag = 0 for i, e in enumerate(list1): if e != 0: if flag == 0: # 第一個(gè)不為0的位置記錄 start_w = i flag = 1 else: # 最后一個(gè)不為0的位置 end_w = i # 求列的范圍 flag = 0 for i, e in enumerate(list2): if e != 0: if flag == 0: # 第一個(gè)不為0的位置記錄 start_h = i flag = 1 else: # 最后一個(gè)不為0的位置 end_h = i print(start_w, end_w) # 行索引范圍 print(start_h, end_h) # 列索引范圍 cv2.imshow('img_number', image[start_h:end_h, start_w:end_w]) l = ([i for i, e in enumerate(list1) if e != 0]) # 列和列表中不為0的索引 # print(l) img_list = [] # 分割數(shù)字圖片存儲(chǔ)列表 temp = [] # 存儲(chǔ)某一個(gè)數(shù)字的所有行索引值 n = 0 # 數(shù)字圖片數(shù)量 for x in l: temp.append(x) if x+1 not in l: # 索引不連續(xù)的情況 if len(temp) != 1: start_w = min(temp) # 索引最小值 end_w = max(temp) # 索引最大值 img_list.append(image[start_h:end_h, start_w:end_w]) # 對(duì)該索引包括數(shù)字切片 n += 1 # print(temp) temp = [] print(n) # 字符數(shù) for i in range(n): # 顯示保存字符 cv2.imshow('number'+str(i), img_list[i]) cv2.imwrite('F://demo'+str(i+1).zfill(2)+'.jpg', img_list[i]) cv2.waitKey(0)
結(jié)語(yǔ)
利用列向和行向相加的方法簡(jiǎn)單分割字符的方法并不適用更加復(fù)雜的分割要求,另外算法中也沒有考慮小數(shù)點(diǎn)分割問題,僅作為學(xué)習(xí)參考,歡迎有問題一起討論交流。
到此這篇關(guān)于python中超簡(jiǎn)單的字符分割算法記錄(車牌識(shí)別、儀表識(shí)別等)的文章就介紹到這了,更多相關(guān)python字符分割算法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
淺談算法之最小生成樹Kruskal的Python實(shí)現(xiàn)
最小生成樹Kruskal算法可以稱為“加邊法”,初始最小生成樹邊數(shù)為0,每迭代一次就選擇一條滿足條件的最小代價(jià)邊,加入到最小生成樹的邊集合里。本文將介紹它的原理,并用Python進(jìn)行實(shí)現(xiàn)2021-06-06Python3.7基于hashlib和Crypto實(shí)現(xiàn)加簽驗(yàn)簽功能(實(shí)例代碼)
這篇文章主要介紹了Python3.7基于hashlib和Crypto實(shí)現(xiàn)加簽驗(yàn)簽功能,環(huán)境是基于python3.7,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-12-12解決Python print 輸出文本顯示 gbk 編碼錯(cuò)誤問題
這篇文章主要介紹了解決Python print 輸出文本顯示 gbk 編碼錯(cuò)誤問題,本文給出了三種解決方法,需要的朋友可以參考下2018-07-07Python 中使用 PyMySQL模塊操作數(shù)據(jù)庫(kù)的方法
這篇文章主要介紹了Python 中使用 PyMySQL模塊操作數(shù)據(jù)庫(kù)的方法,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-11-11python通過nmap掃描在線設(shè)備并嘗試AAA登錄(實(shí)例代碼)
這篇文章主要介紹了python通過nmap掃描在線設(shè)備并嘗試AAA登錄,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-12-12