哈工大人工智能暑期课实践项目——手写体识别四则运算

 

一、项目介绍

手写数字识别增强版。 在 MNist示例程序 的基础上进一步扩展, 

阶段要求:

  1. 能实现多个数字的手写体识别
  2. 能实现加减乘除符号的识别
  3. 能做一个手写体识别四则运算的APP (可以是网页服务或手机App)

    对此,我们延续 MNist示例程序中使用的模型,将mnist数据集进行扩充,添加了'+', '-', '*', '/', '(', ')'这些符号数据,这通过鼠标手写的人工数据构成。另外,我们修改了使用的CNN中一些参数,包括input,epoch, optimizer等。主要使用的是python以及相应的tensorflow, cv2. PIL等库,最后通过django进行网页制作,简单制作了一个网页版的小画板,将鼠标手写的公式传达至后端进行处理之后,将识别出的公式以及计算结果传至前端。从而实现了一个简约而不简单的手写体识别四则运算的网页。

项目的github地址为:https://github.com/Godforever/ms

小组成员为: 周雄, 钟宏宇, 杨帆, 吴沛刚

注:使用python环境是python3, 需要安装的库包括django, sklearn, tensorfow, cv2,还有一个tqdm(进度条库)。

二、项目实现

1. 数据获取与处理

    结合mnist数据集和人工手写扩充的符号集,作为训练数据和测试数据。由于没有现成的手写符号数据集, 人工手写符号的过程是相当的痛苦的,(唉,允悲!),这里是我们人工手写的数据集并经过标准化处理之后的,点这里!0.0。密码: jods

    对于原始输入的数据集,我们采用连通域算法进行图片切割,当然这有个弊端就是我们手写的公式不能连在一起,对于'÷'这个特殊符号,我们特地进行了一些额外的处理。这个算法也会在处理包含公式的图片中用到,下面是连通域算法的主要代码:

def get_x_y_cuts(data, n_lines=1):
    // 获取各个小图像的位置范围
    w, h = data.shape
    visited = set()
    q = queue.Queue()
    offset = [(-1, -1), (0, -1), (1, -1), (-1, 0), (1, 0), (-1, 1), (0, 1), (1, 1)]
    cuts = []
    for y in range(h):
        for x in range(w):
            x_axis = []
            y_axis = []
            if data[x][y] < 200 and (x, y) not in visited:
                q.put((x, y))
                visited.add((x, y))
            while not q.empty():
                x_p, y_p = q.get()
                for x_offset, y_offset in offset:
                    x_c, y_c = x_p + x_offset, y_p + y_offset
                    if (x_c, y_c) in visited:
                        continue
                    visited.add((x_c, y_c))
                    try:
                        if data[x_c][y_c] < 200:
                            q.put((x_c, y_c))
                            x_axis.append(x_c)
                            y_axis.append(y_c)
                    except:
                        pass
            if x_axis:
                min_x, max_x = min(x_axis), max(x_axis)
                min_y, max_y = min(y_axis), max(y_axis)
                if max_x - min_x > 3 and max_y - min_y > 3:
                    cuts.append([min_x, max_x + 1, min_y, max_y + 1])
    if n_lines == 1:
        cuts = sorted(cuts, key=lambda x: x[2])
        pr_item = cuts[0]
        count = 1
        len_cuts = len(cuts)
        new_cuts = [cuts[0]]
        pr_k = 0
        for i in range(1, len_cuts):
            pr_item = new_cuts[pr_k]
            now_item = cuts[i]
            if not (now_item[2] > pr_item[3]):
                new_cuts[pr_k][0] = min(pr_item[0], now_item[0])
                new_cuts[pr_k][1] = max(pr_item[1], now_item[1])
                new_cuts[pr_k][2] = min(pr_item[2], now_item[2])
                new_cuts[pr_k][3] = max(pr_item[3], now_item[3])
            else:
                new_cuts.append(now_item)
                pr_k += 1
        cuts = new_cuts
    return cuts

def get_image_cuts(image, dir=None, is_data=False, n_lines=1, data_needed=False, count=0):
    if is_data:
        data = image
    else:
        data = cv2.imread(image, 2)
    cuts = get_x_y_cuts(data, n_lines=n_lines)
    image_cuts = None
    for i, item in enumerate(cuts):
        count += 1
        max_dim = max(item[1] - item[0], item[3] - item[2])
        new_data = np.ones((int(1.4 * max_dim), int(1.4 * max_dim))) * 255
        x_min, x_max = (max_dim - item[1] + item[0]) // 2, (max_dim - 
  • 11
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值