当前位置:   article > 正文

Python 实现对简单验证码识别_python可以区分大小写的图片识别

python可以区分大小写的图片识别

本文参考链接:https://www.cnblogs.com/xuchunlin/p/9415620.html

首先收集原始的验证码图片:

这种验证码的特点是统一都是红色字体的四个字符组成,其中包括大写字母 A-Z,小写字母 a-z 和数字 0-9。我这儿需要的验证码识别对大小写不加以区分,所以大小写识别错误不算作识别错误,比如第一个验证码:DwP6,如果识别成:Dwp6,我们也把他算作识别正确。通过观察,我们可以提前想到,这种验证码识别的难度在于部分字符的难以区分,比如 S 和 5、I 和 1、 i 和 j、2 和 Z、0 和 o 、y 和 v 、9 和 g 等等之类。字符间的间距也会有一定的干扰,降低了单个字符的区分度,比如会把紧邻的两个字符 vv识别成一个字符 w。验证码中的部分字符连人本身都难以区分,对机器而言难度也就可想而知了。

首先进行灰度处理,将原来的彩色图片变成灰度图片,同时去除部分图片中的暗色条纹。这里选择合适的阈值参数比较重要,阈值太大过滤不掉太多杂质信息,阈值太小则剩下的有效信息又太少。下面是阈值 threshold 分别为 210, 180, 150 对应的灰度图片,我程序里选择的 threshold=180。

                                                             

  1. import os
  2. import pytesseract
  3. from PIL import Image
  4. before = r"D:\MyProject\Python\ReturnVisit\auth_code\before\\" # 原始验证码图片目录
  5. after = r"D:\MyProject\Python\ReturnVisit\auth_code\after\\" # 处理后验证码图片目录
  6. def grey_processing(): # 灰度处理
  7. threshold = 180
  8. file_list = os.listdir(before)
  9. for file in file_list:
  10. path = before + file
  11. img = Image.open(path)
  12. w, h = img.size
  13. for x in range(w):
  14. for y in range(h):
  15. r, g, b = img.getpixel((x, y))
  16. if 190 <= r <= 255 and 170 <= g <= 255 and 0 <= b <= 140:
  17. img.putpixel((x, y), (0, 0, 0))
  18. if 0 <= r <= 90 and 210 <= g <= 255 and 0 <= b <= 90:
  19. img.putpixel((x, y), (0, 0, 0))
  20. img = img.convert('L').point([0] * threshold + [1] * (256 - threshold), '1')
  21. # 边缘噪点处理
  22. for x in range(0, img.size[0]):
  23. for y in range(0, img.size[1]):
  24. if x in [0, img.size[0] - 1] or y in [0, img.size[1] - 1]:
  25. img.putpixel((x, y), 255) # 将边缘全变为非黑的点(简单粗暴)
  26. path = path.replace('PNG', 'jpeg')
  27. path = path.replace('before', 'after') # 更换新图片保存路径
  28. img.save(path)

灰度处理后的图片:

然后进行二值化处理和内部噪点处理:

  1. t2val = {} # 使用字典来保存二值化像素矩阵
  2. def two_value(image, G): # 二值化处理, G是图像二值化阀值
  3. for y in range(0, image.size[1]):
  4. for x in range(0, image.size[0]):
  5. g = image.getpixel((x, y))
  6. if g < G: # 灰度处理以后,点的区分度已经比较明显了。
  7. t2val[(x, y)] = 1
  8. else:
  9. t2val[(x, y)] = 0
  10. # 自定义孤立点为噪点
  11. def clear_noise(image): # 清噪
  12. # 边缘噪点处理(本来想放到这块,但是这儿对像素的修改不能即使生效,对内部噪点处理会有影响,这不是我想要的结果!)
  13. # for x in range(0, image.size[0]):
  14. # for y in range(0, image.size[1]):
  15. # if x in [0, image.size[0] - 1] or y in [0, image.size[1] - 1]:
  16. # image.putpixel((x, y), 255) # 将边缘全变为非黑的点(简单粗暴)
  17. # 内部噪点处理
  18. for x in range(1, image.size[0] - 1):
  19. for y in range(1, image.size[1] - 1):
  20. nearDots = 0
  21. L = 1 # 黑点用1表示
  22. if L == t2val[(x - 1, y - 1)]:
  23. nearDots += 1
  24. if L == t2val[(x - 1, y)]:
  25. nearDots += 1
  26. if L == t2val[(x - 1, y + 1)]:
  27. nearDots += 1
  28. if L == t2val[(x, y - 1)]:
  29. nearDots += 1
  30. if L == t2val[(x, y + 1)]:
  31. nearDots += 1
  32. if L == t2val[(x + 1, y - 1)]:
  33. nearDots += 1
  34. if L == t2val[(x + 1, y)]:
  35. nearDots += 1
  36. if L == t2val[(x + 1, y + 1)]:
  37. nearDots += 1
  38. if nearDots == 0 and t2val[(x, y)] == 1: # 如果当前是黑点且周围领域没有其他黑点
  39. image.putpixel((x, y), 255) # 将当前点变为非黑的点
  40. def denoise(): # 降噪
  41. file_list = os.listdir(after)
  42. for file in file_list:
  43. path = after + file
  44. image = Image.open(path)
  45. two_value(image, 100)
  46. clear_noise(image)
  47. path = path.replace('before', 'after')
  48. image.save(path)

