• 识别验证码:寻找数字的位置(三)


    1 没有意料的的问题

    上回通过机器学习算法已经能够很好地找到那些图片里完整地存在数字,选择出这张图片有助于下一步识别图片中的数字,如果数字包含得都不完整,就不用说识别图片里的数字了。

    红色边框表示算法判断存在数字

    正如人有时很难在一小片图片中判断哪个图片里的数字最完整,算法会找到一小片包含数字的小方块,这些小方块都是彼此相邻的。因此下一步要做的事就是把一片判断包含数字的小方块组成一个组。

    2 组成一组

    必须保证是自左向右地去寻找,这样才能保证验证码里数字的顺序不会错乱。

    def groupParts(predicted):
        """Assume predicted a boolean 2D array of representing a rectangle
        Group: area made up of adjacent Trues values
        Groups: all the group finding from left to the right"""
        partShape = predicted.shape
        looked = np.zeros(partShape,dtype=bool)
        nexts = [(1,0),(0,1),(-1,0),(0,-1)]
        groups = []
        for l in range(partShape[1]):
            for c in range(partShape[0]):
                if not looked[c,l]:
                    looked[c,l] = True
                    if predicted[c,l]:
                        group = []
                        fifo = [(c,l)]
                        while len(fifo)!=0:
                            tmp = fifo.pop(0)
                            looked[tmp[0],tmp[1]] = True
                            if predicted[tmp[0],tmp[1]]:
                                group.append((tmp[0],tmp[1]))
                                for n in nexts:
                                    nextPos = (n[0]+tmp[0],n[1]+tmp[1])
                                    if 0<=nextPos[0]<partShape[0] and 0<=nextPos[1]<partShape[1]:
                                        if not looked[nextPos[0],nextPos[1]]:
                                            looked[nextPos[0],nextPos[1]] = True
                                            fifo.append(nextPos)
                        groups.append(group)
        return groups
    

     写得非常糟糕的一段程序。思路大致是这样的,在没有找到存在数字的小方块时,从左向右一列一列地寻找。查看过的小方块在looked数组里标记,以免重复查看。

    一旦找到了存在数字的小方块,将上下左右的小方块保存在待查看的fifo列表里,每一次循环弹出一个小方块查看,如果包含数字就加入group列表,同时将上下左右的小方块保存在待查看的列表里,直至fifo为空。借鉴了一下图的广度优先搜索。

    结果会是这样的:

    Group 1:[(5, 3), (6, 3), (7, 3), (8, 3), (7, 4)]

    Group 2:[(4, 8), (5, 8), (6, 8), (5, 9), (6, 9)]

    Group 3:[(2, 13), (3, 13), (4, 13), (5, 13), (4, 14)]

    Group 4:[(8, 13)]

    Group 5:[(3, 18), (4, 18), (5, 18), (6, 18)]

    Group 6:[(0, 23), (1, 23), (2, 23), (3, 23), (4, 23), (5, 23)]

    3 对付误判

    预测的算法精度不够,通常有一些误判,这样组Group有可能超过验证码数字的个数5。解决办法很简单,真正包含数字的组一般长度更长,找到长度最长的5个组就可以了。又是一段nasty的代码。

        groups = groupParts(partImgs,predict_contain.reshape(img.partNum))
        num_threshold = sorted(map(len,groups),reverse=True)[4]
        groups_filtered = filter(lambda x:len(x)>=num_threshold,groups)
    

    一组相互毗邻的小方块代表一个数字,可以简单地选择出现最多的数字(众数),作为预测的结果。

  • 相关阅读:
    jenkins免密添加SSH Servers
    Workman启动失败的解决方法 stream_socket_server() has been disabled for security reasons
    jenkins主从从服务器发布脚本执行成功但总提示失败 FATAL: Remote call on XXXX failed
    mac OS配置用户全局环境变量(设置字符集为UTF8)
    使用 Application Loader提交IPA文件到苹果市场
    IOS使用批处理打包
    Java进阶知识24 Spring对JDBC的支持
    Java进阶知识23 Spring execution 切入点表达式
    Java进阶知识22 Spring的AOP编程
    Java进阶知识21 Spring的代理模式
  • 原文地址:https://www.cnblogs.com/meelo/p/4316746.html
Copyright © 2020-2023  润新知