pytorch制作自己的LMDB數(shù)據(jù)操作示例
本文實(shí)例講述了pytorch制作自己的LMDB數(shù)據(jù)操作。分享給大家供大家參考,具體如下:
前言
記錄下pytorch里如何使用lmdb的code,自用
制作部分的Code
code就是ASTER里數(shù)據(jù)制作部分的代碼改了點(diǎn),aster_train.txt里面就算圖片的完整路徑每行一個(gè),圖片同目錄下有同名的txt,里面記著jpg的標(biāo)簽
import os import lmdb # install lmdb by "pip install lmdb" import cv2 import numpy as np from tqdm import tqdm import six from PIL import Image import scipy.io as sio from tqdm import tqdm import re def checkImageIsValid(imageBin): if imageBin is None: return False imageBuf = np.fromstring(imageBin, dtype=np.uint8) img = cv2.imdecode(imageBuf, cv2.IMREAD_GRAYSCALE) imgH, imgW = img.shape[0], img.shape[1] if imgH * imgW == 0: return False return True def writeCache(env, cache): with env.begin(write=True) as txn: for k, v in cache.items(): txn.put(k.encode(), v) def _is_difficult(word): assert isinstance(word, str) return not re.match('^[\w]+$', word) def createDataset(outputPath, imagePathList, labelList, lexiconList=None, checkValid=True): """ Create LMDB dataset for CRNN training. ARGS: outputPath : LMDB output path imagePathList : list of image path labelList : list of corresponding groundtruth texts lexiconList : (optional) list of lexicon lists checkValid : if true, check the validity of every image """ assert(len(imagePathList) == len(labelList)) nSamples = len(imagePathList) env = lmdb.open(outputPath, map_size=1099511627776)#最大空間1048576GB cache = {} cnt = 1 for i in range(nSamples): imagePath = imagePathList[i] label = labelList[i] if len(label) == 0: continue if not os.path.exists(imagePath): print('%s does not exist' % imagePath) continue with open(imagePath, 'rb') as f: imageBin = f.read() if checkValid: if not checkImageIsValid(imageBin): print('%s is not a valid image' % imagePath) continue #數(shù)據(jù)庫(kù)中都是二進(jìn)制數(shù)據(jù) imageKey = 'image-%09d' % cnt#9位數(shù)不足填零 labelKey = 'label-%09d' % cnt cache[imageKey] = imageBin cache[labelKey] = label.encode() if lexiconList: lexiconKey = 'lexicon-%09d' % cnt cache[lexiconKey] = ' '.join(lexiconList[i]) if cnt % 1000 == 0: writeCache(env, cache) cache = {} print('Written %d / %d' % (cnt, nSamples)) cnt += 1 nSamples = cnt-1 cache['num-samples'] = str(nSamples).encode() writeCache(env, cache) print('Created dataset with %d samples' % nSamples) def get_sample_list(txt_path:str): with open(txt_path,'r') as fr: jpg_list=[x.strip() for x in fr.readlines() if os.path.exists(x.replace('.jpg','.txt').strip())] txt_content_list=[] for jpg in jpg_list: label_path=jpg.replace('.jpg','.txt') with open(label_path,'r') as fr: try: str_tmp=fr.readline() except UnicodeDecodeError as e: print(label_path) raise(e) txt_content_list.append(str_tmp.strip()) return jpg_list,txt_content_list if __name__ == "__main__": txt_path='/home/gpu-server/disk/disk1/NumberData/8NumberSample/aster_train.txt' lmdb_output_path = '/home/gpu-server/project/aster/dataset/train' imagePathList,labelList=get_sample_list(txt_path) createDataset(lmdb_output_path, imagePathList, labelList)
讀取部分
這里用的pytorch的dataloader,簡(jiǎn)單記錄一下,人比較懶,代碼就直接抄過來(lái),不整理拆分了,重點(diǎn)看__getitem__
from __future__ import absolute_import # import sys # sys.path.append('./') import os # import moxing as mox import pickle from tqdm import tqdm from PIL import Image, ImageFile import numpy as np import random import cv2 import lmdb import sys import six import torch from torch.utils import data from torch.utils.data import sampler from torchvision import transforms from lib.utils.labelmaps import get_vocabulary, labels2strs from lib.utils import to_numpy ImageFile.LOAD_TRUNCATED_IMAGES = True from config import get_args global_args = get_args(sys.argv[1:]) if global_args.run_on_remote: import moxing as mox #moxing是一個(gè)分布式的框架 跳過 class LmdbDataset(data.Dataset): def __init__(self, root, voc_type, max_len, num_samples, transform=None): super(LmdbDataset, self).__init__() if global_args.run_on_remote: dataset_name = os.path.basename(root) data_cache_url = "/cache/%s" % dataset_name if not os.path.exists(data_cache_url): os.makedirs(data_cache_url) if mox.file.exists(root): mox.file.copy_parallel(root, data_cache_url) else: raise ValueError("%s not exists!" % root) self.env = lmdb.open(data_cache_url, max_readers=32, readonly=True) else: self.env = lmdb.open(root, max_readers=32, readonly=True) assert self.env is not None, "cannot create lmdb from %s" % root self.txn = self.env.begin() self.voc_type = voc_type self.transform = transform self.max_len = max_len self.nSamples = int(self.txn.get(b"num-samples")) self.nSamples = min(self.nSamples, num_samples) assert voc_type in ['LOWERCASE', 'ALLCASES', 'ALLCASES_SYMBOLS','DIGITS'] self.EOS = 'EOS' self.PADDING = 'PADDING' self.UNKNOWN = 'UNKNOWN' self.voc = get_vocabulary(voc_type, EOS=self.EOS, PADDING=self.PADDING, UNKNOWN=self.UNKNOWN) self.char2id = dict(zip(self.voc, range(len(self.voc)))) self.id2char = dict(zip(range(len(self.voc)), self.voc)) self.rec_num_classes = len(self.voc) self.lowercase = (voc_type == 'LOWERCASE') def __len__(self): return self.nSamples def __getitem__(self, index): assert index <= len(self), 'index range error' index += 1 img_key = b'image-%09d' % index imgbuf = self.txn.get(img_key) #由于Image.open需要一個(gè)類文件對(duì)象 所以這里需要把二進(jìn)制轉(zhuǎn)為一個(gè)類文件對(duì)象 buf = six.BytesIO() buf.write(imgbuf) buf.seek(0) try: img = Image.open(buf).convert('RGB') # img = Image.open(buf).convert('L') # img = img.convert('RGB') except IOError: print('Corrupted image for %d' % index) return self[index + 1] # reconition labels label_key = b'label-%09d' % index word = self.txn.get(label_key).decode() if self.lowercase: word = word.lower() ## fill with the padding token label = np.full((self.max_len,), self.char2id[self.PADDING], dtype=np.int) label_list = [] for char in word: if char in self.char2id: label_list.append(self.char2id[char]) else: ## add the unknown token print('{0} is out of vocabulary.'.format(char)) label_list.append(self.char2id[self.UNKNOWN]) ## add a stop token label_list = label_list + [self.char2id[self.EOS]] assert len(label_list) <= self.max_len label[:len(label_list)] = np.array(label_list) if len(label) <= 0: return self[index + 1] # label length label_len = len(label_list) if self.transform is not None: img = self.transform(img) return img, label, label_len
更多關(guān)于Python相關(guān)內(nèi)容可查看本站專題:《Python數(shù)學(xué)運(yùn)算技巧總結(jié)》、《Python圖片操作技巧總結(jié)》、《Python數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Python函數(shù)使用技巧總結(jié)》、《Python字符串操作技巧匯總》及《Python入門與進(jìn)階經(jīng)典教程》
希望本文所述對(duì)大家Python程序設(shè)計(jì)有所幫助。
- 使用 pytorch 創(chuàng)建神經(jīng)網(wǎng)絡(luò)擬合sin函數(shù)的實(shí)現(xiàn)
- 人工智能學(xué)習(xí)Pytorch梯度下降優(yōu)化示例詳解
- 人工智能學(xué)習(xí)Pytorch數(shù)據(jù)集分割及動(dòng)量示例詳解
- 人工智能學(xué)習(xí)PyTorch實(shí)現(xiàn)CNN卷積層及nn.Module類示例分析
- 人工智能學(xué)習(xí)pyTorch的ResNet殘差模塊示例詳解
- 人工智能學(xué)習(xí)pyTorch自建數(shù)據(jù)集及可視化結(jié)果實(shí)現(xiàn)過程
- 人工智能學(xué)習(xí)Pytorch進(jìn)階操作教程
相關(guān)文章
Python3調(diào)用微信企業(yè)號(hào)API發(fā)送文本消息代碼示例
這篇文章主要介紹了Python3調(diào)用微信企業(yè)號(hào)API發(fā)送文本消息代碼示例,具有一定參考價(jià)值,需要的朋友可以了解下。2017-11-11Python圖像處理之gif動(dòng)態(tài)圖的解析與合成操作詳解
這篇文章主要介紹了Python圖像處理之gif動(dòng)態(tài)圖的解析與合成操作,結(jié)合實(shí)例形式分析了Python基于PIL模塊解析gif文件,以及基于imageio庫(kù)合成gif文件的相關(guān)操作技巧,需要的朋友可以參考下2018-12-12python socket通信編程實(shí)現(xiàn)文件上傳代碼實(shí)例
這篇文章主要介紹了python socket通信編程實(shí)現(xiàn)文件上傳代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-12-12Python初學(xué)者需要注意的事項(xiàng)小結(jié)(python2與python3)
這篇文章主要介紹了Python初學(xué)者需要注意的事項(xiàng)小結(jié),包括了python2與python3的一些區(qū)別,需要的朋友可以參考下2018-09-09深入理解NumPy簡(jiǎn)明教程---數(shù)組1
這篇文章主要介紹了深入理解NumPy簡(jiǎn)明教程(二、數(shù)組1),NumPy數(shù)組是一個(gè)多維數(shù)組對(duì)象,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2016-12-12python?opencv實(shí)現(xiàn)灰度圖和彩色圖的互相轉(zhuǎn)換
這篇文章主要給大家介紹了關(guān)于python?opencv實(shí)現(xiàn)灰度圖和彩色圖的互相轉(zhuǎn)換,文中通過實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2022-01-01Python matplotlib通過plt.scatter畫空心圓標(biāo)記出特定的點(diǎn)方法
今天小編就為大家分享一篇Python matplotlib通過plt.scatter畫空心圓標(biāo)記出特定的點(diǎn)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來(lái)看看吧2018-12-12詳解Python中的相對(duì)導(dǎo)入和絕對(duì)導(dǎo)入
絕對(duì)導(dǎo)入是指跳過包內(nèi),直接搜索 sys.path ,在sys.path的基礎(chǔ)上進(jìn)行我們的模塊搜索。相對(duì)導(dǎo)入是指先包內(nèi),再包外,再,,,那么下面這篇文章主要給大家介紹了Python中的相對(duì)導(dǎo)入和絕對(duì)導(dǎo)入,需要的朋友可以參考借鑒,下面來(lái)一起看看吧。2017-01-01python安裝CLIP包出現(xiàn)錯(cuò)誤:安裝.git報(bào)錯(cuò)問題及解決
這篇文章主要介紹了python安裝CLIP包出現(xiàn)錯(cuò)誤:安裝.git報(bào)錯(cuò)問題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-06-06