降噪处理后的图片: 

然后就是关于对降噪后的验证码图片进行识别了,其中会用到 pytesseract,这个包的安装和使用请自行参考链接https://blog.csdn.net/EB_NUM/article/details/77060009。需要下载 tesseract-ocr-setup-3.02.02.exe 进行安装,并对 pytesseract.py文件进行相应修改。

  1. def recognize(): # 识别
  2. file_list = os.listdir(after)
  3. for file in file_list:
  4. img_path = after + file
  5. im = Image.open(img_path)
  6. text = pytesseract.image_to_string(im, lang='eng')
  7. exclude_char_list = ' ‘’.:\\|\'\"?![],()~@#$%^&*_+-={};<>/¥©“連'
  8. # 去除识别结果中的特殊字符
  9. text = ''.join([x for x in text if x not in exclude_char_list])[:4]
  10. # 对易混淆字符添加识别结果可选项,提高识别率
  11. # S 和 5、l 和 1、 i 和 j、2 和 Z、0 和 o 、y 和 v 、9 和 g、h 和 n
  12. options = [text]
  13. if len(text) == 4:
  14. if 'i' in text:
  15. options.append(text.replace('i', 'j'))
  16. if 'j' in text:
  17. options.append(text.replace('j', 'i'))
  18. if 'l' in text:
  19. options.append(text.replace('l', '1'))
  20. if '1' in text:
  21. options.append(text.replace('1', 'l'))
  22. if 's' in text:
  23. options.append(text.replace('s', '5'))
  24. if '5' in text:
  25. options.append(text.replace('5', 's'))
  26. if '2' in text:
  27. options.append(text.replace('2', 'z'))
  28. if 'z' in text:
  29. options.append(text.replace('z', '2'))
  30. if '0' in text:
  31. options.append(text.replace('0', 'o'))
  32. if 'o' in text:
  33. options.append(text.replace('o', '0'))
  34. if 'y' in text:
  35. options.append(text.replace('y', 'v'))
  36. if 'v' in text:
  37. options.append(text.replace('v', 'y'))
  38. if '9' in text:
  39. options.append(text.replace('9', 'g'))
  40. if 'g' in text:
  41. options.append(text.replace('g', '9'))
  42. if 'h' in text:
  43. options.append(text.replace('h', 'n'))
  44. if 'n' in text:
  45. options.append(text.replace('n', 'h'))
  46. if '8' in text:
  47. options.append(text.replace('8', 'B'))
  48. if 'B' in text:
  49. options.append(text.replace('B', '8'))
  50. elif len(text) == 3 and "W" in text.upper():
  51. options.append(text.upper().replace('W', 'vv'))
  52. options.append(text.upper().replace('W', 'yy'))
  53. print(file, options)

