opencv-python之投影

字符分割有很多方法,但并不是每一种方法是万能的,那么就需要根据自己的需要来分析。

例如:我现在项目的需求是将一串编号给切分开来。查了网上的资料和文献,大致适合项目的有两种方法:投影分割法和连通域分割法。

当然还有其他的一些改进的算法,今天就不作深入讨论,以后研究了再分享。今天我们就来实现垂直投影和水平投影

首先是我们的原图片

 

 垂直投影方法

(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() 

投影法的原理其实很简单,利用二值化图片的像素的分布直方图进行分析,从而找出相邻字符的分界点进行分割。

总结:做图像分割的时候要选择合适的方法,例如我这张样本图的布局是左右型,就适合用垂直投影的方法,反之若是上下型,则做水平投影即可。

若图像内的字符是纵横交错的话就需要先垂直投影分割再水平分割,或者采用连通域分割法,取出字符范围。

 

posted @ 2020-03-16 19:04  王涛5  阅读(1127)  评论(0编辑  收藏  举报