CharDataSimulation

1. 图片生成

利用电脑中字体文件生成a-z 字符图片数据。

# 测试文件
from PIL import Image, ImageDraw, ImageFont, ImageFilter
import random
import matplotlib.pyplot as plt
import numpy as np
import os
# 随机字母:
def rndChar():
    return chr(random.randint(65, 90))
# 随机颜色1:
def rndColor():
    return (random.randint(64, 255), random.randint(64, 255), random.randint(64, 255))
# 随机颜色2:
def rndColor2():
    return (random.randint(32, 127), random.randint(32, 127), random.randint(32, 127))

letters='abcdefghiJKLmnopqrstuvwxyzCFIJKLOPSUVWXYZ'
str = [letters[i] for i in range(0,len(letters))]
num = len(str)
print(letters,num)
width = 64*num
height = 64
step_size = 64
for file in os.listdir('C:/windows/fonts/'):
    try:
        tmp=os.path.join('C:/windows/fonts/',file)
        print(tmp)
        # 创建Image
        image = Image.new('RGB', (width, height), (255, 255, 255))
        #选择字体
        font = ImageFont.truetype(tmp, 80)
        # 创建Font对象:
        # 创建Draw对象:
        draw = ImageDraw.Draw(image)
        # 输出文字:
        for t in range(num):
            draw.text((step_size * t, 0), str[t], font=font, fill=(0,0,0))
        # 模糊:
        # image = image.filter(ImageFilter.BLUR)
        image.save("./png/"+file+'.jpg','jpeg')
    except Exception as err:
        pass
# 生成原始数据集
from PIL import Image, ImageDraw, ImageFont, ImageFilter
import random
import matplotlib.pyplot as plt
import numpy as np
import os

#数据集根目录
rootpath="./data/"
#windows上字体文件路径
fontpath='C:/windows/fonts/'
#图片旋转角度
rotateAngel=[-20,-15,-10,-5,5,10,15,20]
#生成图片大小
width = 96
height = 96
#需要生成得字体字符  abcdefghIJkLmnopqrstUVWxYZ
letters='w'
CharData = [letters[i] for i in range(0,len(letters))]

# 黑色,用户显示字体
def blackColor():
    return (0,0,0)

# 根据data数据生成目录文件,data=[a,b,c,d,] 这种字符数列
def mkdir_for_imgs(data):
    for tm in data:
        if os.path.isdir(rootpath+tm):
            pass
        else:
            print(rootpath+tm)
            os.makedirs(rootpath+tm)


#罗列和手势分开字符比较相似的不同font 名称
def getFontList(fontpath):
    listfontnames=os.listdir(fontpath)
    return [name[:-4] for name in listfontnames]
