字符分割有很多方法,但並不是每一種方法是萬能的,那么就需要根據自己的需要來分析。
例如:我現在項目的需求是將一串編號給切分開來。查了網上的資料和文獻,大致適合項目的有兩種方法:投影分割法和連通域分割法。
當然還有其他的一些改進的算法,今天就不作深入討論,以后研究了再分享。今天我們就來實現垂直投影和水平投影
首先是我們的原圖片

垂直投影方法
(h,w)=thresh2.shape a = [0 for z in range(0, w)] for j in range(0,w): for i in range(0,h): if thresh2[i,j]==0: a[j]+=1 thresh2[i,j]=255 for j in range(0,w): for i in range((h-a[j]),h): thresh2[i,j]=0
水平投影方法
(h,w)=thresh1.shape a = [0 for z in range(0, h)] for j in range(0,h): for i in range(0,w): if thresh1[j,i]==0: a[j]+=1 thresh1[j,i]=255 for j in range(0,h): for i in range(0,a[j]): thresh1[j,i]=0
垂直投影的結果:

水平投影的結果:

接下來是完整代碼:
import cv2 import numpy as np from PIL import Image #灰度圖片進行二值化處理 img=cv2.imread('123.jpg') GrayImage=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) ret,thresh1=cv2.threshold(GrayImage,130,255,cv2.THRESH_BINARY) ret,thresh2=cv2.threshold(GrayImage,130,255,cv2.THRESH_BINARY) #水平投影 (h,w)=thresh1.shape a = [0 for z in range(0, h)] for j in range(0,h): for i in range(0,w): if thresh1[j,i]==0: a[j]+=1 thresh1[j,i]=255 for j in range(0,h): for i in range(0,a[j]): thresh1[j,i]=0 #垂直投影 (h,w)=thresh2.shape a = [0 for z in range(0, w)] for j in range(0,w): for i in range(0,h): if thresh2[i,j]==0: a[j]+=1 thresh2[i,j]=255 for j in range(0,w): for i in range((h-a[j]),h): thresh2[i,j]=0 #展示圖片 cv2.imshow("src",img) cv2.imshow('img',thresh1) cv2.imshow('img2',thresh2) cv2.waitKey(0) cv2.destroyAllWindows()
投影法的原理其實很簡單,利用二值化圖片的像素的分布直方圖進行分析,從而找出相鄰字符的分界點進行分割。
總結:做圖像分割的時候要選擇合適的方法,例如我這張樣本圖的布局是左右型,就適合用垂直投影的方法,反之若是上下型,則做水平投影即可。
若圖像內的字符是縱橫交錯的話就需要先垂直投影分割再水平分割,或者采用連通域分割法,取出字符范圍。
