CASIA数据集转png HWDB2.0-2.2
https://nlpr.ia.ac.cn/databases/handwriting/Home.html
CASIA在线和离线中文手写数据库
https://nlpr.ia.ac.cn/databases/handwriting/Offline_database.html
CASIA-HWDB2.0-2.2
离线文本数据库是由孤立字符数据集的作者制作的。每人撰写了五页给定文本。由于数据丢失,缺少一位作者(编号 371)和四页内容。每一页都存储在以作者索引和页码命名的 *.dgrl 文件中。除灰度图像外,数据文件还包括文本行分割的基本事实和字符类别标签(GB 码)。(训练集和测试集的作者是互斥的)
| Dataset | #writers | #pages | #lines | #character/#class | #out-of-class sample |
|---|---|---|---|---|---|
| HWDB2.0 | 419 | 2,092 | 20,495 | 538,868/1,222 | 1,106 |
| HWDB2.1 | 300 | 1,500 | 17,292 | 429,553/2,310 | 172 |
| HWDB2.2 | 300 | 1,499 | 14,443 | 380,993/1,331 | 581 |
| Total | 1,019 | 5,091 | 52,230 | 1,349,414/2,703 | 1,859 |
截图(使用https://nlpr.ia.ac.cn/databases/Download/DGRLView.exe查看)

使用准备
把原训练集和测试集的数据合并到一个文件夹里,再根据作者重新分配训练集和测试集,确保训练集中存在每一个作者的笔迹.还要把dgrl 转成 png.
使用dgrl 查看002-P18.dgrl 是正常的(不会出现上下行重叠)

使用代码导出 png 时,发生了重叠(每行的坐标和长宽使用的是文件里面解析的结果)

软件应该是进行了渲染的处理,比如正片叠底

这里使用简单的方法处理,记录每行添加进大图后的最下边的 y 值,这样虽然上下距离变远了但不影响使用.

007-P19

这里的白边切不掉

修改后的代码(参考https://blog.csdn.net/DaGongJiGuoMaLu09/article/details/107050519)
import os
import struct
from pathlib import Pathimport cv2 as cv
import numpy as np
from tqdm import tqdm#切割白边
def remove_white(image):# 将图像反相inverted_image = cv.bitwise_not(image)# 计算上下左右投影horizontal_projection = np.sum(inverted_image, axis=1)vertical_projection = np.sum(inverted_image, axis=0)# 找到非零元素的索引范围non_zero_horizontal = np.where(horizontal_projection > 0)non_zero_vertical = np.where(vertical_projection > 0)# 获取边界top = non_zero_horizontal[0][0]bottom = non_zero_horizontal[0][-1]left = non_zero_vertical[0][0]right = non_zero_vertical[0][-1]# 切割图像并返回cropped_image = image[top:bottom, left:right]return cropped_imagedef read_from_dgrl(dgrl):if not os.path.exists(dgrl):print("DGRL not exists!")return# if(os.path.basename(dgrl)!="385-P20.dgrl"):# returngray_output_dir = "Y:/RawData/CASIA-HWDB2-png/gray/test"binary_output_dir = "Y:/RawData/CASIA-HWDB2-png/binary/test"with open(dgrl, "rb") as f:# 读取表头尺寸header_size = np.fromfile(f, dtype="uint8", count=4)header_size = sum([j << (i * 8) for i, j in enumerate(header_size)])# print(header_size)# 读取表头剩下内容,提取 code_lengthheader = np.fromfile(f, dtype="uint8", count=header_size - 4)code_length = sum([j << (i * 8) for i, j in enumerate(header[-4:-2])])# print(code_length)# 读取图像尺寸信息,提取图像中行数量image_record = np.fromfile(f, dtype="uint8", count=12)height = sum([j << (i * 8) for i, j in enumerate(image_record[:4])])width = sum([j << (i * 8) for i, j in enumerate(image_record[4:8])])line_num = sum([j << (i * 8) for i, j in enumerate(image_record[8:])])# print("图像尺寸:")# print(height, width, line_num)# 创建一个空白图像来存储所有行的图像big_image = np.zeros((height+3000, 9000), dtype=np.uint8)big_image.fill(255)now_x=0now_y=0# 读取每一行的信息for k in range(line_num):# print(k + 1)# 读取该行的字符数量char_num = np.fromfile(f, dtype="uint8", count=4)char_num = sum([j << (i * 8) for i, j in enumerate(char_num)])# print("字符数量:", char_num)# 读取该行的标注信息label = np.fromfile(f, dtype="uint8", count=code_length * char_num)label = [label[i] << (8 * (i % code_length))for i in range(code_length * char_num)]label = [sum(label[i * code_length : (i + 1) * code_length])for i in range(char_num)]label = [struct.pack("I", i).decode("gbk", "ignore")[0] for i in label]# print("合并前:", label)label = "".join(label)# 去掉不可见字符 \x00,这一步不加的话后面保存的内容会出现看不见的问题label = "".join(label.split(b"\x00".decode()))# print("合并后:", label)# 读取该行的位置和尺寸pos_size = np.fromfile(f, dtype="uint8", count=16)y = sum([j << (i * 8) for i, j in enumerate(pos_size[:4])])x = sum([j << (i * 8) for i, j in enumerate(pos_size[4:8])])h = sum([j << (i * 8) for i, j in enumerate(pos_size[8:12])])w = sum([j << (i * 8) for i, j in enumerate(pos_size[12:])])# print(x, y, w, h)# 读取该行的图片bitmap = np.fromfile(f, dtype="uint8", count=h * w)bitmap = np.array(bitmap).reshape(h, w)base_name = os.path.basename(dgrl)filename, _ = os.path.splitext(base_name)# 保存图片(每行的图片)bitmap=remove_white(bitmap)# image_file = os.path.join(gray_output_dir, filename + "_"+str(k)+".png")# cv.imwrite(image_file, bitmap)h, w = bitmap.shape[0], bitmap.shape[1]# if np.all(bitmap == 0) or np.all(bitmap == 255):# pass# 将该行图像放入大图中的相应位置if(k==0):big_image[y : y + h, x : x + w] = bitmap[:h, :w]now_y=y+helse:# print(x+w)# print(big_image.shape[:2])# print(big_image[now_y : now_y + h, x : x + w].shape[:2])if(x<0):x=abs(x)big_image[now_y : now_y + h, x : x + w] = bitmap[:h, :w]now_y=now_y + hcropped_image=remove_white(big_image)cropped_image_file = os.path.join(gray_output_dir, filename + ".png")cv.imwrite(cropped_image_file, cropped_image)# 使用大津法进行二值化处理_, binaryx_image =cv.threshold(cropped_image, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)# 将二值图像保存到文件中cv.imwrite(os.path.join(binary_output_dir, filename + ".png"), binaryx_image)if __name__ == "__main__":dgrl_paths = Path("Y:/RawData/CASIA-HWDB2/test").iterdir()dgrl_paths = list(dgrl_paths)la=Falsefor dgrl_path in tqdm(dgrl_paths):print(dgrl_path)# if(os.path.basename(dgrl_path)=="385-P20.dgrl"):# la=True# if(la):# read_from_dgrl(dgrl_path)read_from_dgrl(dgrl_path)
提取结果(保存灰度图和二值图)

相关文章:
CASIA数据集转png HWDB2.0-2.2
https://nlpr.ia.ac.cn/databases/handwriting/Home.html CASIA在线和离线中文手写数据库 https://nlpr.ia.ac.cn/databases/handwriting/Offline_database.html CASIA-HWDB2.0-2.2 离线文本数据库是由孤立字符数据集的作者制作的。每人撰写了五页给定文本。由于数据丢失&a…...
学习或复习电路的game推荐:nandgame(NAND与非门游戏)、Turing_Complete(图灵完备)
https://www.nandgame.com/ 免费 https://store.steampowered.com/app/1444480/Turing_Complete/ 收费,70元。据说可以导出 Verilog !...
前端面试题《react》
说说React render方法的原理?在什么时候会被触发? render函数里面可以编写JSX,转化成createElement这种形式,用于生成虚拟DOM,最终转化成真实DOM 在 React 中,类组件只要执行了 setState 方法,…...
快速入门Kotlin③类与对象
类 构造函数 主构造函数:主构造函数是类头的一部分,它跟在类名后面。主构造函数没有函数体,它可以包含初始化代码和属性声明。初始化块:init关键字修饰,它直接写在类体中。它的执行顺序与它们在类体中的出现顺序一致。 次构造函数:次要构造函数是可选的,用于提供额外…...
RUST:Arc (Atomic Reference Counted) 原子引用计数
在Rust编程语言中,Arc 是一个智能指针类型,全称为 "Atomic Reference Counted"(原子引用计数)。它的主要作用是提供线程安全的共享所有权机制,使得多个线程可以同时持有同一个数据结构的访问权,并…...
从0写一个问卷调查APP的第13天-1
1.今日任务 我也只是一个大学生,有什么思路不对的地方给我指出来哟! 分析:上次我们实现了任务调查的插入。但是我们插入的问卷调查只有它的标题,也就是这个问卷调查是什么我们告诉数据库了,但是现在我们还没有给它添加任何问题&…...
20.Python从入门到精通—参数 位置参数 关键字参数 默认参数 匿名函数 return 语句 强制位置参数
20.从入门到精通:参数 位置参数 关键字参数 默认参数 匿名函数 return 语句 强制位置参数 参数位置参数关键字参数默认参数 匿名函数return 语句强制位置参数 参数 在Python中,函数可以接受任意数量的参数,包括位置参数、关键字参数和默认参数。以下是这…...
Python爬虫之requests库
1、准备工作 pip install requests 2、实例 urllib库中的urlopen方法实际上就是以GET方式请求网页,requests库中相应的方法就是get方法。 import requestsr requests.get(https://www.baidu.com/) print(type(r)) # <class requests.models.Response> 响…...
鱼塘钓鱼(多路归并)
有 N 个鱼塘排成一排,每个鱼塘中有一定数量的鱼,例如:N5 时,如下表: 鱼塘编号12345第1分钟能钓到的鱼的数量 (1…1000)101420169每钓鱼1分钟钓鱼数的减少量(1…100)24653当前鱼塘到…...
java每日一题——买啤酒(递归经典问题)
前言: 非常喜欢的一道题,经典中的经典。打好基础,daydayup!!!啤酒问题:一瓶啤酒2元,4个盖子可以换一瓶,2个空瓶可以换一瓶,请问10元可以喝几瓶 题目如下: 啤酒问题:一瓶…...
最近接到一个大项目,给公司设计抢商品代金劵业务
我们公司是做汽车金融方面的工作,在业内还挺大。目前单量来源于2,3线城市,随着大环境越老越差位了吸引他们, 公司决定给全国的客户,销售等发一些商品 1.总体学习了京东开源秒杀系统设计思路和方案。 我们公司决定进行…...
防火墙(讲解)
目录 1.防火墙是什么? 2.防火墙设备 3.防火墙功能 1)出色的控制能力,过滤掉不安全服务 2)过滤非法用户和访问特殊站点 3)它能够对网络存取和访问进行监控审计 4.防火墙的局限 (1)防火墙有可能是可以绕过的 (2)防火墙不能防止内部出卖性攻击或者内部误操作…...
Python之装饰器-带参装饰器
Python之装饰器-带参装饰器 带参装饰器 之后不是一个单独的标识符,是一个函数调用函数调用的返回值又是一个函数,此函数是一个无参装饰器带参装饰器,可以有任意个参数 func()func(1)func(1, 2) def add(x, y):"""函数说明&…...
抖音IP属地怎么更改
抖音是一个非常受欢迎的短视频平台,吸引了无数用户在上面分享自己的生活和才艺。然而,随着快手的火爆,一些用户开始担心自己的IP地址会被他人获取,引起个人隐私风险。那么,抖音用户又该如何更改到别的地方呢࿱…...
Flutter 全局控制底部导航栏和自定义导航栏的方法
1. 介绍 导航栏在移动应用中扮演着至关重要的角色,它是用户与应用之间进行导航和交互的核心组件之一。无论是简单的页面切换,还是复杂的应用导航,导航栏都能够帮助用户快速找到所需内容,提升用户体验和应用的易用性。 在移动应用…...
检索增强生成(RAG)技术:实现流程、作用及应用案例
一. RAG简介 在自然语言处理(NLP)领域中,检索增强生成(Retrieval-Augmented Generation, RAG)技术巧妙地结合了信息检索与神经网络生成模型的力量,通过在生成过程中引入相关的外部信息,实现了在…...
Ubuntu安装和使用
Ubuntu 安装和配置 修改下载源 打开软件与更新, 选择其它站点, 选择中国, 选择阿里云源 谷歌中文输入法配置 Ctrl Alt T打开终端, 执行下述命令下fcitx框架 输入密码进行安装 sudo apt-get install -y fcitx-googlepinyinWin呼出菜单, 选择语言支持, 第一次打开会显示语言…...
【Unity】Stream最好用的Selfhost开源轻量服务
【背景】 有好几种场景的投屏或者远控应用希望实现,无论用哪种方式,都绕不开如何构建服务这一关。 【分析】 外网有很多直接付费使用的信令传输类型或是提供流服务的服务器,但我的目标场景是断绝外网的局域网,而且付费也总觉得…...
Web 常见的攻击方式有哪些?
常见的 Web 攻击方式有以下几种: 跨站脚本攻击(XSS 攻击) 跨站请求伪造(XSRF 攻击) SQL 注入 XSS 攻击 MDN 定义如下: 跨站脚本攻击(Cross-site scripting,XSS)是一…...
Rancher(v2.6.3)——Rancher部署Redis(单机版)
Rancher部署Redis详细说明文档]:https://gitee.com/WilliamWangmy/snail-knowledge/blob/master/Rancher/Rancher%E4%BD%BF%E7%94%A8%E6%96%87%E6%A1%A3.md#6rancher%E9%83%A8%E7%BD%B2redis ps:如果觉得作者写的还行,能够满足您的需求&#…...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...
ubuntu搭建nfs服务centos挂载访问
在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...
突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合
强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...
使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...
【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...
Java面试专项一-准备篇
一、企业简历筛选规则 一般企业的简历筛选流程:首先由HR先筛选一部分简历后,在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如:Boss直聘(招聘方平台) 直接按照条件进行筛选 例如:…...
C# 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
使用LangGraph和LangSmith构建多智能体人工智能系统
现在,通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战,比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...
基于IDIG-GAN的小样本电机轴承故障诊断
目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) 梯度归一化(Gradient Normalization) (2) 判别器梯度间隙正则化(Discriminator Gradient Gap Regularization) (3) 自注意力机制(Self-Attention) 3. 完整损失函数 二…...
MySQL JOIN 表过多的优化思路
当 MySQL 查询涉及大量表 JOIN 时,性能会显著下降。以下是优化思路和简易实现方法: 一、核心优化思路 减少 JOIN 数量 数据冗余:添加必要的冗余字段(如订单表直接存储用户名)合并表:将频繁关联的小表合并成…...
