1 对图片进行二值化处理
二值化就是将图片的颜色转换成非黑即白的图片
from PIL import Image
im = Image.open('yzm.jpg') # 用pil打开这个图片
im = im.convert('L') # 将图像转换为“L”模式, 即黑白。
yuzhi = 127 # 根据需要自行更改阈值
im = im.point(lambda x: 0 if x < yuzhi else x >= yuzhi, '1') # 二值化 127为分割灰度的点(阀值)
im.show() # 查看图片
图片资源:
经过上述处理应该这样的生成图片:
如果显示的图片效果不理想,可以调整阀值来进行调整(但是依然会留有小黑点)
2 去除噪点
把图片中的黑点去掉
from PIL import ImageDraw, Image
def getPixel(image, x, y):
"""
去除黑点
:param image: 图片路径
:param x: 像素点x轴坐标
:param y: 像素点y轴坐标
:return:
"""
L = image.getpixel((x, y)) # 获取当前像素点的像素
if L == 0: # 判读此像素点是否为黑,因为如果是白的就没必要处理了
nearDots = 0 # 初始化记录周围有没有黑像素数量的值
# 判断周围像素点(白色 +1)
for i in range(1, 4): # 根据点的大小自行选择周围像素点层数
# try 防止越界
try:
if L - image.getpixel((x - i, y - i)):
nearDots += 1
except:
pass
try:
if L - image.getpixel((x - i, y)):
nearDots += 1
except:
pass
try:
if L - image.getpixel((x - i, y + i)):
nearDots += 1
except:
pass
try:
if L - image.getpixel((x, y - i)):
nearDots += 1
except:
pass
try:
if L - image.getpixel((x, y + i)):
nearDots += 1
except:
pass
try:
if L - image.getpixel((x + i, y - i)):
nearDots += 1
except:
pass
try:
if L - image.getpixel((x + i, y)):
nearDots += 1
except:
pass
try:
if L - image.getpixel((x + i, y + i)):
nearDots += 1
except:
pass
# 根据需求自行调节
if nearDots > 16: # 这里如果周围16个是白点那么就返回一个白点,实现去黑点的操作
return 1 # 返回白点
else:
return 0 # 返回黑点
else:
return 1
def clearNoise(image):
"""清除噪点"""
draw = ImageDraw.Draw(image)
# 循环遍历每个像素点
for x in range(0, image.size[0]):
for y in range(0, image.size[1]):
color = getPixel(image, x, y)
draw.point((x, y), color)
return image
if __name__ == '__main__':
im = Image.open("./yzm_gai.png")
im = clearNoise(im)
im.show()
经过上述处理应该这样的生成图片:
3 OCR识别
import pytesseract
from PIL import Image
image = Image.open('yzm_gai.png')
# chi_sim 是中文识别包,equ 是数学公式包,eng 是英文包
code = pytesseract.image_to_string(image, lang="chi_sim")
print(code)
识别结果:
M8K2
成功,完美!!!
虽然本次识别成功,并不代表每次都可以识别成功,对于较复杂的验证码识别成功率更低,那该怎么办呢???
当然是训练!!!(待续。。。)
完整代码:
import pytesseract
from PIL import Image, ImageDraw
def img_to_L(img_path):
"""
将图片转化为非黑即白的图片
:param img_path: 图片路径
:return:
"""
im = Image.open(img_path) # 用pil打开这个图片
im = im.convert('L')
yuzhi = 127
im = im.point(lambda x: 0 if x < yuzhi else x >= yuzhi, '1') # 二值化 100为分割灰度的点(阀值),二值化就是将图片的颜色转换成非黑即白的图片
im.show()
return im
def getPixel(image, x, y):
"""
去除黑点
:param image: 图片路径
:param x: 像素点x轴坐标
:param y: 像素点y轴坐标
:return:
"""
L = image.getpixel((x, y)) # 获取当前像素点的像素
if L == 0: # 判读此像素点是否为黑,因为如果是白的就没必要处理了
nearDots = 0 # 初始化记录周围有没有黑像素数量的值
# 判断周围像素点(白色 +1)
for i in range(1, 4):
try:
if L - image.getpixel((x - i, y - i)):
nearDots += 1
except:
pass
try:
if L - image.getpixel((x - i, y)):
nearDots += 1
except:
pass
try:
if L - image.getpixel((x - i, y + i)):
nearDots += 1
except:
pass
try:
if L - image.getpixel((x, y - i)):
nearDots += 1
except:
pass
try:
if L - image.getpixel((x, y + i)):
nearDots += 1
except:
pass
try:
if L - image.getpixel((x + i, y - i)):
nearDots += 1
except:
pass
try:
if L - image.getpixel((x + i, y)):
nearDots += 1
except:
pass
try:
if L - image.getpixel((x + i, y + i)):
nearDots += 1
except:
pass
if nearDots > 16: # 这里如果周围10个是白点那么就返回一个白点,实现去黑点的操作
return 1 # 返回白点
else:
return 0 # 返回黑点
else:
return 1
def clearNoise(image):
"""
清除噪点
:param image: 图像路径
:return:
"""
draw = ImageDraw.Draw(image)
# 循环遍历每个像素点
for x in range(0, image.size[0]):
for y in range(0, image.size[1]):
color = getPixel(image, x, y)
draw.point((x, y), color)
return image
def OCR(im):
# chi_sim 是中文识别包,equ 是数学公式包,eng 是英文包
code = pytesseract.image_to_string(im, lang='eng')
return code
if __name__ == '__main__':
# 图像路径
im = "yzm.jpg"
# # 将图片转化为非黑即白的图片
im = img_to_L(im)
# 将上一步处理完成的im对象传给clearNoise()函数
im = clearNoise(im)
im.show()
# 进行OCR识别
code = OCR(im)
print(code)