识别结果如下:

  1. "D:\Program Files\Python36\python3.exe" D:/MyProject/Python/ReturnVisit/verification_code_recognize.py
  2. IMG_0326.jpeg ['DwP6']
  3. IMG_0327.jpeg ['QXH']
  4. IMG_0328.jpeg ['hzew', 'h2ew', 'nzew']
  5. IMG_0329.jpeg ['']
  6. IMG_0330.jpeg ['iQlg', 'jQlg', 'iQ1g', 'iQl9']
  7. IMG_0331.jpeg ['apor', 'ap0r']
  8. IMG_0332.jpeg ['apor', 'ap0r']
  9. IMG_0333.jpeg ['wsn', 'vvSN', 'yySN']
  10. IMG_0334.jpeg ['uSZ5', 'uSZs']
  11. IMG_0335.jpeg ['nz']
  12. IMG_0336.jpeg ['aNpW']
  13. IMG_0337.jpeg ['RWU', 'RvvU', 'RyyU']
  14. IMG_0338.jpeg ['LNX1', 'LNXl']
  15. IMG_0339.jpeg ['Mzln', 'Mz1n', 'M2ln', 'Mzlh']
  16. IMG_0340.jpeg ['Xo1v', 'Xolv', 'X01v', 'Xo1y']
  17. IMG_0341.jpeg ['WBJ4']
  18. IMG_0342.jpeg ['Qc1S', 'QclS']
  19. IMG_0343.jpeg ['JTPB']
  20. IMG_0344.jpeg ['rW7N']
  21. IMG_0345.jpeg ['ZSLE']
  22. IMG_0347.jpeg ['b3D']
  23. IMG_0348.jpeg ['OY7']
  24. IMG_0349.jpeg ['HQK7']
  25. IMG_0350.jpeg ['X304', 'X3o4']
  26. IMG_0351.jpeg ['2PQW', 'zPQW']
  27. IMG_0352.jpeg ['psks', 'p5k5']
  28. IMG_0353.jpeg ['NOE']
  29. IMG_0354.jpeg ['WYOY']
  30. IMG_0355.jpeg ['M3oA', 'M30A']
  31. IMG_0356.jpeg ['AMV']
  32. IMG_0357.jpeg ['VFSR']
  33. IMG_0358.jpeg ['ZZIH']
  34. IMG_0359.jpeg ['4RoS', '4R0S']
  35. IMG_0360.jpeg ['mu']
  36. IMG_0361.jpeg ['mm']
  37. IMG_0362.jpeg ['FBV2', 'FBVz']
  38. IMG_0363.jpeg ['2eEc', 'zeEc']
  39. IMG_0364.jpeg ['Wm']
  40. IMG_0365.jpeg ['EoFR', 'E0FR']
  41. IMG_0366.jpeg ['CQU9', 'CQUg']
  42. Process finished with exit code 0

其中列表第一个元素为原始识别结果,通过统计,识别正确率大概只有25%左右。如果把S 和 5、I 和 1、 i 和 j、2 和 Z、0 和 o 、y 和 v 、9 和 g这些容易混淆字符稍作处理给出多个可选项,识别正确率应该会有一定的提升。

如果你想自己训练模型来进行验证码的识别,请继续往下看:

自己训练模型的话,最重要的是训练集的收集了。为表诚意,小弟先奉上1056张带标记的验证码图片百度云链接(为了便于分享,已经将图片文件夹压缩成了rar文件,其中图片文件名为验证码生成的真实字符串,完全手工标记,因此也有部分出错的地方,不过出错的部分很少,不用过于担心!):链接:https://pan.baidu.com/s/14pJdTXD9OarUSrkgeDGE5g          提取码:xfym,我自己使用了其中 1000 张作为训练集,剩下的 56 张作为验证集使用。

目录结构如图:其中 train 目录是训练集所在目录,before 为带标签的原始验证码图片目录;after 为二值化、降噪处理后的验证码图片目录;cutting 则为验证码处理后的图片再次切割后的单个字符图片目录。validation 目录是验证集所在目录,目录结构与 train 目录类似:

          

       

