使用tesserocr库可以识别图片验证码,我们以一个简单的图片验证码为例,来演示这个流程
因为验证码中噪点、干扰线以及颜色的干扰,我们不能直接使用tesserocr库来识别验证码,先要对验证码进行去噪操作
将验证码转换为灰度图片
#获取图片对象
img = Image.open("demo.jpg")
#转换为灰度图片
imgGary = img.convert('L')
#查看图片
imgGray.show()
将灰度图片二值化
获取所有像素点,并将小于阈值threshold的,转换为黑色。大于阈值转换为白色。这里我阈值设置的是165,可以根据实际情况自己设定
#设置阈值
threshold = 165
#加载像素点
pixdata = imgGray.load()
#获取图片的宽高
width, height = imgGray.size
for y in range(height):
for x in range(width):
if pixdata[x, y] < threshold:
pixdata[x, y] = 0
else:
pixdata[x, y] = 255
#查看图片
binImg = imgGray
binImg .show()
对二值化的图片进行降噪
此时我们已经消除了颜色的干扰,接下来我们使用八邻域降噪来消除噪点和干扰线。
因为噪点和干扰线大多是独立且零散的,所以我们检查每一个像素点,当像素点的八个相邻的像素点中有超过4个空白的像素点,那么我们就认为这是一个噪点,并删除这个噪点
降噪可以多次进行
#加载像素点
pixdata = binImg.load()
#获取图片宽高
width, height = binImg.size
for y in range(1, height- 1):
for x in range(1, width- 1):
count = 0
# 上
if pixdata[x, y - 1] > 245:
count = count + 1
# 下
if pixdata[x, y + 1] > 245:
count = count + 1
# 左
if pixdata[x - 1, y] > 245:
count = count + 1
# 右
if pixdata[x + 1, y] > 245:
count = count + 1
# 左上
if pixdata[x - 1, y - 1] > 245:
count = count + 1
# 左下
if pixdata[x - 1, y + 1] > 245:
count = count + 1
# 右上
if pixdata[x + 1, y - 1] > 245:
count = count + 1
# 右下
if pixdata[x + 1, y + 1] > 245:
count = count + 1
#消除噪点
if count > 4:
pixdata[x, y] = 255
#查看图片
nrImg = binImg
nrImg.show()
可以发现降噪效果非常明显
使用tesserocr识别验证码
#识别降噪后的图片
ans = tesserocr.image_to_text(nrImg)
#消除空白字符
ans.strip()
#打印
print(ans)
成功识别
完整代码
import tesserocr
from PIL import Image
#获取图片img对象
def getImg(path):
img = Image.open(path)
return img
#将彩色图片转换为灰度图片
def toGrayImg(img):
imgGary = img.convert('L')
return imgGary
#将灰度图片二值化
def toBinImg(imgGray, threshold=165):
pixdata = imgGray.load()
width, height= imgGray.size
for y in range(height):
for x in range(width):
if pixdata[x, y] < threshold:
pixdata[x, y] = 0
else:
pixdata[x, y] = 255
return imgGray
#对图片进行降噪,可进行多轮降噪
def noiseReduction(binImg):
pixdata = binImg.load()
width, height = binImg.size
for y in range(1, height- 1):
for x in range(1, width- 1):
count = 0
# 上
if pixdata[x, y - 1] > 245:
count = count + 1
# 下
if pixdata[x, y + 1] > 245:
count = count + 1
# 左
if pixdata[x - 1, y] > 245:
count = count + 1
# 右
if pixdata[x + 1, y] > 245:
count = count + 1
# 左上
if pixdata[x - 1, y - 1] > 245:
count = count + 1
# 左下
if pixdata[x - 1, y + 1] > 245:
count = count + 1
# 右上
if pixdata[x + 1, y - 1] > 245:
count = count + 1
# 右下
if pixdata[x + 1, y + 1] > 245:
count = count + 1
if count > 4:
pixdata[x, y] = 255
return binImg
def dealImg(path):
img = getImg(path)
grayImg = toGrayImg(img)
binImg = toBinImg(grayImg)
return noiseReduction(binImg)
def readVerificationCode(path):
img = dealImg(path)
print(tesserocr.image_to_text(img))
if __name__ == '__main__':
readVerificationCode("demo.jpg")