#电脑上总共有663个字体返回的有效字体199个  ['50416___.TTF', '65659___.TTF', '75678___.TTF', '75749___.TTF', 'AGENCYR.TTF', 'ANTQUAB.TTF', 'ANTQUABI.TTF', 'ANTQUAI.TTF', 'arial.ttf', 'ariali.ttf', 'ARIALN.TTF', 'ARIALNB.TTF', 'ARIALNBI.TTF', 'ARIALNI.TTF', 'ARIALUNI.TTF', 'bahnschrift.ttf', 'BASKVILL.TTF', 'BELL.TTF', 'BELLB.TTF', 'BELLI.TTF', 'BKANT.TTF', 'BOD_B.TTF', 'BOD_BI.TTF', 'BOD_CI.TTF', 'BOD_I.TTF', 'BOD_R.TTF', 'BOOKOS.TTF', 'BOOKOSI.TTF', 'BRADHITC.TTF', 'calibri.ttf', 'calibrib.ttf', 'calibrii.ttf', 'calibril.ttf', 'calibrili.ttf', 'CALIFI.TTF', 'CALIFR.TTF', 'CALIST.TTF', 'CALISTB.TTF', 'CALISTBI.TTF', 'CALISTI.TTF', 'cambriai.ttf', 'Candara.ttf', 'Candarab.ttf', 'Candarai.ttf', 'Candaral.ttf', 'Candarali.ttf', 'Candaraz.ttf', 'CENSCBK.TTF', 'CENTAUR.TTF', 'CENTURY.TTF', 'comic.ttf', 'comici.ttf', 'comicz.ttf', 'consola.ttf', 'consolab.ttf', 'consolai.ttf', 'consolaz.ttf', 'constan.ttf', 'constanb.ttf', 'constani.ttf', 'corbel.ttf', 'corbelb.ttf', 'corbeli.ttf', 'corbell.ttf', 'corbelli.ttf', 'cour.ttf', 'courbd.ttf', 'courbi.ttf', 'couri.ttf', 'Deng.ttf', 'Dengb.ttf', 'Dengl.ttf', 'DUBAI-LIGHT.TTF', 'DUBAI-MEDIUM.TTF', 'DUBAI-REGULAR.TTF', 'ebrima.ttf', 'ebrimabd.ttf', 'ERASDEMI.TTF', 'ERASLGHT.TTF', 'ERASMD.TTF', 'FRABK.TTF', 'FRABKIT.TTF', 'FRADMCN.TTF', 'FRADMIT.TTF', 'FRAMDCN.TTF', 'framdit.ttf', 'FREESCPT.TTF', 'FTLTLT.TTF', 'FZSTK.TTF', 'FZYTK.TTF', 'Gabriola.ttf', 'GARA.TTF', 'GARABD.TTF', 'GARAIT.TTF', 'georgia.ttf', 'georgiai.ttf', 'GILC____.TTF', 'GILI____.TTF', 'GIL_____.TTF', 'GLECB.TTF', 'GOTHICI.TTF', 'GOUDOS.TTF', 'GOUDOSI.TTF', 'himalaya.ttf', 'HTOWERT.TTF', 'HTOWERTI.TTF', 'INFROMAN.TTF', 'Inkfree.ttf', 'LBRITED.TTF', 'LBRITEDI.TTF', 'LBRITEI.TTF', 'LEELAWAD.TTF', 'LEELAWDB.TTF', 'LeelawUI.ttf', 'LeelUIsl.ttf', 'LFAX.TTF', 'LFAXD.TTF', 'LFAXI.TTF', 'LSANSDI.TTF', 'LSANSI.TTF', 'LTYPE.TTF', 'LTYPEB.TTF', 'LTYPEBO.TTF', 'LTYPEO.TTF', 'lucon.ttf', 'MAIAN.TTF', 'malgun.ttf', 'malgunbd.ttf', 'malgunsl.ttf', 'mingliub.ttc', 'mmrtext.ttf', 'MOD20.TTF', 'monbaiti.ttf', 'msgothic.ttc', 'msjh.ttc', 'msjhl.ttc', 'MSUIGHUB.TTF', 'MSUIGHUR.TTF', 'msyhl.ttc', 'msyi.ttf', 'Nirmala.ttf', 'NirmalaS.ttf', 'ntailu.ttf', 'OCRAEXT.TTF', 'palabi.ttf', 'palai.ttf', 'PERI____.TTF', 'PER_____.TTF', 'phagspa.ttf', 'REFSAN.TTF', 'ROCKI.TTF', 'SCHLBKI.TTF', 'segoeuii.ttf', 'segoeuil.ttf', 'segoeuisl.ttf', 'seguiemj.ttf', 'seguihis.ttf', 'seguili.ttf', 'seguisb.ttf', 'seguisbi.ttf', 'seguisli.ttf', 'seguisym.ttf', 'simfang.ttf', 'simhei.ttf', 'simkai.ttf', 'SIMLI.TTF', 'simsun.ttc', 'simsunb.ttf', 'SIMYOU.TTF', 'Sitka.ttc', 'SitkaI.ttc', 'STFANGSO.TTF', 'STKAITI.TTF', 'STSONG.TTF', 'STXINWEI.TTF', 'STZHONGS.TTF', 'sylfaen.ttf', 'tahoma.ttf', 'taile.ttf', 'TCCM____.TTF', 'TCMI____.TTF', 'TCM_____.TTF', 'times.ttf', 'timesbi.ttf', 'timesi.ttf', 'trebucit.ttf', 'tt0142m_.ttf', 'tt0143m_.ttf', 'tt0200m_.ttf', 'tt0372m_.ttf', 'tt0395m_.ttf', 'tt0849m_.ttf', 'TT1139M_.TTF', 'tt2002m_.ttf', 'verdana.ttf', 'verdanai.ttf', 'YuGothL.ttc', 'YuGothM.ttc', 'YuGothR.ttc']

