简体   繁体   English

如何在 Python 中创建带有英文字母(AZ、az、0-9)的图像?

[英]How to create images with English alphabets (A-Z, a-z, 0-9) in Python?

I want to prepare a dataset for the recognition of English Alphanumeric characters.我想准备一个用于识别英文字母数字字符的数据集。 I want to train my Deep learning model to recognize the characters.我想训练我的深度学习 model 来识别字符。 Image size should be 32 * 32 or 28 * 28. And Characters should be scaled with the height and width of the Image.图像大小应为 32 * 32 或 28 * 28。字符应随图像的高度和宽度缩放。 Given below is the expected Output.下面给出的是预期的 Output。

Character "A" scaled with the Image用图像缩放的字符“A”

I have tried getsize() but I am not able to scale character with the image size.我试过 getsize() 但我无法用图像大小缩放字符。

from PIL import Image, ImageDraw, ImageFont
import os,glob
import numpy as np
import random

parentPath=r"CaptchaDataset\\"


charactersList=['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','0','1','2','3','4','5','6','7','8','9']
fontTypes=[]

for font in glob.glob("fonts\\*"): # Create Image for every font
    fontTypes.append(os.path.abspath(font))
    
for index,character in enumerate(charactersList):
    
    path=os.path.join(parentPath,character+"_"+str(index))
    os.mkdir(path)
    
    
    for imageCounter in range(len(fontTypes)):
        for repeats in range(3): #Number of Images
            img = Image.new('1', (28, 28), color = 'black')
            fnt = ImageFont.truetype(fontTypes[imageCounter], random.randint(30,50))
            w,h=fnt.getsize(character)
            d = ImageDraw.Draw(img)
            d.text(((28-w)/2-5,((28-h)/2)-5), character, font=fnt, fill=(255),align="center") #TO ALIGN CHARACTER IN CENTER
            img=np.pad(img,pad_width=10, mode='constant', constant_values=0) #Manually added padding
            img=Image.fromarray(img)
            img.save(path+"\\"+str(imageCounter)+"_"+str(repeats)+".jpg")

UnExpected Output of Above program.上述程序的意外 Output。 "g" is cropped “g”被裁剪

The solution is simple: Create the image after creating the font.解决方案很简单:创建字体后创建图像。

Instead of creating 28x28 pixels image, and drawing a character that may be larger than the image, create the font, get the size, and create the image according to the font's size.与其创建 28x28 像素的图像,并绘制一个可能比图像大的字符,不如创建字体,获取大小,然后根据字体大小创建图像。

  • Create the font, and get the font's size:创建字体,并获取字体的大小:

     fnt = ImageFont.truetype(fontTypes[imageCounter], random.randint(30, 50)) w, h = fnt.getsize(character)
  • Set image size according to font size and create the image:根据字体大小设置图像大小并创建图像:

     img_w, img_h = w + 20, h + 20 # Add 20 pixels padding (assume 10 pixels from each side). img = Image.new('L', (img_w, img_h), color='black') # Replace '1' with 'L' (8-bit pixels, black and white - we fill 255 so we can't use 1 bit per pixel)
  • Draw the character at the center of the image:在图像的中心绘制角色:

     d.text(((img_w-w)/2, (img_h-h)/2), character, font=fnt, fill=255, align="center") # TO ALIGN CHARACTER IN CENTER

Here is a complete (updated) code:这是一个完整的(更新的)代码:

from PIL import Image, ImageDraw, ImageFont
import os,glob
import numpy as np
import random

parentPath = "CaptchaDataset\\"

charactersList=['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','0','1','2','3','4','5','6','7','8','9']
fontTypes=[]

for font in glob.glob("fonts\\*"): # Create Image for every font
    fontTypes.append(os.path.abspath(font))
    
for index,character in enumerate(charactersList):    
    path = os.path.join(parentPath,character + "_" + str(index))

    if not os.path.exists(path):
        os.mkdir(path)
     
    for imageCounter in range(len(fontTypes)):
        for repeats in range(3): # Number of Images
            #img = Image.new('1', (28, 28), color = 'black')
            fnt = ImageFont.truetype(fontTypes[imageCounter], random.randint(30, 50))
            w, h = fnt.getsize(character)
            img_w, img_h = w + 20, h + 20  # Add 20 pixels padding (assume 10 pixels from each side).
            img = Image.new('L', (img_w, img_h), color='black')  # Replace '1' with 'L' (8-bit pixels, black and white - we fill 255 so we can't use 1 bit per pixel)
            d = ImageDraw.Draw(img)
            d.text(((img_w-w)/2, (img_h-h)/2), character, font=fnt, fill=255, align="center") # TO ALIGN CHARACTER IN CENTER
            #img = np.pad(img, pad_width=10, mode='constant', constant_values=0) #Manually added padding
            #img = Image.fromarray(img)
            img.save(path + "\\" + str(imageCounter) + "_" + str(repeats) + ".jpg")

Few sample results:少量样本结果:
在此处输入图像描述 在此处输入图像描述 在此处输入图像描述 在此处输入图像描述 在此处输入图像描述 在此处输入图像描述 在此处输入图像描述 在此处输入图像描述 在此处输入图像描述

在此处输入图像描述 在此处输入图像描述 在此处输入图像描述 在此处输入图像描述 在此处输入图像描述 在此处输入图像描述 在此处输入图像描述 在此处输入图像描述 在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM