制作自己的ctpn数据集

article/2025/11/2 15:20:16

制作自己的ctpn数据集
1、利用label-image标注自己的数据集,保存为.txt文件,结果如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
上图第一列 0:标签 后面的小数是label—image标注的坐标框位置(归一化后的结果)

 2、ctpn数据集的格式:x1,y1,x2,y2,x3,y3,x4,y4 顺序是:左上角、右上角、右下角、左下角 (坐标) (参考mlt数据集格式)参考链接:https://blog.csdn.net/monk1992/article/details/99670559(ctpn中的数据集格式为:左上角、右下角)3、将自己标注的数据集转换成 2中的格式,代码如下:
在这里插入代码片import cv2
import osdef change_labelimage_to_cptn_data(pictures_file_path, txt_file_path, cptn_data_labels_path):list = os.listdir(txt_file_path)# for txt_name in os.listdir(txt_file_path):#     txt_path = os.path.join(txt_file_path,txt_name).replace('\\','/')#     with open(txt_path,mode='rb') as f:#         data = f.readlines(txt_path)#         print(data)for i in range(1, len(list)+1):txt_path = txt_file_path + str(i).zfill(6) + '.txt'  #原数据集(label-image标注的)对应的txt标签存放路径dir = open(txt_path)lines = dir.readlines()lists = []  # 直接用一个数组存起来就好了for line in lines:lists.append(line.split())print(lists)im_path = pictures_file_path+str(i).zfill(6)+'.jpg'  #原数据集图片存放路径picture = cv2.imread(im_path)# print(len(lists))for j in range(0, len(lists)):a = lists[j][1]  #宽b = lists[j][2] #高c = lists[j][3] #宽度d = lists[j][4] #高度#根据txt标签中的归一化坐标还原为标注图像的真实坐标e = int((float(a) * picture.shape[1]) - (float(c) *int(picture.shape[1])/2))f = int((float(b) * picture.shape[0]) - (float(d) * picture.shape[0]/2))q = int((float(a) * picture.shape[1]) + (float(c) * picture.shape[1]/2))s = int((float(b) * picture.shape[0]) + (float(d) * picture.shape[0]/2))print(e,f,q,s)with open(cptn_data_labels_path + str(i).zfill(6)+'.txt', 'a+') as p:p.write(str(e) + ',' + str(f) + ',' + str(q) + ',' + str(s) + '\n')if __name__ == '__main__':pictures_path = './standard-CTPN-label/image/' #图片路径txt_path = './standard-CTPN-label/label/' #label-image标注的标签路径ctpn_labels = './standard-CTPN-label/ctpn_labels/' #转换后,结果保存路径change_labelimage_to_cptn_data(pictures_path, txt_path, ctpn_labels)

结果图片展示:
在这里插入图片描述
运行下面代码:split_label.py

