前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >利用Caffe与lmdb读写图像数据

利用Caffe与lmdb读写图像数据

作者头像
mythsman
发布2022-11-14 14:56:41
4960
发布2022-11-14 14:56:41
举报
文章被收录于专栏:mythsman的个人博客

由于有关caffe的开发资料实在太少,单单是这个问题就困扰了我半天。最后终于找到了一个大腿----beenfrog,也是一个正在学习caffe框架的研究人员。博客mark下,以后有问题可以去这里找。

本文代码部分主要参考于此文

简述

lmdb是一种轻量级的数据库,caffe中主要就是使用lmdb模块来进行图像数据集的保存。据说是因为lmdb有读取速度快,支持多线程、多进程并发,等这样那样的优点(具体见官网,虽然我暂时没有看出来,据我所知网上查找lmdb文档的人大都仅仅是为了使用caffe的),注意到这个数据库其实并没有任何压缩处理的作用,他的目的只是为了快速的索引和存取。他的数据都会带着一定的数据结构从而使的体积略微增大。

事实上如果仅仅看lmdb的用法是无法直接应用于图像文件的处理的。由于caffe是将图像以他自带的数据类型的形式传入lmdb中的,因此我们必须结合caffe的数据类型才能完成读取和使用。

lmdb的安装

参考官方文档,安装如下依赖即可:

代码语言:javascript
复制
udo apt-get install cython
sudo apt-get install libffi-dev python-dev build-essential
sudo apt-get install python-cffi
sudo easy_install lmdb

实践再次映证了用easy_install 安装要比pip好的多(在版本跟的上的情况下)。

生成数据文件

这里以zhengfang/文件夹下的1.png至1000.png为例

代码语言:javascript
复制
#coding:utf-8
import lmdb
import numpy as np
import cv2
import caffe
from caffe.proto import caffe_pb2

#basic setting
lmdb_file = 'lmdb_data'#期望生成的数据文件
batch_size = 200       #lmdb对于数据进行的是先缓存后一次性写入从而提高效率,因此定义一个batch_size控制每次写入的量。

# create the leveldb file
lmdb_env = lmdb.open(lmdb_file, map_size=int(1e12))#生成一个数据文件,定义最大空间
lmdb_txn = lmdb_env.begin(write=True)              #打开数据库的句柄
datum = caffe_pb2.Datum()                          #这是caffe中定义数据的重要类型

for x in range(1000):
    x+=1
    img=cv2.imread('zhengfang/'+str(x)+'.png').convert('RGB')     #从zhengfang/文件夹中依次读取图像

    # save in datum
    data = img.astype('int').transpose(2,0,1)      #图像矩阵,注意需要调节维度
    #data = np.array([img.convert('L').astype('int')]) #或者这样增加维度
    label = x                                      #图像的标签,为了方便存储,这个必须是整数。
    datum = caffe.io.array_to_datum(data, label)   #将数据以及标签整合为一个数据项

    keystr = '{:0>8d}'.format(x-1)                 #lmdb的每一个数据都是由键值对构成的,因此生成一个用递增顺序排列的定长唯一的key
    lmdb_txn.put( keystr, datum.SerializeToString())#调用句柄,写入内存。

    # write batch
    if x % batch_size == 0:                        #每当累计到一定的数据量,便用commit方法写入硬盘。
        lmdb_txn.commit()
        lmdb_txn = lmdb_env.begin(write=True)      #commit之后,之前的txn就不能用了,必须重新开一个。
        print 'batch {} writen'.format(x)

lmdb_env.close()                                   #结束后记住释放资源,否则下次用的时候打不开。。。

输出:

代码语言:javascript
复制
batch 200 writen
batch 400 writen
batch 600 writen
batch 800 writen
batch 1000 writen

照着注释,很好理解了。值得一提的是,生成的文件是以文件夹的形式保存的,内部由data.mdb lock.mdb组成,不用管他。

这里需要强烈注意的一点是,datum里的图像是需要有长宽高三个维度的,而且第一个维度默认是通道数,而我们平常的图像格式是第三位是通道。因此我们需要在读入普通图像的时候将他转置一下存入datum中,或者在外面增加一层。

读取数据文件

读取上面生成的数据文件。

代码语言:javascript
复制
#coding:utf-8

import caffe
import lmdb
import numpy as np
import cv2
from caffe.proto import caffe_pb2

lmdb_env = lmdb.open('lmdb_data')#打开数据文件
lmdb_txn = lmdb_env.begin()      #生成句柄
lmdb_cursor = lmdb_txn.cursor()  #生成迭代器指针
datum = caffe_pb2.Datum()        #caffe定义的数据类型

for key, value in lmdb_cursor:   #循环获取数据
    datum.ParseFromString(value) #从value中读取datum数据

    label = datum.label          #获取标签以及图像数据
    data = caffe.io.datum_to_array(datum)
    print data.shape
    print datum.channels
    image =data.transpose(1,2,0)
    cv2.imshow('cv2.png', image) #显示
    cv2.waitKey(0)

cv2.destroyAllWindows()
lmdb_env.close()

输出:(图像略)

代码语言:javascript
复制
(3, 27, 72)
3

基本是和写入程序一一相对,很好理解。同样需要注意的是如需要显示图像,则需要将数据转置回来。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 简述
  • lmdb的安装
  • 生成数据文件
  • 读取数据文件
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档