验证集有了以后,先进行灰度化处理(同上),然后对每四个字符的验证码图片进行切割标记:

  1. import numpy as np
  2. from sklearn.externals import joblib
  3. from sklearn.neighbors import KNeighborsClassifier
  4. before = r"D:\MyProject\Python\ReturnVisit\auth_code\train\before\\" # 原始验证码图片目录
  5. after = r"D:\MyProject\Python\ReturnVisit\auth_code\train\after\\" # 处理后验证码图片目录
  6. cutting = r"D:\MyProject\Python\ReturnVisit\auth_code\train\cutting\\" # 切割后的图片目录
  7. def smart_slice_image(img, outDir, file, count=4, p_w=3):
  8. """
  9. :param img: image对象
  10. :param outDir: 切割图片输出目录
  11. :param count: 图片中有多少个图片
  12. :param p_w: 对切割地方多少像素内进行判断
  13. """
  14. w, h = img.size
  15. pixdata = img.load()
  16. eachWidth = int(w / count) # 每个切割图片的宽度
  17. beforeX = 0
  18. for i in range(count):
  19. # temp_dir = file[i]
  20. allBCount = []
  21. nextXOri = (i + 1) * eachWidth
  22. for x in range(nextXOri - p_w, nextXOri + p_w):
  23. if x >= w:
  24. x = w - 1
  25. if x < 0:
  26. x = 0
  27. b_count = 0
  28. for y in range(h):
  29. if pixdata[x, y] == 0:
  30. b_count += 1
  31. allBCount.append({'x_pos': x, 'count': b_count})
  32. sort = sorted(allBCount, key=lambda e: e.get('count'))
  33. nextX = sort[0]['x_pos']
  34. box = (beforeX, 0, nextX, h)
  35. isExists = os.path.exists(outDir + file[i].upper() + "\\")
  36. # 判断结果
  37. if not isExists:
  38. os.makedirs(outDir + file[i].upper() + "\\")
  39. img.crop(box).save(outDir + file[i].upper() + "\\" + file[i] + "_" + file)
  40. beforeX = nextX
  41. def cutting_image():
  42. file_list = os.listdir(after)
  43. for file in file_list:
  44. path = after + file
  45. img = Image.open(path)
  46. out_dir = cutting
  47. smart_slice_image(img, out_dir, file, count=4, p_w=3)

验证码图片切割好以后,开始进行模型训练,我这儿的原始验证码图片规格为 49×25:

  1. def load_dataset(): # 将切割后的图片与字符标签对应起来保存成数组
  2. X = []
  3. Y = []
  4. for i in "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ":
  5. target_path = cutting + i # 训练集
  6. for title in os.listdir(target_path):
  7. # pix = np.asarray(Image.open(os.path.join(target_path, title)).convert('L'))
  8. pix = np.asarray(Image.open(os.path.join(target_path, title)).resize((13, 25), Image.ANTIALIAS))
  9. pix = pix.reshape(13 * 25)
  10. X.append(pix)
  11. Y.append(i)
  12. X = np.asarray(X)
  13. Y = np.asarray(Y)
  14. return X, Y
  15. def train_model():
  16. X, Y = load_dataset()
  17. knn = KNeighborsClassifier()
  18. knn.fit(X, Y)
  19. joblib.dump(knn, 'recognize.model')

模型训练完成以后,开始进行模型验证:

  1. def verify_model(model):
  2. pre_list = []
  3. y_list = []
  4. for i in "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ":
  5. part_path = cutting.replace('train', 'validation') + i # 验证集
  6. if os.path.exists(part_path):
  7. for title in os.listdir(part_path):
  8. pix = np.asarray(Image.open(os.path.join(part_path, title)).resize((13, 25), Image.ANTIALIAS))
  9. pix = pix.reshape(13 * 25)
  10. pre_list.append(pix) # 待预测列表
  11. y_list.append(i)
  12. pre_list = np.asarray(pre_list)
  13. # y_list = np.asarray(y_list)
  14. predict_list = list(model.predict(pre_list)) # 预测结果
  15. acc = 0
  16. for i in range(len(y_list)):
  17. if y_list[i] == predict_list[i]:
  18. acc += 1
  19. print("原始字符:", list(y_list))
  20. print("预测字符:", list(predict_list))
  21. print("单个字符识别正确率:", "%.2f" % (100 * acc / len(y_list)) + "%")
  22. if __name__ == '__main__':
  23. train_model()
  24. model = joblib.load('recognize.model')
  25. verify_model(model)