在这里插入代码片
import os
import numpy as np
import math
import cv2 as cvpath = '/data/data/ldx/chinese_ocr/ctpn/erweima/image' #图片路径
gt_path = '/data/data/ldx/chinese_ocr/ctpn/erweima/label' #转换后的标签路径
out_path = 're_image'
if not os.path.exists(out_path):os.makedirs(out_path)
files = os.listdir(path)
files.sort()
#files=files[:100]
for file in files:_, basename = os.path.split(file)if basename.lower().split('.')[-1] not in ['jpg', 'png']:continuestem, ext = os.path.splitext(basename)gt_file = os.path.join(gt_path, stem + '.txt')img_path = os.path.join(path, file)print(img_path)img = cv.imread(img_path)img_size = img.shapeim_size_min = np.min(img_size[0:2])im_size_max = np.max(img_size[0:2])im_scale = float(600) / float(im_size_min)if np.round(im_scale * im_size_max) > 1200:im_scale = float(1200) / float(im_size_max)re_im = cv.resize(img, None, None, fx=im_scale, fy=im_scale, interpolation=cv.INTER_LINEAR)re_size = re_im.shapecv.imwrite(os.path.join(out_path, stem) + '.jpg', re_im)with open(gt_file, 'r') as f:lines = f.readlines()for line in lines:splitted_line = line.strip().lower().split(',')pt_x = np.zeros((4, 1))pt_y = np.zeros((4, 1))pt_x[0, 0] = int(float(splitted_line[0]) / img_size[1] * re_size[1])pt_y[0, 0] = int(float(splitted_line[1]) / img_size[0] * re_size[0])pt_x[1, 0] = int(float(splitted_line[2]) / img_size[1] * re_size[1])pt_y[1, 0] = int(float(splitted_line[3]) / img_size[0] * re_size[0])pt_x[2, 0] = int(float(splitted_line[4]) / img_size[1] * re_size[1])pt_y[2, 0] = int(float(splitted_line[5]) / img_size[0] * re_size[0])pt_x[3, 0] = int(float(splitted_line[6]) / img_size[1] * re_size[1])pt_y[3, 0] = int(float(splitted_line[7]) / img_size[0] * re_size[0])ind_x = np.argsort(pt_x, axis=0)pt_x = pt_x[ind_x]pt_y = pt_y[ind_x]if pt_y[0] < pt_y[1]:pt1 = (pt_x[0], pt_y[0])pt3 = (pt_x[1], pt_y[1])else:pt1 = (pt_x[1], pt_y[1])pt3 = (pt_x[0], pt_y[0])if pt_y[2] < pt_y[3]:pt2 = (pt_x[2], pt_y[2])pt4 = (pt_x[3], pt_y[3])else:pt2 = (pt_x[3], pt_y[3])pt4 = (pt_x[2], pt_y[2])xmin = int(min(pt1[0], pt2[0]))ymin = int(min(pt1[1], pt2[1]))xmax = int(max(pt2[0], pt4[0]))ymax = int(max(pt3[1], pt4[1]))if xmin < 0:xmin = 0if xmax > re_size[1] - 1:xmax = re_size[1] - 1if ymin < 0:ymin = 0if ymax > re_size[0] - 1:ymax = re_size[0] - 1width = xmax - xminheight = ymax - ymin# reimplementstep = 16.0x_left = []x_right = []x_left.append(xmin)x_left_start = int(math.ceil(xmin / 16.0) * 16.0)if x_left_start == xmin:x_left_start = xmin + 16for i in np.arange(x_left_start, xmax, 16):x_left.append(i)x_left = np.array(x_left)x_right.append(x_left_start - 1)for i in range(1, len(x_left) - 1):x_right.append(x_left[i] + 15)x_right.append(xmax)x_right = np.array(x_right)idx = np.where(x_left == x_right)x_left = np.delete(x_left, idx, axis=0)x_right = np.delete(x_right, idx, axis=0)if not os.path.exists('label_tmp'):os.makedirs('label_tmp')with open(os.path.join('label_tmp', stem) + '.txt', 'a') as f:for i in range(len(x_left)):f.writelines("text\t")f.writelines(str(int(x_left[i])))f.writelines("\t")f.writelines(str(int(ymin)))f.writelines("\t")f.writelines(str(int(x_right[i])))f.writelines("\t")f.writelines(str(int(ymax)))f.writelines("\n")

生成两个文件在这里插入图片描述
在运行:ToVoc.py