#fontname: 字体得名称
# chardata: 需要生成图片的字符
# picturename: 生成图片的名字
#outputdir: 生成图片存储目录
# 字符居中,生成单张图片
def generateBlackPicuture(fontname,chardata,picturename,outputdir):
    try:
        fullfontpath=os.path.join(fontpath,fontname)
        # 创建Image
        image = Image.new('RGB', (width, height), (255, 255, 255))
        #选择字体
        font = ImageFont.truetype(fullfontpath, 80)
        # 创建Font对象:
        # 创建Draw对象:
        draw = ImageDraw.Draw(image)
        #设置字体居中对齐
        imwidth, imheight = image.size
        font_width, font_height = draw.textsize(chardata, font)
        draw.text(((imwidth - font_width-font.getoffset(chardata)[0]) / 2, (imheight - font_height-font.getoffset(chardata)[1]) / 2),chardata,font=font,fill=blackColor())
        #image = image.filter(ImageFilter.BLUR)
        image.save(os.path.join(outputdir,picturename+'.png'))  
        #进行旋转操作并进行处理
       # rotateImage(outputdir,picturename+'.png',outputdir)

        # 模糊:
        # image = image.filter(ImageFilter.BLUR)
    except Exception as err:
        pass
   
#图片旋转操作
#inputdir: the inputdir of dataset
#filename: the name of picture to handle
# outputdir: the name of outputdir to save rotated file
def rotateImage(inputdir,filename,outputdir):
    # original image 
    img = Image.open(os.path.join(inputdir,filename))
    # converted to have an alpha layer 
    im2 = img.convert('RGBA') 
    for i in range(0,24,8):
        savepath=os.path.join(outputdir,filename+str(i) +'.png')
        # rotated image 
        rot = im2.rotate(i, expand=1) 
        # a white image same size as rotated image 
        fff = Image.new('RGBA', rot.size, (255,)*4) 
        # create a composite image using the alpha layer of rot as a mask 
        out = Image.composite(rot, fff, rot) 
        out=out.resize((96,96),Image.ANTIALIAS)
        # save your work (converting back to mode='1' or whatever..) 
        out.convert(img.mode).save(savepath) 
    for i in range(336,360,8):
        savepath=os.path.join(outputdir,filename+str(i)+'.png')
            # rotated image 
        rot = im2.rotate(i, expand=1) 
        # a white image same size as rotated image 
        fff = Image.new('RGBA', rot.size, (255,)*4) 
        # create a composite image using the alpha layer of rot as a mask 
        out = Image.composite(rot, fff, rot) 
        out=out.resize((96,96),Image.ANTIALIAS)
        # save your work (converting back to mode='1' or whatever..) 
        out.convert(img.mode).save(savepath) 
#生成单个字符数据集
# charname: 字符名称
#charnamedir: 字符数据集存储对应的文件夹目录
def generateSingleCharDataset(charname,charnamedir):
    for fonttemp in getFontList("./png"):
        generateBlackPicuture(fonttemp,charname,fonttemp.split('.')[0],charnamedir)

#生成所有字符数据集
def generateAlldata():
    mkdir_for_imgs(CharData)
    for charname in CharData:
        generateSingleCharDataset(charname,os.path.join(rootpath,charname))