运行输出结果为(一张验证码图片如果有相同字符,按照我当前对分割图片的命名规则会覆盖掉,所以这儿的原始字符个数并不是 56*4=224张),验证码字符的粘连性导致切割后的图片与字符的对应关系出错:

  1. 原始字符: ['0', '0', '1', '2', '4', '5', '5', '5', '5', '6', '6', '6', '6', '7', '7', '7',
  2. '9', '9', '9', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C',
  3. 'D', 'D', 'D', 'D', 'D', 'D', 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'F', 'F',
  4. 'F', 'G', 'G', 'G', 'G', 'G', 'H', 'H', 'H', 'H', 'H', 'H', 'H', 'I', 'I', 'I', 'I', 'I',
  5. 'I', 'J', 'J', 'J', 'J', 'K', 'K', 'K', 'K', 'K', 'K', 'K', 'L', 'L', 'L', 'L', 'L', 'M',
  6. 'M', 'M', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'O', 'O', 'O', 'O', 'O', 'P', 'P', 'P', 'P',
  7. 'P', 'P', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R',
  8. 'R', 'S', 'S', 'S', 'S', 'S', 'S', 'T', 'T', 'T', 'U', 'U', 'V', 'V', 'V', 'V', 'V', 'V',
  9. 'V', 'V', 'V', 'V', 'V', 'V', 'W', 'W', 'W', 'W', 'X', 'X', 'X', 'X', 'Y', 'Y', 'Y', 'Y',
  10. 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y',
  11. 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Z', 'Z', 'Z', 'Z', 'Z', 'Z', 'Z', 'Z', 'Z',
  12. 'Z', 'Z', 'Z', 'Z', 'Z', 'Z', 'Z', 'Z', 'Z', 'Z', 'Z', 'Z', 'Z', 'Z', 'Z', 'Z', 'Z', 'Z',
  13. 'Z', 'Z', 'Z', 'Z']
  14. 预测字符: ['1', '0', '1', '2', '4', '5', '5', '5', '1', '5', '6', '6', '5', '7', '7', '7',
  15. 'D', '9', '9', 'Q', 'A', 'A', '1', 'B', 'B', 'B', 'C', '1', 'C', 'O', 'C', '1', 'C', 'O',
  16. 'L', 'D', 'D', 'Q', 'D', 'W', 'E', 'C', '5', 'E', 'E', 'E', 'E', 'E', 'E', 'C', 'F', 'F',
  17. '4', 'G', 'G', 'G', 'G', 'G', 'H', 'H', 'H', 'H', 'H', 'H', 'H', '5', 'J', 'I', 'I', 'I',
  18. 'I', 'D', '1', 'B', '1', '1', 'K', 'K', 'K', 'K', 'K', 'I', 'L', '1', 'I', '1', 'L', 'M',
  19. 'H', 'M', 'N', 'N', 'M', 'H', 'N', '1', 'K', 'H', 'O', 'O', 'C', '0', 'B', 'P', '1', 'C',
  20. 'B', 'O', 'D', 'O', 'Q', 'O', 'O', 'Q', 'I', 'Q', '0', 'S', 'L', 'R', '1', 'R', 'R', 'R',
  21. 'H', 'H', 'S', 'S', 'S', 'S', 'S', 'H', 'U', 'T', 'U', 'I', 'V', '1', '1', 'V', 'V', '5',
  22. 'Y', 'V', 'V', 'V', 'V', 'V', 'W', '1', 'W', 'W', 'X', 'X', 'X', 'X', 'Y', 'Y', 'Y', 'Y',
  23. 'H', 'Y', '4', '1', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'W',
  24. 'Y', 'Y', '1', '1', 'Y', 'Y', 'Y', '1', 'I', 'Z', 'Z', '7', '7', 'Z', '2', 'Z', '7', 'Z',
  25. '7', 'Z', '7', 'Z', '2', 'Z', '7', '7', '7', 'Z', 'Z', '7', '1', '7', 'Z', '7', 'Z', '7',
  26. '7', 'Z', 'Z', 'Z']
  27. 单个字符识别正确率: 61.01%

