colorfire 发表于 2013-2-7 09:34:21

自动登录脚本之图像识别

仅做个保留吧,等完成之后一起写。

import Image,ImageFont,ImageDrawimport os,sysfrom math import atan2,piimport pickleDURATION = 1000DIAMETER = 20COLORDIFF = 10TEXTCOLOR = (128,128,128)BACKGROUND = (255,255,255)MODE = 'sample'samples = Nonedef purifyIM(image):    frame = image.load()    (w,h)=image.size    for i in range(h):      for j in range(w):            if frame < TEXTCOLOR:                image.putpixel( (j,i), TEXTCOLOR )            else:                image.putpixel( (j,i), BACKGROUND )    return imagedef purify(region):    frame = region.getdata()    (w,h)=region.size    for i in range(h):      for j in range(w):            if frame != BACKGROUND and frame != (0,0,0):                region.putpixel( (j,i), TEXTCOLOR )            else:                region.putpixel( (j,i), BACKGROUND )    return regiondef printregion(region):    frame = region.getdata()    (w,h)=region.size    f = file('testCode2.txt','w')    for i in range(h):      for j in range(w):            if frame != BACKGROUND:                f.write('*')            else:                f.write(' ')      f.write('\n')    f.close()def getImage(fname):    im = Image.open(fname)    return imdef normalize(im):    regions = imdiv(im)    if len(regions)!=4:      regoins = imdiv2(im)    for k in range(len(regions)):      regions = dorotate(regions)      regions = purify( docrop(regions) )    return regionsdef dorotate(region):    deg = 0    maxdens = 0    for i in range(-30,31):      dens = density( docrop( region.rotate(i) ) )      if dens > maxdens:            deg = i            maxdens = dens    return region.rotate(deg)def density(region):    frame = region.getdata()    (w,h) = region.size    area_all = w*h    area = 0    for i in range(h):      for j in range(w):            if frame != BACKGROUND and frame != (0,0,0):                area += 1    return 1.0*area/area_alldef docrop(region):    croppos = getcrop(region)    newregion = region.crop(croppos)    return newregiondef getcrop(region):    frame = region.getdata()    (w,h)=region.size    pts = []    ptsi = []    for i in range(h):      for j in range(w):            if frame != BACKGROUND and frame != (0,0,0):                pts.append((i,j))                ptsi.append((j,i))    if pts == []:      return     pp1 = min(pts)    pp2 = max(pts)    pp3 = min(ptsi)    pp4 = max(ptsi)    return ,pp1,pp4+1,pp2+1]def crackcode(im):    global samples    if not samples:      samples = loadsamples()    regions = normalize(im)    s = []    ans = []    for r in regions:      s.append(match(r,samples).upper())    messup = ['TFY7','FE','38','72YT','CQGR6','G6C','XK','HK','89B','YV','VY']    for i in range(len(s)):      for mess in messup:            if s == mess:                s = mess    if len(s) != 4:      return ['failed']    else:      for s1 in s:            for s2 in s:                for s3 in s:                  for s4 in s:                        t = s1+s2+s3+s4                        ans.append(t)    return ansdef match(region,samples):    if samples == {}:      return None    dists = []    for (k,v) in samples.items():      dists.append( (distance(region,k),v) )    dists.sort()    if MODE == 'sample':      return dists    else:      i = 0      while dists in ['H','I']:            i += 1      return distsdef distance(r1,r2):    den1 = density(r1)    den2 = density(r2)    if 1.0*den1/den2>1:      (den1,den2) = (den2,den1)    r1 = r1.resize(r2.size)      d1 = r1.getdata()    d2 = r2.getdata()    same =     total =     for i in xrange(len(d1)):      if d1 != BACKGROUND:            total += 1            if d1 == d2:                same += 1      if d2 != BACKGROUND:            total += 1            if d1 == d2:                same += 1    return 1 - 1.0*same/total * 1.0*same/total * 1.0*den1/den2def loadsamples():    pks = pickle.load(open('samples.pk','rb'))    samples = {}    for (pk,v) in pks.items():      im = Image.new('RGB',pk)      r = im.crop((0,0,pk,pk))      r.fromstring(pk)      samples = v    return samplesdef loadttf():    files = [ 'ttf/'+x for x in os.listdir('ttf') ]    fonts = []    for f in files:      fonts.append( ImageFont.truetype(f,32) )    regions = []    regionsv = []    for font in fonts:      im = Image.new( 'RGB', (1000,50), BACKGROUND )      draw = ImageDraw.Draw(im)      draw.text((0,0),"B C E F G H J K M P Q R T V W X Y 2 3 4 6 7 8 9"\                ,font=font,fill=TEXTCOLOR )      regions.extend( imdiv(im) )      regionsv.extend( 'B C E F G H J K M P Q R T V W X Y 2 3 4 6 7 8 9'.split(' ') )    for i in xrange(len(regions)):      regions = docrop(regions)            printregion( regions )    kv = {}    for i in range(len(regions)):      kv] = regionsv    return kvdef imdiv(im):    frame = im.load()    (w,h) = im.size    horis =[]    for i in range(w):      for j in range(h):            if frame != BACKGROUND:                horis.append(i)                break    horis2 = -2,0)]    for i in range(1,len(horis)-1):      if horis!=horis-1:            horis2.append((horis+horis)/2)    horis2.append(min(horis[-1]+3,w))    boxes=[]    for i in range(len(horis2)-1):      boxes.append( ,0,horis2,h])    for k in range(len(boxes)):      verts = []      for j in range(h):            for i in range(boxes,boxes):                if frame != BACKGROUND:                  verts.append(j)      boxes = max(verts-2,0)      boxes = min(verts[-1]+3,h)    if boxes == []:      return None    regions = []    for box in boxes:      regions.append( im.crop(box) )    return regionsdef imdiv2(im):    divs = {}    frame = im.load()    (w,h) = im.size    for i in range(w):      for j in range(h):            color = frame            if color != BACKGROUND:                if divs.has_key( color ):                  divs[ color ].append( (i,j) )                else:                  divs[ color ] = [ (i,j) ]    regions = []    divs = [ (x,sorted(x,cmp=lambda x,y:cmp(x,y))) for x indivs.items() ]    divs.sort(cmp=lambda x,y:cmp(x,y))    for (color,pts) in divs:      xs = [ x for x in pts ]      ys = [ x for x in pts ]      box = ( min(xs), min(ys), min(max(xs)+1,w), min(max(ys)+1,h) )      regions.append(im.crop(box))    return regionsdef train(im):    print 1    global samples    try:      samples = pickle.load(open('samples.pk','rb'))    except:      samples = {}      pickle.dump(samples,open('samples.pk','wb'))    regions = normalize(im)    for region in regions:      printregion(region)      smps = loadsamples()      printframeBy(region)      print match(region,smps).upper()      print 'Enter to add to library: '      ans = raw_input()      if len(ans) == 1:            key = (region.size,region.tostring())            samples = ans            pickle.dump(samples,open('samples.pk','wb'))def printframeBy(im,code=-1):    frame = im.load()    (w,h) = im.size    for j in xrange(h):      for i in xrange(w):            if (code == -1 and frame !=BACKGROUND) or (code != -1 and frame==code) :                print '*',            else:                print ' ',      printdef identify(fname):    image = getImage(fname)    image = purifyIM(image)    regions = normalize(image)    ans = crackcode(image)    return ans    #printregion(regions)def trainBy(fname):    if sys.argv.startswith('train'):      trainfiles = os.listdir(sys.argv)      trainfiles.sort()      for trainfile in trainfiles:            trainfile = sys.argv+'/'+trainfile            print trainfile            im = getImage(trainfile)            im = purifyIM(im)            train(im)if __name__ == '__main__':    if len(sys.argv) == 2:      print "Run training"      trainBy('genimg3.jpg')    else:      print "Run indentify"      identify('genimg3.jpg')
页: [1]
查看完整版本: 自动登录脚本之图像识别