def generateAllRotatePicture(rootdir):
    for dirname in os.listdir(rootdir):
        tempdir=os.path.join(rootdir,dirname)
        filenames=os.listdir(tempdir)
        for filename in filenames:
            rotateImage(tempdir,filename,tempdir)


if __name__ == "__main__":
   #generateAllRotatePicture("./data/")
   generateAlldata()

2. label generate

读取标注xml文件,绘制label 图像文件。

import xml.etree.ElementTree as ET
import os
import sys
from xml.dom.minidom import parse
import numpy as np
import cv2
def readPointXML(filepath):
    domTree = parse(filepath)
    # 文档根元素
    rootNode = domTree.documentElement
    objects = rootNode.getElementsByTagName("object")
    #print("objects=",objects)
    point=[]
    for item in objects:
        bndboxs=item.getElementsByTagName('bndbox')
        #print("bndbox",bndboxs)
        if bndboxs and len(bndboxs)>0:
            xmin=(int)(bndboxs[0].getElementsByTagName("xmin")[0].firstChild.data)
            ymin=(int)(bndboxs[0].getElementsByTagName("ymin")[0].firstChild.data)
            xmax=(int)(bndboxs[0].getElementsByTagName("xmax")[0].firstChild.data)
            ymax=(int)(bndboxs[0].getElementsByTagName("ymax")[0].firstChild.data)
            point.append((int((xmin+xmax)/2),int((ymin+ymax)/2)))
    return point

def dealsingleImage():
    points=readPointXML('./calibrili.xml')
    print(points)
    temp=np.zeros([96,96,3])
    for point in points:
        temp[point[1],point[0]]=[255,255,255]
    cv2.imwrite("11.png",temp)
    
#path="H:\chardigitDataset\mnist\characterdigit\codes\data\xtfk\train\data\\"  saverootdir="H:\chardigitDataset\mnist\characterdigit\codes\data\xtfk\train\label"
def generateLabel(path,saverootdir):
    for charfoder in os.listdir(path):
        print(charfoder)
        tempfolder=os.path.join(path,charfoder)
        tempsavefolder=os.path.join(saverootdir,charfoder)
        if not os.path.exists(tempsavefolder):
             os.makedirs(tempsavefolder)
        for filename in os.listdir(tempfolder):
            if filename[-1]=="l":
                points=readPointXML(os.path.join(tempfolder,filename))
                temp=np.zeros([96,96,3])
                for point in points:
                    temp[point[1],point[0]]=[255,255,255]
                savefile=os.path.join(tempsavefolder,filename.split(".")[0]+".png")
                print(savefile)
                cv2.imwrite(savefile,temp)


if __name__ == "__main__":
    generateLabel("H:\\chardigitDataset\\mnist\\characterdigit\\codes\\data\\xtfk\\train\\data\\","H:\\chardigitDataset\\mnist\\characterdigit\\codes\\data\\xtfk\\train\\label\\")
    dealsingleImage()

针对k,t,x,f 这四个字符当提取出来关键点之后,使用一次函数将关键点连接

from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
import cv2
import os

#根据字符的特性,最上面点,最上面右边点, 根据y的距离大小 来过滤相邻的点

#可视化显示某张字符检测效果
def CornerPointDetectionTest(imgpath):
    img=cv2.imread(imgpath)
    gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    corners=cv2.goodFeaturesToTrack(gray,10,0.3,6)
    corners=np.int0(corners)
    corners=np.array([[i[0][0],i[0][1]] for i in corners])
    print(corners)
    corners=corners[corners[:,0].argsort()]
    print(corners)
    for x in corners:
        cv2.circle(img,(x[0],x[1]),2,255,-1)
    #cv2.circle(img,(4,8),2,255,-1)   图片左上角 (0,0), 行x,列y
    plt.imshow(img)
    plt.show()