from xml.dom.minidom import Document
import cv2
import os
import glob
import shutil
import numpy as npdef generate_xml(name, lines, img_size, class_sets, doncateothers=True):doc = Document()def append_xml_node_attr(child, parent=None, text=None):ele = doc.createElement(child)if not text is None:text_node = doc.createTextNode(text)ele.appendChild(text_node)parent = doc if parent is None else parentparent.appendChild(ele)return eleimg_name = name + '.jpg'# create headerannotation = append_xml_node_attr('annotation')append_xml_node_attr('folder', parent=annotation, text='text')append_xml_node_attr('filename', parent=annotation, text=img_name)source = append_xml_node_attr('source', parent=annotation)append_xml_node_attr('database', parent=source, text='coco_text_database')append_xml_node_attr('annotation', parent=source, text='text')append_xml_node_attr('image', parent=source, text='text')append_xml_node_attr('flickrid', parent=source, text='000000')owner = append_xml_node_attr('owner', parent=annotation)append_xml_node_attr('name', parent=owner, text='ms')size = append_xml_node_attr('size', annotation)append_xml_node_attr('width', size, str(img_size[1]))append_xml_node_attr('height', size, str(img_size[0]))append_xml_node_attr('depth', size, str(img_size[2]))append_xml_node_attr('segmented', parent=annotation, text='0')# create objectsobjs = []for line in lines:splitted_line = line.strip().lower().split()cls = splitted_line[0].lower()if not doncateothers and cls not in class_sets:continuecls = 'dontcare' if cls not in class_sets else clsif cls == 'dontcare':continueobj = append_xml_node_attr('object', parent=annotation)occlusion = int(0)x1, y1, x2, y2 = int(float(splitted_line[1]) + 1), int(float(splitted_line[2]) + 1), \int(float(splitted_line[3]) + 1), int(float(splitted_line[4]) + 1)truncation = float(0)difficult = 1 if _is_hard(cls, truncation, occlusion, x1, y1, x2, y2) else 0truncted = 0 if truncation < 0.5 else 1append_xml_node_attr('name', parent=obj, text=cls)append_xml_node_attr('pose', parent=obj, text='none')append_xml_node_attr('truncated', parent=obj, text=str(truncted))append_xml_node_attr('difficult', parent=obj, text=str(int(difficult)))bb = append_xml_node_attr('bndbox', parent=obj)append_xml_node_attr('xmin', parent=bb, text=str(x1))append_xml_node_attr('ymin', parent=bb, text=str(y1))append_xml_node_attr('xmax', parent=bb, text=str(x2))append_xml_node_attr('ymax', parent=bb, text=str(y2))o = {'class': cls, 'box': np.asarray([x1, y1, x2, y2], dtype=float), \'truncation': truncation, 'difficult': difficult, 'occlusion': occlusion}objs.append(o)return doc, objsdef _is_hard(cls, truncation, occlusion, x1, y1, x2, y2):hard = Falseif y2 - y1 < 25 and occlusion >= 2:hard = Truereturn hardif occlusion >= 3:hard = Truereturn hardif truncation > 0.8:hard = Truereturn hardreturn harddef build_voc_dirs(outdir):mkdir = lambda dir: os.makedirs(dir) if not os.path.exists(dir) else Nonemkdir(outdir)mkdir(os.path.join(outdir, 'Annotations'))mkdir(os.path.join(outdir, 'ImageSets'))mkdir(os.path.join(outdir, 'ImageSets', 'Layout'))mkdir(os.path.join(outdir, 'ImageSets', 'Main'))mkdir(os.path.join(outdir, 'ImageSets', 'Segmentation'))mkdir(os.path.join(outdir, 'JPEGImages'))mkdir(os.path.join(outdir, 'SegmentationClass'))mkdir(os.path.join(outdir, 'SegmentationObject'))return os.path.join(outdir, 'Annotations'), os.path.join(outdir, 'JPEGImages'), os.path.join(outdir, 'ImageSets','Main')if __name__ == '__main__':_outdir = 'TEXTVOC/VOC2007'_draw = bool(0)_dest_label_dir, _dest_img_dir, _dest_set_dir = build_voc_dirs(_outdir)_doncateothers = bool(1)for dset in ['train']:_labeldir = 'label_tmp'_imagedir = 're_image'class_sets = ('text', 'dontcare')class_sets_dict = dict((k, i) for i, k in enumerate(class_sets))allclasses = {}fs = [open(os.path.join(_dest_set_dir, cls + '_' + dset + '.txt'), 'w') for cls in class_sets]ftrain = open(os.path.join(_dest_set_dir, dset + '.txt'), 'w')files = glob.glob(os.path.join(_labeldir, '*.txt'))files.sort()for file in files:path, basename = os.path.split(file)stem, ext = os.path.splitext(basename)with open(file, 'r') as f:lines = f.readlines()img_file = os.path.join(_imagedir, stem + '.jpg')print(img_file)img = cv2.imread(img_file)img_size = img.shapedoc, objs = generate_xml(stem, lines, img_size, class_sets=class_sets, doncateothers=_doncateothers)cv2.imwrite(os.path.join(_dest_img_dir, stem + '.jpg'), img)xmlfile = os.path.join(_dest_label_dir, stem + '.xml')with open(xmlfile, 'w') as f:f.write(doc.toprettyxml(indent='	'))ftrain.writelines(stem + '\n')cls_in_image = set([o['class'] for o in objs])for obj in objs:cls = obj['class']allclasses[cls] = 0 \if not cls in list(allclasses.keys()) else allclasses[cls] + 1for cls in cls_in_image:if cls in class_sets:fs[class_sets_dict[cls]].writelines(stem + ' 1\n')for cls in class_sets:if cls not in cls_in_image:fs[class_sets_dict[cls]].writelines(stem + ' -1\n')(f.close() for f in fs)ftrain.close()print('~~~~~~~~~~~~~~~~~~~')print(allclasses)print('~~~~~~~~~~~~~~~~~~~')shutil.copyfile(os.path.join(_dest_set_dir, 'train.txt'), os.path.join(_dest_set_dir, 'val.txt'))shutil.copyfile(os.path.join(_dest_set_dir, 'train.txt'), os.path.join(_dest_set_dir, 'trainval.txt'))for cls in class_sets:shutil.copyfile(os.path.join(_dest_set_dir, cls + '_train.txt'),os.path.join(_dest_set_dir, cls + '_trainval.txt'))shutil.copyfile(os.path.join(_dest_set_dir, cls + '_train.txt'),os.path.join(_dest_set_dir, cls + '_val.txt'))

