• ocr数据不够,怎么造数据


    1.确定特定字体类型;

    2.收集合适的图片作为背景

    3.在背景图上填写特定字体的字符内容

    1)字体无法确认时怎么办?

    方法一:可以将文本行裁剪出来去网站上确认,网站链接:字体识别-在线扫一扫图片找字体-搜字体!

    方法二:将文字输入到文档文件中,更换不同的字体,看是否与字体目标匹配;

    字体可以去网上下载,也可以在本机查找;本机的字体所在位置:

    个人用户字体文件:~/.local/share/fonts
    系统字体文件:/usr/share/fonts
    字体配置文件:/etc/fonts/

    下面是我处理的代码,仅供参考:

    1. def check_dir1(path):
    2. if not os.path.exists(path):
    3. os.mkdir(path)
    4. else:
    5. files = os.listdir(path)
    6. for file in files:
    7. file_path = os.path.join(path, file)
    8. os.remove(file_path)
    1. '''
    2. 制作一些文本行数据
    3. '''
    4. from PIL import ImageFont, ImageDraw
    5. import PIL.Image as PImage
    6. import random
    7. import os
    8. import numpy as np
    9. import cv2
    10. from rec.temporary_boundary.line_process import cut_line3_1
    11. from result_process.preprocess import check_dir1
    12. if __name__=='__main__':
    13. cha_list = ['A','B','C','D','E','F','G','H','I','J','K',\
    14. 'L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']
    15. save_dir = '/home/fuxueping/4tdisk/data/certificate_reader/北京现场测试数据/20240614针对识别问题/SAU_name'
    16. check_dir1(save_dir)
    17. txt_parh = '/home/fuxueping/4tdisk/data/certificate_reader/北京现场测试数据/20240614针对识别问题/SAU_name.txt'
    18. bg_img_dir = '/home/fuxueping/4tdisk/data/certificate_reader/北京现场测试数据/20240614针对识别问题/bg'
    19. bg_imgs = os.listdir(bg_img_dir)
    20. f_save = open(txt_parh, 'w', encoding='utf-8')
    21. check_dir1(save_dir)
    22. num = 50
    23. while num:
    24. all_num = 0
    25. bg_img = random.choice(bg_imgs)
    26. num1=random.choice([2, 3])
    27. chr_str = ''
    28. all_num += num1
    29. while num1:
    30. chr_ = random.choice(cha_list)
    31. chr_str += chr_
    32. num1 -=1
    33. char_med = ''
    34. for i in range(3):
    35. num2=random.choice([5,6,7,8])
    36. chr_str2=''
    37. all_num += num2
    38. while num2:
    39. chr_ = random.choice(cha_list)
    40. chr_str2 += chr_
    41. num2 -= 1
    42. if i == 0:
    43. char_med += chr_str2+', '
    44. elif i == 1:
    45. char_med += chr_str2 + ' '
    46. elif i == 2:
    47. char_med += chr_str2 + ' '
    48. chr_1 = random.choice(cha_list)
    49. result_str = chr_str+' '+char_med+chr_1
    50. all_num += 1
    51. im = PImage.open(os.path.join(bg_img_dir, bg_img))
    52. w, h = im.size
    53. font_size = 24
    54. w_len = int(0 + all_num * (font_size-3) + 4)
    55. if w_len > w:
    56. num -= 1
    57. continue
    58. name_font = ImageFont.truetype('/home/fuxueping/4tdisk/data/certificate_reader/北京现场测试数据/20240614针对识别问题/fonts/n019003l.pfb', font_size)
    59. draw = ImageDraw.Draw(im)
    60. y_len = random.randint(0, h-font_size-5)
    61. color = tuple([random.randint(0, 20) for _ in range(3)])
    62. draw.text((2, y_len), result_str, fill=color, font=name_font)
    63. box = (0, y_len, w_len, y_len+font_size+5)
    64. rect_img = im.crop(box)
    65. image_array = np.array(rect_img)
    66. cv2_image = cv2.cvtColor(image_array, cv2.COLOR_RGB2BGR)
    67. result, _ = cut_line3_1(cv2_image)
    68. if len(result):
    69. region_rec = cv2_image[result[1]:result[3], result[0]:min(w, result[2]+2)] # 裁剪出待识别的区域
    70. image_array = cv2.cvtColor(region_rec, cv2.COLOR_BGR2RGB)
    71. rect_img = PImage.fromarray(image_array)
    72. # image_array = cv2.cvtColor(cv2_image, cv2.COLOR_BGR2RGB)
    73. # rect_img = PImage.fromarray(image_array)
    74. save_path = os.path.join(save_dir, str(num)+'_'+result_str+'.jpg')
    75. line = save_path+'\t'+result_str+'\n'
    76. f_save.write(line)
    77. rect_img.save(save_path)
    78. num -= 1
    79. f_save.close()
    1. # 根据设定的阈值和图片直方图,找出波峰,用于分隔字符
    2. def find_waves_row(threshold, histogram):#行数是59
    3. # up_point = -1 # 上升点
    4. # is_peak = False
    5. # if histogram[0] >= threshold:
    6. up_point = 0 #起始位置
    7. is_peak = True
    8. wave_peaks = []
    9. top_cut = []
    10. for i, x in enumerate(histogram): #x是对应的像素和,i是行
    11. if is_peak and x >= threshold:
    12. if i - up_point >=2 :
    13. # top_cut.append((up_point, i)) #加这一行,相当于裁减掉多于的空行
    14. up_point = i-1
    15. else:
    16. up_point = i
    17. is_peak = False
    18. elif not is_peak and x < threshold:#随后找到字符消失的位置
    19. is_peak = True
    20. if 1 < i < histogram.shape[0]-1:#行数不是在开头也不在结尾
    21. wave_peaks.append((up_point, i+1))
    22. else:
    23. wave_peaks.append((up_point, i))
    24. up_point = i
    25. # if is_peak and up_point != -1 and i - up_point > 4:
    26. # wave_peaks.append((up_point, i))
    27. if not is_peak and x >= threshold:#虽然数据已经结束,但是没有出现小于阈值的情况
    28. wave_peaks.append((up_point, i))
    29. return wave_peaks
    30. def cut_line3_1(rgb_img, kernel_size = 3, y_len = 5, row_threshold=255 * 1, col_thresh = 255*1):
    31. '''
    32. 切割出每一行,只保留高度满足条件的一行内容,然后切除掉每一行的前端后尾端的空白
    33. '''
    34. rgb_img = method_9(rgb_img) #高斯滤波
    35. # 使用sauvola进行二值化
    36. h, w = rgb_img.shape[:2]
    37. sau_bin = sauvola_bin(rgb_img) #sauvola二值化
    38. # cv2.imwrite('./../temp/sauvola_bin.jpg', sau_bin)
    39. # sau_bin = get_charcter_region(rgb_img) # 局部区域算阈值二值化
    40. # cv2.imwrite('./../temp/sau_bin1.jpg', sau_bin)
    41. sau_bin_inv = 255 - sau_bin
    42. # cv2.imwrite('./../temp/sau_bin_inv1.jpg', sau_bin_inv)
    43. if kernel_size != 0:
    44. sau_bin_inv = cv2.medianBlur(sau_bin_inv, kernel_size)
    45. # cv2.imwrite('./../temp/sau_bin_inv_dinose1.jpg', sau_bin_inv)
    46. col_histogram = np.sum(sau_bin_inv, axis=1)
    47. wave_peaks = find_waves_row(col_thresh, col_histogram)
    48. result = []
    49. #找出高度最大的区域,只保留一行内容
    50. max_y = 0
    51. result_y = []
    52. if not len(wave_peaks):
    53. return [], sau_bin_inv
    54. for i, wave_peak in enumerate(wave_peaks):
    55. y1 = wave_peak[0]
    56. y2 = wave_peak[1]
    57. if y2 - y1 < y_len: #20之前是这个阈值 ,将高度不满足>=5的字符区域去掉
    58. continue
    59. if max_y < y2 - y1:
    60. max_y = y2 - y1
    61. result_y = [y1, y2]
    62. if len(result_y): #有时候裁剪的图片可能是没有字符,这种情况多出现在证件类别错误的情况
    63. y1 = result_y[0]
    64. y2 = result_y[1]
    65. else:
    66. return [], sau_bin_inv
    67. line_img = sau_bin_inv[y1:y2, :]
    68. # line_img_bgr = rgb_img[wave_peak[0]:wave_peak[1], :]
    69. # save_other = os.path.join(save_path, file + '_'+str(i)+'.jpg')
    70. # cv2.imwrite(save_other, line_img)
    71. row_histogram = np.sum(line_img, axis=0) # 数组的每一列求和
    72. # row_max = np.max(row_histogram)
    73. # row_threshold = row_max - 255*1
    74. wave_peaks_line = find_waves_col(row_threshold, row_histogram)
    75. # cv2.imwrite('./../temp/line_img.jpg', line_img)
    76. x1 = 0
    77. x2 = w
    78. result_ = []
    79. for wave_ in wave_peaks_line:
    80. len_x = wave_[1] - wave_[0]
    81. if len_x > 5:
    82. result_.append(wave_)
    83. if len(result_): # 有时候朝水平投影内容消失了,就用【0,w】代替
    84. x1 = result_[0][0]
    85. x2 = result_[-1][1]
    86. return [x1, y1, x2, y2], sau_bin_inv

  • 相关阅读:
    C++之修改结构体成员字节对齐(二百一十三)
    【趣味实践】自动补帧算法——RIFE的使用
    安全与加密常识(5)自签名证书
    C++语法——make_heap、push_heap、pop_heap、sort_heap使用介绍
    PAT 1066 AVL树模板
    Web3 游戏周报(3.24-3.30)
    操作服务器的神奇工具Tmux
    代码随想录算法训练营第三天| LeetCode ● 203.移除链表元素 ● 707.设计链表 ● 206.反转链表
    赴日IT必备!日本技术人文签证怎么拿?
    Web安全总结
  • 原文地址:https://blog.csdn.net/qq_22764813/article/details/139825639