ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

如何优雅地把大批手写实验数据输入电脑?

2022-02-07 17:30:33  阅读:239  来源: 互联网

标签:电脑 cv2 picFilePath 优雅 json import 手写 data


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

图片预处理:

图片转成excel:

 

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

1.实现思路        

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

2.实现代码

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

# -*- 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.shape
    scale = 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 = 30
    kernel = 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 location
    text,yloc,wheight = getContent(picFilePath)
    #3rd step: get table location
    mylistx,mylisty = getTable(picFilePath,wheight)
    #4th step: output table
    row_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文库icon-default.png?t=M0H8https://download.csdn.net/download/weixin_43367441/79581415

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

 

标签:电脑,cv2,picFilePath,优雅,json,import,手写,data
来源: https://blog.csdn.net/weixin_43367441/article/details/122809870

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有