做实验的过程中往往需要记录数据,比如笔者有时需要测定上百个DNA样品的浓度,有时又需要去野外实验地记录田间数据,手写记录目前还是最可靠、最便捷、最有效的方法。但手写数据需要录入电脑进行数据分析,录入的过程往往相当繁琐,没有任何技术可言,那么如何让手写数据更快更高效地录入电脑,从而提高我们学习工作的效率呢?那么就让我们一起用python来解决这个问题吧。先看看效果:

图片预处理:

图片转成excel:

利用下面的python代码可以将每一张表格照片都转成了excel中的一个sheet,非常适合批量操作。不过手写数字识别难免会有一定的错误率,实验数据要求很高,因此不要偷懒,还是需要核对一遍的哈。下面我们介绍一下实现的思路和代码

1.实现思路        

首先,我们面临的问题就是如何识别手写数字,难道我还要从机器学习开始一步步学习然后才能实现?CSDN上有很多介绍用TensorFlow框架进行手写识别的教程,感兴趣的同学可以深入研究。但此处我们直接调用科大讯飞人工智能开放平台的手写识别API来实现手写识别(
https://www.xfyun.cn/service/wordRecghttps://www.xfyun.cn/service/wordRecg),手写识别的问题就解决了 。然后,我们将识别的结果进行定位,再利用python写入excel表格即可。

2.实现代码

该代码会调用科大讯飞手写识别的webAPI,需要用户名和密码,可以自行前往科大讯飞官网购买相应服务。如何想直接使用笔者打包好的代码,可参考文章配套的付费资源链接哈(https://download.csdn.net/download/weixin_43367441/79581415https://download.csdn.net/download/weixin_43367441/79581415),下载相应的模板进行实验记录,并用笔者提供的程序批量录入数据即可。

# -*- coding: utf-8 -*-
import cv2
import numpy as np
import base64
import hashlib
import time
import requests
import json
import xlsxwriter
from PIL import Image
import os
import sys
"""手写文字识别WebAPI接口调用示例接口文档(必看):https://doc.xfyun.cn/rest_api/%E6%89%8B%E5%86%99%E6%96%87%E5%AD%97%E8%AF%86%E5%88%AB.html图片属性:jpg/png/bmp,最短边至少15px,最长边最大4096px,编码后大小不超过4M,识别文字语种:中英文webapi OCR服务参考帖子(必看):http://bbs.xfyun.cn/forum.php?mod=viewthread&tid=39111&highlight=OCR(Very Important)创建完webapi应用添加服务之后一定要设置ip白名单,找到控制台--我的应用--设置ip白名单,如何设置参考:http://bbs.xfyun.cn/forum.php?mod=viewthread&tid=41891错误码链接:https://www.xfyun.cn/document/error-code (code返回错误码时必看)@author iflytek
"""
# OCR手写文字识别接口地址
URL = "http://webapi.xfyun.cn/v1/service/v1/ocr/handwriting"
# 应用APPID(必须为webapi类型应用,并开通手写文字识别服务,参考帖子如何创建一个webapi应用:http://bbs.xfyun.cn/forum.php?mod=viewthread&tid=36481)
APPID = "**yourappid**"
# 接口密钥(webapi类型应用开通手写文字识别后,控制台--我的应用---手写文字识别---相应服务的apikey)
API_KEY = "**yourappkey**"
# 语种设置
language = "cn|en"
# 是否返回文本位置信息
location = "true"
# 图片上传接口地址
picFilePath = sys.argv[1]
#picFilePath = "C:/Users/Tianlong Hu/Desktop/test"
def getFiles(picFilePath):f = []for filepath,dirnames,filenames in os.walk(picFilePath):for filename in filenames:f = f+[os.path.join(filepath,filename)]return f
def getHeader():curTime = str(int(time.time()))param = "{\"language\":\""+language+"\",\"location\":\""+location+"\"}"paramBase64 = base64.b64encode(param.encode('utf-8'))m2 = hashlib.md5()str1 = API_KEY + curTime + str(paramBase64, 'utf-8')m2.update(str1.encode('utf-8'))checkSum = m2.hexdigest()# 组装http请求头header = {'X-CurTime': curTime,'X-Param': paramBase64,'X-Appid': APPID,'X-CheckSum': checkSum,'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8',}return header
def getBody(filepath):with open(filepath, 'rb') as f:imgfile = f.read()data = {'image': str(base64.b64encode(imgfile), 'utf-8')}return data
#def getImage(picFilePath):#img_data = cv2.imread(picFilePath, 1)#height,width = img_data.shape[:2]#size = (int(height*4050/height), int(width*4050/height))#img_data = cv2.resize(img_data,size)#return img_data
def getContent(img_data):r = requests.post(URL, headers=getHeader(), data=getBody(picFilePath))#print(r.content)result_json = json.loads(r.content)text = [];xloc = [];yloc = [];wheight = []for i in range(0,len(result_json["data"]["block"][0]["line"])):text = text+[result_json["data"]["block"][0]["line"][i]["word"]]xloc = xloc+[(result_json["data"]["block"][0]["line"][i]["location"]["top_left"]["x"] + result_json["data"]["block"][0]["line"][i]["location"]["right_bottom"]["x"])/2]yloc = yloc+[(result_json["data"]["block"][0]["line"][i]["location"]["top_left"]["y"] + result_json["data"]["block"][0]["line"][i]["location"]["right_bottom"]["y"])/2]wheight = wheight + [result_json["data"]["block"][0]["line"][i]["location"]["right_bottom"]["y"] - result_json["data"]["block"][0]["line"][i]["location"]["top_left"]["y"]]return text,yloc,wheight
def getTable(picFilePath,wheight):#二值化image_data = cv2.imread(picFilePath, 1)gray = cv2.cvtColor(image_data, cv2.COLOR_BGR2GRAY)binary = cv2.adaptiveThreshold(~gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 35, -5)#ret,binary = cv2.threshold(~gray, 127, 255, cv2.THRESH_BINARY)#cv2.imshow("cell", binary)#cv2.waitKey(0)rows,cols=binary.shapescale = 40#识别横线kernel  = cv2.getStructuringElement(cv2.MORPH_RECT,(cols//scale,1))eroded = cv2.erode(binary,kernel,iterations = 1)#cv2.imshow("Eroded Image",eroded)dilatedcol = cv2.dilate(eroded,kernel,iterations = 1)#cv2.imshow("Dilated Image",dilatedcol)#cv2.waitKey(0)#识别竖线scale = 30kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(1,rows//scale))eroded = cv2.erode(binary,kernel,iterations = 1)dilatedrow = cv2.dilate(eroded,kernel,iterations = 1)#cv2.imshow("Dilated Image",dilatedrow)#cv2.waitKey(0)#标识交点bitwiseAnd = cv2.bitwise_and(dilatedcol,dilatedrow)#cv2.imshow("bitwiseAnd Image",bitwiseAnd)#cv2.waitKey(0)#cv2.imwrite('/home/hutianlong/Desktop/test2.png',bitwiseAnd)#标识表格#merge = cv2.add(dilatedcol,dilatedrow)#cv2.imshow("add Image",merge)#cv2.waitKey(0)#识别黑白图中的白色点ys,xs = np.where(bitwiseAnd>0)mylisty=[]mylistx=[]#通过排序,获取跳变的x和y的值,说明是交点,否则交点会有好多像素值,我只取最后一点myxs=np.sort(xs)for i in range(len(myxs)-1):if(myxs[i+1]-myxs[i]>150):mylistx.append(myxs[i])mylistx.append(myxs[i])# print(mylistx)# print(len(mylistx))myys=np.sort(ys)#print(np.sort(ys))for i in range(len(myys)-1):if(myys[i+1]-myys[i]>min(wheight)/2):mylisty.append(myys[i])mylisty.append(myys[i])# print(mylisty)# print(len(mylisty))return mylistx,mylisty
def outputTable(text,yloc,mylisty):row_id = []for i in range(len(text)):row_id = row_id + [sum((yloc[i] - np.array(mylisty))>0)]return row_id# 建立文件
workbook = xlsxwriter.Workbook(sys.argv[2])
#workbook = xlsxwriter.Workbook("C:/Users/Tianlong Hu/Desktop/test.xlsx")
for picFilePath in getFiles(picFilePath):#2nd step: output content and its locationtext,yloc,wheight = getContent(picFilePath)#3rd step: get table locationmylistx,mylisty = getTable(picFilePath,wheight)#4th step: output tablerow_id = outputTable(text,yloc,mylisty)# 建立sheet, 可以work.add_worksheet('employee')来指定sheet名,但中文名会报UnicodeDecodeErro的错误mytext = [[] for i in range(max(row_id))]for i in range(max(row_id)):for j in range(len(text)):if row_id[j] == i+1:mytext[i] = mytext[i] + text[j]# 建立sheet, 可以work.add_worksheet('employee')来指定sheet名,但中文名会报UnicodeDecodeErro的错误worksheet = workbook.add_worksheet()for i in range(len(mytext)):for j in range(len(mytext[i])):worksheet.write(i,j,mytext[i][j]["content"])
workbook.close()

3. 使用方法:
——》打开cmd.exe,进入命令行模式。
——》切换到程序所在文件夹,使用如下命令运行程序:
        handwriting_table_ocr_xunfeiai.exe test test.xlsx
——》test为手写数据照片所在文件夹,test.xlsx为输出Excel表格名称。

4. 注意事项:
——》程序在使用过程中需要连接科大讯飞提供的API,请保持网络连接畅通;
——》在拍照过程中确保表格四周均在视野范围内,推荐使用WPS文档扫描文件;
——》照片最大高度控制在4096像素内;
——》照片不要倾斜或旋转。
——》图片格式最好为JPG或PNG

也可直接使用笔者打包好的EXE文件运行哈,见如下链接:手写实验数据批量转Excel的python脚本及EXE文件-教育文档类资源-CSDN文库https://download.csdn.net/download/weixin_43367441/79581415

使用过程中有任何问题,欢迎评论或后台留言,我会尽快回复您。

如何批量将手写数据转Excel?相关推荐

  1. Python+OpenCV:基于SVM手写数据OCR(OCR of Hand-written Data using SVM)

    Python+OpenCV:基于SVM手写数据OCR(OCR of Hand-written Data using SVM) dsize = 20 affine_flags = lmc_cv.WARP ...

  2. Python+OpenCV:基于KNN手写数据OCR(OCR of Hand-written Data using kNN)

    Python+OpenCV:基于KNN手写数据OCR(OCR of Hand-written Data using kNN) OCR of Hand-written Digits ########## ...

  3. mfc创建excel如何另存为_mfc表格数据保存为excel文件-VC (MFC)如何从对话框写数据到Excel...

    我现在把Excel表格嵌入到MFC单文档界面,然后对嵌... 1.首先,打开媒介工具"记事本",将word文件里需要导入的数据,复制粘贴到记事本当中,然后保存成为txt文件,本例中 ...

  4. 中文手写数据生成基于paddleocr和textrenderer-大幅提高中文识别准确率

    文章目录 参考 一.textrenderer更多参数解释 二.准备手写字体文件 效果展示 参考 主要是参考了这位大佬的工作 ,大佬说生成都是灰度图,因为考虑样本多样性,主要介绍如何生成彩色图片,字典文 ...

  5. pyTorch入门(一)——Minist手写数据识别训练全连接网络

    学更好的别人, 做更好的自己. --<微卡智享> 本文长度为1739字,预计阅读5分钟 前言 做为pyTorch的刚入门者,需要自己再做Demo进行练习,所以这个入门是一个系列,从pyTo ...

  6. c#写数据到Excel慢

    本示例是用于将ListView中的内容倒入到Excel,与常用的逐单元格写不同的是,本例子采用数据写入到range的方法.该方法效率明显较高. Excel.Application app = new ...

  7. mysql写到excel_使用Python从 MySQL写数据到Excel

    直接上代码:#!/usr/bin/env python #coding:utf-8 import xlwt import MySQLdb import datetime database = MySQ ...

  8. MATLAB xlswrite 写数据 到 Excel文件

    目录下建立一个xlsx文件夹,'out_ans.xlsx' xlswrite('out_ans.xlsx',[1 2 3 4]','A1') 写入字符串 " str "  双引号的 ...

  9. 如何快速将手写数据录入 Excel

    假设我有手写数据(假装它是纸质版的手写数据): 我要将它录入到 excel 表格中,如何录入呢? 我们可以打开语音输入法,然后照着念,并在每个数据后,多念一个 a (用来分列的),得到(逗号,空格都不 ...

最新文章

  1. ImageView no longer exists. You should not use this PhotoViewAttacher any more
  2. 99%的产品经理不知道的秘密:如何招程序猿喜欢?
  3. 笔记2深度学习 梯度和梯度法
  4. nvidia nvlink互联与nvswitch介绍
  5. redis缓存穿透、缓存雪崩、缓存击穿、并发竞争
  6. 2020 WTM 继续向前
  7. 90后清华博士爆红,颜值惊呆网友:所谓的“命好”,不过是努力的别称
  8. 图解:Activity生命周期
  9. Etl之HiveSql调优(left join where的位置)
  10. 锁定非物质化的梦想,一切选择都会变简单!
  11. C语言函数取大,C语言函数大全(部分)
  12. 深度学习GPU显卡选型攻略
  13. 计算机十六进制ABCD,16进制计算(十六进制计算器在线)
  14. 【历史上的今天】4 月 3 日:亚马逊卖出第一本书;世界上第一通手机电话;IBM 计算机先驱出生
  15. web调用钉钉待办审批
  16. 【Unity3D】Tank大战
  17. security基于数据库的认证(二)
  18. 原生小程序使用 flyio,以及拦截器
  19. svchost占用内存过高电脑很卡如何解决
  20. android 5.x—Elevation阴影

热门文章

  1. 木兰天池全新景观2013闪亮登场
  2. 「涪陵榨菜」使用区块链溯源系统?回应:看榨菜集团的安排
  3. 我们在这创业,我们在这融资,我们在这泡妞,我们在这死去...
  4. SQL语句和sql函数
  5. 如何设置窗口的标题栏里的标题【转】
  6. 笔记本无线连外网,有线连内网,如何实现?
  7. 谷歌高级架构师十年心血终成Kubernetes微服务实战文档
  8. JS手写上传文件、React手写上传文件
  9. 2020-11-25-springboot-打开web日志
  10. STEAM游戏高主频i9-12900k 搭建CS:GO服务器