单个字符识别率在60%左右的话,整体的识别率还是偏低的,肯定还有可以进行改进的地方,比如降噪这块,可以使用 8-连通 区域范围黑点的个数来进行更加合理的降噪。为了便于查看整个识别过程的步骤,我将单张验证码图片的识别单独写了一个函数。

  1. import os
  2. import pytesseract
  3. from PIL import Image
  4. import numpy as np
  5. from sklearn.externals import joblib
  6. from sklearn.neighbors import KNeighborsClassifier
  7. before = r"D:\MyProject\Python\ReturnVisit\auth_code\train\before\\" # 原始验证码图片目录
  8. after = r"D:\MyProject\Python\ReturnVisit\auth_code\train\after\\" # 处理后验证码图片目录
  9. cutting = r"D:\MyProject\Python\ReturnVisit\auth_code\train\cutting\\" # 切割后的图片目录
  10. def single_picture_recognize(model, image_path): # 单张验证码图片识别
  11. # 灰度处理
  12. img = Image.open(image_path)
  13. threshold = 180 # 阈值
  14. w, h = img.size
  15. for x in range(w):
  16. for y in range(h):
  17. r, g, b = img.getpixel((x, y))
  18. if 190 <= r <= 255 and 170 <= g <= 255 and 0 <= b <= 140:
  19. img.putpixel((x, y), (0, 0, 0))
  20. if 0 <= r <= 90 and 210 <= g <= 255 and 0 <= b <= 90:
  21. img.putpixel((x, y), (0, 0, 0))
  22. img = img.convert('L').point([0] * threshold + [1] * (256 - threshold), '1')
  23. # 边缘噪点处理
  24. for x in range(0, img.size[0]):
  25. for y in range(0, img.size[1]):
  26. if x in [0, img.size[0] - 1] or y in [0, img.size[1] - 1]:
  27. img.putpixel((x, y), 255) # 将边缘全变为非黑的点(简单粗暴)
  28. img.save(image_path)
  29. # 降噪处理
  30. image = Image.open(image_path)
  31. two_value(image, 100)
  32. clear_noise(image)
  33. image.save(image_path)
  34. # 图片切割
  35. """
  36. :param img: image对象
  37. :param outDir: 切割图片输出目录
  38. :param count: 图片中有多少个图片
  39. :param p_w: 对切割地方多少像素内进行判断
  40. """
  41. img = Image.open(image_path)
  42. cutting_picture = []
  43. count = 4
  44. p_w = 3
  45. w, h = img.size
  46. pixdata = img.load()
  47. eachWidth = int(w / count) # 每个切割图片的宽度
  48. beforeX = 0
  49. for i in range(count):
  50. # temp_dir = file[i]
  51. allBCount = []
  52. nextXOri = (i + 1) * eachWidth
  53. for x in range(nextXOri - p_w, nextXOri + p_w):
  54. if x >= w:
  55. x = w - 1
  56. if x < 0:
  57. x = 0
  58. b_count = 0
  59. for y in range(h):
  60. if pixdata[x, y] == 0:
  61. b_count += 1
  62. allBCount.append({'x_pos': x, 'count': b_count})
  63. sort = sorted(allBCount, key=lambda e: e.get('count'))
  64. nextX = sort[0]['x_pos']
  65. box = (beforeX, 0, nextX, h)
  66. pix = np.asarray(img.crop(box).resize((13, 25), Image.ANTIALIAS))
  67. pix = pix.reshape(13 * 25)
  68. cutting_picture.append(pix)
  69. beforeX = nextX
  70. # 开始识别
  71. pre_list = np.asarray(cutting_picture)
  72. predict_list = list(model.predict(pre_list)) # 预测结果
  73. return predict_list
  74. if __name__ == '__main__':
  75. # train_model()
  76. model = joblib.load('recognize.model')
  77. image_path = r"D:\MyProject\Python\ReturnVisit\auth_code\test.png"
  78. predict_result = single_picture_recognize(model, image_path)
  79. print(predict_result)

识别输出结果如下:

  1. "D:\Program Files\Python36\python3.exe" D:/MyProject/Python/ReturnVisit/auth_code/verification_code_recognize.py
  2. ['Y', 'E', 'U', 'V']
  3. Process finished with exit code 0

原始图片为:

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/532187
推荐阅读
相关标签
  

闽ICP备14008679号