图形验证码识别——图像预处理:二值化
https://github.com/tesseract-ocr/tesseract/wiki/ImproveQuality
什么是图像二值化
全局阈值——otsu算法(自实现版)
https://blog.csdn.net/weixin_40647819/article/details/90179953
总结以下:
import numpy as np
from PIL import Image
import tesserocr
def otsu_threshold(im):
width, height = im.size
pixel_counts = np.zeros(256)
for x in range(width):
for y in range(height):
pixel = im.getpixel((x, y))
pixel_counts[pixel] = pixel_counts[pixel] + 1
# 得到图片的以0-255索引的像素值个数列表
s_max = (0, -10)
for threshold in range(256):
# 遍历所有阈值,根据公式挑选出最好的
# 更新
w_0 = sum(pixel_counts[:threshold]) # 得到阈值以下像素个数
w_1 = sum(pixel_counts[threshold:]) # 得到阈值以上像素个数
# 得到阈值下所有像素的平均灰度
u_0 = sum([i * pixel_counts[i] for i in range(0, threshold)]) / w_0 if w_0 > 0 else 0
# 得到阈值上所有像素的平均灰度
u_1 = sum([i * pixel_counts[i] for i in range(threshold, 256)]) / w_1 if w_1 > 0 else 0
# 总平均灰度
u = w_0 * u_0 + w_1 * u_1
# 类间方差
g = w_0 * (u_0 - u) * (u_0 - u) + w_1 * (u_1 - u) * (u_1 - u)
# 类间方差等价公式
# g = w_0 * w_1 * (u_0 * u_1) * (u_0 * u_1)
# 取最大的
if g > s_max[1]:
s_max = (threshold, g)
return s_max[0]
if __name__ == "__main__":
image = Image.open('yzm.jpg')
image = image.convert('L') #rgb转h灰度图
threshold = otsu_threshold(image)#调用算法
blackwhite = image.point(lambda x: 0 if x < threshold else 255, '1')
blackwhite.show()
print(tesserocr.image_to_text(blackwhite))
代码输入如下图片,文字识别正确。
otsu算法——skimage库
使用方法参考如下:
https://scikit-image.org/docs/dev/auto_examples/segmentation/plot_thresholding.html#sphx-glr-auto-examples-segmentation-plot-thresholding-py
测试代码如下:
import numpy as np
from skimage.filters import threshold_otsu
from skimage import io,color,img_as_uint
if __name__ == "__main__":
image = io.imread('yzm.jpg',as_gray=True)
width,height = image.shape
thresh = threshold_otsu(image)
for x in range(width):
for y in range(height):
if image[x,y] < thresh:
image[x,y] = 0
else:
image[x,y] = 1
io.imsave('yzm_copy.jpg', image)
skimage 库真的很简单……
两篇文章结合一下,图形验证码完成!