最后生成一个文件:
在这里插入图片描述
参考博客:https://blog.csdn.net/monk1992/article/details/99670559
https://github.com/YCG09/chinese_ocr


http://chatgpt.dhexx.cn/article/hVN8mbRF.shtml

相关文章

CTPN文本检测与tensorflow实现

1. 引言 近年来&#xff0c;随着人工智能的发展&#xff0c;文本检测在很多任务中都是一项基本任务&#xff0c;比如广告牌中文字识别、智能驾驶路牌的检测、身份证识别、快递地址识别等。这些任务中首先的一项就是文本检测&#xff0c;即检测出文本在图像中的位置&#xff0c;…

制作自己的CTPN训练集

制作自己的CTPN训练集 使用labelimg工具制作YOLO格式再将其转为CTPN中需要的8个坐标 1.标注框 2.代码生成坐标并保存 import cv2 import os def change_labelimage_to_cptn_data(pictures_file_path, txt_file_path, cptn_data_labels_path):list os.listdir(txt_file_pat…

【文本检测与识别-白皮书-3.1】第四节:算法模型 2

CTPN CTPN&#xff0c;全称是“Detecting Text in Natural Image with Connectionist Text Proposal Network”&#xff08;基于连接预选框网络的文本检测&#xff09;。CTPN直接在卷积特征映射中检测一系列精细比例的文本建议中的文本行。CTPN开发了一个垂直锚定机制&#xf…

CPTN代码运行报错

Windows10 系统运行 github上给的是linux操作系统指令 因为我是Windows10 的系统&#xff0c;不能通过setup的指令得到所需文件&#xff0c;后面根据https://github.com/eragonruan/text-detection-ctpn/issues/359的方法到第4步报错 错误1&#xff1a; 找不到cl.exe&#x…

JAVA项目实战开发电商项目案例(十)订单与支付模块

文章目录 1项目架构2项目采用技术3订单与支付模块功能演示4如何开发支付宝的支付模块以及订单模块4.1首先需要编写前端页面以及JS文件4.2其次需要编写JAVA后台接口4.3支付模块分析4.4订单模块分析5代码分析6个人说明7 [我的个人网站](http://www.liph.fun)8获取源码 此次电商系…

Java 项目实战 坦克大战 (0)--前言

做了有一个星期了&#xff0c;java语言太强大了&#xff0c;也算是学得最认真的一门语言了&#xff0c;本次课设花的心思也就比较多了。关键总是追求完美总是想原创&#xff0c;最终做出来效果不错&#xff0c;但感觉代码逻辑很乱&#xff0c;今天开始就好好整理一番&#xff0…

Java项目实战第11天:搜索功能的实现

目录 一、sql语句动态拼接二、前后台代码编写三、搜索框数据回填最后 今天是刘小爱自学Java的第110天。 感谢你的观看&#xff0c;谢谢你。 话不多说&#xff0c;开始今天的学习&#xff1a; 事先说明&#xff1a;关于今天的搜索功能实现。 并没有使用到倒排索引这样的主流搜…

【CSDN最全java项目实战500篇】练手/项目经验/毕设刚需

免费精选&#xff01;强烈建议收藏&#xff01;学完这一套直接进大厂&#xff08;附配套源码&资料&#xff09; C站&#xff08;CSDN&#xff09;软件工程师能力认证&#xff0c;已上线70天&#xff0c;下图300所高校的小伙伴们都已经预约、完成C认证&#xff0c;就等你来啦…

Java项目开发实战入门 PDF 扫描完整版

内容介绍 《Java项目开发实战入门》以一起来画画、通讯录系统、明日彩票预测系统、小小五子棋、企业进销存管理系统、企业QQ&#xff08;局域网版&#xff09;、九宫格记忆网和铭成在线考试系统8个精选项目为案例&#xff0c;从趣味性和实际应用角度出发&#xff0c;采用了当前…

全站最全实战的Java项目(附源码)

嗨喽&#xff0c;大家好&#xff0c;今天又要给大家整一波福利了&#xff01; 不管我们要学习哪种语言都希望能第一时间看到成效&#xff0c;能做出实际的东西来&#xff0c;那么这里所说的实际东西当然就是项目啦&#xff01;不用我说大家也知道&#xff0c;学编程语言不做项…

java项目实战之404错误原因总结

java项目实战之404错误原因总结 第一个原因可能是你的URL写错了&#xff0c;正确的URL应该这么写 localhost:8080/项目名称/对应的目录或者映射 好好检查检查是否是拼写错误&#xff0c;或者多了什么&#xff0c;少了什么 第二个原因可能是你的Spring配置文件写错了 一般都…

最牛逼的 Java 项目实战,没有之一!

想要成长为高级开发&#xff0c;掌握更多层面的技术&#xff0c;兼顾深度和广度是毋庸置疑的。你肯定认为&#xff0c;我要认真努力的学习技术&#xff0c;丰富自己的技术栈&#xff0c;然后就可以成为一个优秀的高级开发了。但当你真正去学习之后就会发现&#xff0c;技术栈异…

史上最全Java项目实战课程(含项目实战+源码)

【此文章转自乐字节】 很多小伙伴学了Java有一段时间了&#xff0c;想找几个项目想练练手&#xff0c;更有助于我们的学习和工作实践&#xff0c;最重要的是提高自己的项目经验&#xff0c;对于找工作而言有着大大的帮助&#xff0c;那今天UP主就来分享一些Java实战项目&#…

10套最全Java项目实战课程(附项目实战+源码)

家人们&#xff0c;我又来啦&#xff0c;今天我们来看一下学Java必练的10款游戏项目&#xff01; 大家都知道学习编程必须要做的就是敲代码和做项目练手了&#xff0c;那项目有难有易&#xff0c;很多小伙伴不知道从哪里找项目来练习&#xff0c;今日我们来看一下初级项目中都…

8个Java实践项目:平均半个小时就可干完~

最近有很多看过Java300集小伙伴私信我说推荐几个Java实践练手项目&#xff0c;在这里我收集了8个可以供大家在平时学习过程中进行练手的项目&#xff01;平均每个项目&#xff0c;半个小时即可完成&#xff01;&#xff01;&#xff01; 最近学习Java的小伙伴们快来练练看看自己…

亲测:三个值得练手的Java实战项目

测试奇谭&#xff0c;BUG不见。 大家好&#xff0c;我是谭叔。 一提到编码&#xff0c;很多小伙伴便感到头疼&#xff0c;特别是半路转行的小伙伴或者没有系统学习过计算机基础的小伙伴。 对于想学而不知道怎么学的小伙伴&#xff0c;我可以分享下我的策略&#xff1a; 刷一…

你必看的Java实战练手项目(附源码)

嗨喽&#xff0c;大家好&#xff0c;关注我&#xff0c;福利不断&#xff01; 不管我们要学习哪种语言都希望能第一时间看到成效&#xff0c;能做出实际的东西来&#xff0c;那么这里所说的实际东西当然就是项目啦&#xff01;不用我说大家也知道&#xff0c;学编程语言不做项目…

12个Java实践项目:练完变学神

【尚学堂Java游戏项目“超级玛丽“】Java实战教程 最近有很多看过java300集小伙伴私信我说推荐几个Java实践练手项目&#xff0c;在这里我收集了12个可以供大家在平时学习过程中进行练手的项目&#xff01; 尚学堂给同学们带来全新的Java300集课程啦!java零基础小白自学Java必备…

Java项目实战【超级详细】

软件开发流程 角色分工 开发环境搭建 创建普通Maven项目编写pom.xml导入依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instanc…

android markdown编辑器,安卓版好用的Markdown编辑器

有很多的朋友一直想找一个安卓手机的markdown编辑器&#xff0c;问我有没有好用的安卓版Markdown编辑器&#xff0c;我要告诉你的是当然有啦&#xff01;到软件应用市场输入“markdown”&#xff0c;对比了一下&#xff0c;发现这款编辑器非常不错。 坚果云markdown软件是一款非…