用投影法矫正字符旋转

这是段简单的代码,目的是处理旋转验证码的问题,主要思想就是通过将字符以45°到135°的角度投影下来,得到一系列的投影范围,然后得到这当中投影长度最小的一个角度。这个角度我们就可以简单的把他看成是字符的偏转角。然后用这个角度通过仿射变换得到矫正后的字符。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#coding=utf-8
import cv2,os,sys,Image,math
import numpy as np
from pylab import *
%matplotlib inline

def getBinary(path):#传入图片名,返回二值化的图片
im=cv2.imread(path,0)
thresh,im=cv2.threshold(255-im,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
return im

def shadow(im,angel):#传入图像im以及角度(角度制)angle,返回图像在该角度下的投影长度
x=[]
height , width = im.shape
for i in xrange(height):
for j in xrange(width):
if im[i][j]==255:
x.append(j-1.0*i/math.tan(math.radians(angel)))
x=np.array(x)
return x.max()-x.min()

def shadowTest():#测试shadow函数,需要weibo文件夹下的图片
directory='weibo'
pics=os.listdir(directory)
for pic in pics[:10]:
im=getBinary(os.path.join(directory,pic))
print shadow(im,50)
figure()
gray()
imshow(im)

def getAngle(im):#传入图片,返回使他投影最小的角度
minShadow=500
ans=90
for angle in np.linspace(45,135,91):#我这里范围设置的是45到135度,分度值是1度
thisShadow=shadow(im,angle)
if minShadow>thisShadow:
ans=angle
minShadow=thisShadow
return ans

def getAngleTest():#测试getAngle函数
directory='weibo'
pics=os.listdir(directory)
for pic in pics[:5]:
im=getBinary(os.path.join(directory,pic))
print getAngle(im)
figure()
imshow(im)

def affine(im):#将结合上面的函数,输入图片,输出矫正后的图片
height,width=im.shape
angle=getAngle(im)
#下面是仿射变换,通过确定三点的原值和新值来确定变换的过程,这里我们选取的三点是中心点,顶部中心点,和左部中心点。
pts1=np.float32([[width/2,height/2],[width/2,0],[0,height/2]])
pts2=np.float32([[width/2,height/2],[width/2+height/2/math.tan(math.radians(angle)),0],[0,height/2]])
M=cv2.getAffineTransform(pts1,pts2)
dst=cv2.warpAffine(im,M,(width,height))

return dst

def affineTest():#测试affine函数
directory='weibo'
pics=os.listdir(directory)
for pic in pics[:1]:
im=getBinary(os.path.join(directory,pic))
dst=affine(im)
gray()
figure()
imshow(np.hstack([im,dst]))
axis('off')

affineTest()#测试效果

效果图





可以发现这个方法还是有点效果的。