def getCornerPoint(imgpath):
    img=cv2.imread(imgpath)
    gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    corners=cv2.goodFeaturesToTrack(gray,30,0.2,2)
    corners=np.int0(corners)
    corners=np.array([[i[0][0],i[0][1]] for i in corners])
    print("orgin",corners)
    pointA,pointB=[0,0],[0,0]
    temp=corners[corners[:,1].argsort()]
    ymin=temp[0][1]
    ymax=temp[len(temp)-1][1]
    steplen=(ymax-ymin)/3
    print("y order",temp,ymin,ymax,steplen)
    corners=corners[corners[:,0].argsort()][::-1]
    print("orderx",corners)
    a,b=-1,-1
    pointA=corners[0]

    temp=corners[corners[:,1].argsort()][::-1]
    corners=corners[corners[:,0].argsort()][::-1]
    pointT=corners[0]
    pointMiddle=[int((pointA[0]+pointT[0])/2),int((pointA[1]+pointT[1])/2)]
    for t in corners[1:]:
        if abs(t[1]-pointMiddle[1]) < steplen:
            pointB=t
            break
        # if t[1]>ymin-1 and t[1]<ymin+steplen and a==-1:
        #     pointA=t
        #     a=1
        # elif t[1]>=ymin+steplen and t[1]<ymin+2*steplen and b==-1:
        #     pointB=t
        #     b=1
        # else:
        #     pass
    return pointA,pointB

#曲线拟合为 y=ax+b
def handleCurve(rootdir,picpath):
    imgpath=os.path.join(rootdir,picpath)
    print(imgpath)
    corners=getCornerPoint(imgpath)
    img=cv2.imread(imgpath)
    print(corners[0],corners[1])
    #cv2.line(img,(corners[0][0],corners[0][1]),(corners[1][0],corners[1][1]),(255,255,255))   #(255,255,255)  白色
    pt=(corners[0][0],corners[1][1])
    tut=np.array([(corners[0][0],corners[0][1]),(pt[0]-1,pt[1]-2),(corners[1][0],corners[1][1])])
    tut=tut.reshape(-1,1,2)
    print(tut)
    cv2.polylines(img,[tut],False,(255,255,255))
    savepath="11"+picpath.split(".")[0]+".png"
    print(savepath)
    cv2.imwrite(savepath,img)
   
#处理一个目录文件夹文件
def handle(rootdir):
    templist=os.listdir(rootdir)
    for file in templist:
        try:
            handleCurve(rootdir,file)
        except Exception as err :
            print(err)


def calculateAB(pointA,pointB):
    a=(pointA[1]-pointB[1])/(pointA[0]-pointB[0])
    b=pointA[1]-a*pointA[0]
    return a,b



if __name__ == "__main__":
    #handle("H:\\chardigitDataset\\mnist\\characterdigit\\codes\\data\\Xihua\\k\\")
    #handleCurve("","./corbel.png")
    #print(getCornerPoint("./calibrili.png"))
    CornerPointDetectionTest("./calibrili.png")
#img=np.array(Image.open("./calibrili.png"))
#index=np.argwhere(img>1)
#print(index)
# plt.figure("lena")
# plt.imshow(img,cmap='gray')
# plt.axis('off')
# plt.show()

3. 图片旋转细化操作

from PIL import Image, ImageDraw, ImageFont, ImageFilter
import random
import matplotlib.pyplot as plt
import numpy as np
import os
import cv2
#图片旋转操作
#inputdir: the inputdir of dataset
#filename: the name of picture to handle
# outputdir: the name of outputdir to save rotated file
def rotateImage(inputdir,filename,outputdir):
    # original image 
    img = Image.open(os.path.join(inputdir,filename))
    # converted to have an alpha layer 
    im2 = img.convert('RGBA') 
    for i in range(0,17,8):
        savepath=os.path.join(outputdir,filename+"rot"+str(i) +'.png')
        # rotated image 
        rot = im2.rotate(i, expand=1) 
        # a white image same size as rotated image 
        fff = Image.new('RGBA', rot.size, (255,)*4) 
        # create a composite image using the alpha layer of rot as a mask 
        out = Image.composite(rot, fff, rot) 
        out=out.resize((96,96),Image.ANTIALIAS)
        # save your work (converting back to mode='1' or whatever..) 
        out.convert(img.mode).save(savepath) 
    for i in range(336,360,8):
        savepath=os.path.join(outputdir,filename+"rot"+str(i)+'.png')
            # rotated image 
        rot = im2.rotate(i, expand=1) 
        # a white image same size as rotated image 
        fff = Image.new('RGBA', rot.size, (255,)*4) 
        # create a composite image using the alpha layer of rot as a mask 
        out = Image.composite(rot, fff, rot) 
        out=out.resize((96,96),Image.ANTIALIAS)
        # save your work (converting back to mode='1' or whatever..) 
        out.convert(img.mode).save(savepath) 

def pictureExpand(imgfile, savefilename):
    try:
        img=cv2.imread(imgfile,0)
        kernels=[np.ones((2,2),np.uint8),np.ones((3,3),np.uint8)]
        j=0
        for i in [2,3]:
            for kernel in kernels:
                dilation=cv2.dilate(img,kernel,iterations=i)
                gray =255-dilation
                savefile=savefilename+str(j)+".png"
                print(savefile)
                cv2.imwrite(savefile,gray)
                j=j+1
    except Exception as err:
        print(err)
#处理单张图片
def handimage(inputpath,savepath):
    if inputpath.find(".png")==-1:
        return
    img=mpimg.imread(inputpath)
    img=color.rgb2gray(img)
    img=1-img
    # shape=img.shape
    # for i in range(0,shape[0]):
    #     for j in range(0,shape[1]):
    #         if img[i][j]<0.5:
    #             img[i][j]=0
    #         else:
    #             img[i][j]=1
    skeleton=morphology.skeletonize(img)
    imsave(savepath,  img_as_uint(skeleton))

4. 文件操作

#移动文件 folder 目录格式: data/a/1.xml, pathfromfolder:       
def moveFile():
    pathfromfolder="H:\\chardigitDataset\\mnist\\characterdigit\\codes\\data\\xtfk\\train\\label\\"
    savefromfolder="H:\\chardigitDataset\\mnist\\characterdigit\\codes\\data\\xtfk\\train\\data\\"
    sourcefolder="H:\\chardigitDataset\\mnist\\characterdigit\\codes\\data\\xtfk\\Xihua\\"
    # if not os.path.isdir(pathfromfolder):
    #     print("folder not exit")
    # if not os.path.isfile(pathtofolder):
    #     os.mkdirs(pathtofolder)
    for tmfoler in os.listdir(pathfromfolder):
        temppath=os.path.join(pathfromfolder,tmfoler)
        for filename in os.listdir(temppath):
            tmp=os.path.join(sourcefolder,tmfoler,filename)
            try:
                shutil.move(tmp,os.path.join(savefromfolder,tmfoler,filename))
            except Exception as err :
                print(tmp+" is not exit")

def dataSplit(sourcedir,targetdir):
    for tmfolder in os.listdir(sourcedir):
        sourcechardir=os.path.join(sourcedir,tmfolder)
        traindir=os.path.join(targetdir,"train",tmfolder)
        validdir=os.path.join(targetdir,"valid",tmfolder)
        testdir=os.path.join(targetdir,"test",tmfolder)
        print(sourcechardir)
        if not os.path.exists(traindir):
            os.makedirs(traindir)
        if not os.path.exists(validdir):
            os.makedirs(validdir)
        if not os.path.exists(testdir):
            os.makedirs(testdir)
        i=0
        for filename in os.listdir(sourcechardir):
            if i%10 ==9:
                shutil.move(os.path.join(sourcechardir,filename),os.path.join(testdir,filename))
            elif i%10<7:
                shutil.move(os.path.join(sourcechardir,filename),os.path.join(traindir,filename))
            else:
                shutil.move(os.path.join(sourcechardir,filename),os.path.join(validdir,filename))
            i=i+1
0%