caffe神经网络框架的辅助工具(将图片转换为leveldb格式)

caffe神经网络框架的辅助工具(将图片转换为leveldb格式)

大家好,又见面了,我是全栈君,祝每个程序员都可以多学几门语言。

caffe中负责整个网络输入的datalayer是从leveldb里读取数据的,是一个google实现的很高效的kv数据库。

因此我们训练网络必须先把数据转成leveldb的格式。

这里我实现的是把一个目录的全部图片转成leveldb的格式。


工具使用命令格格式:convert_imagedata src_dir dst_dir attach_dir channel width height

例子:./convert_imagedata.bin /home/linger/imdata/collar_train/ /home/linger/linger/testfile/crop_train_db/ /home/linger/linger/testfile/crop_train_attachment/ 3 50 50


源码:

#include <google/protobuf/text_format.h>
#include <glog/logging.h>
#include <leveldb/db.h>

#include <stdint.h>
#include <fstream>  // NOLINT(readability/streams)
#include <string>
#include <set>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/types.h>
#include "caffe/proto/caffe.pb.h"
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/highgui/highgui_c.h>
#include <opencv2/imgproc/imgproc.hpp>

using std::string;
using namespace std;


set<string> all_class_name;
map<string,int> class2id;


/**
 * path:文件夹
 * files:用于保存文件名称的vector
 * r:是否须要遍历子文件夹
 * return:文件名称,不包括路径
 */
void list_dir(const char *path,vector<string>& files,bool r = false)
{
	DIR *pDir;
	struct dirent *ent;
	char childpath[512];
	pDir = opendir(path);
	memset(childpath, 0, sizeof(childpath));
	while ((ent = readdir(pDir)) != NULL)
	{
		if (ent->d_type & DT_DIR)
		{

			if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0)
			{
				continue;
			}
			if(r) //假设须要遍历子文件夹
			{
				sprintf(childpath, "%s/%s", path, ent->d_name);
				list_dir(childpath,files);
			}
		}
		else
		{
			files.push_back(ent->d_name);
		}
	}
	sort(files.begin(),files.end());//排序

}

string get_classname(string path)
{
	int index = path.find_last_of('_');
	return path.substr(0, index);
}


int get_labelid(string fileName)
{
	string class_name_tmp = get_classname(fileName);
	all_class_name.insert(class_name_tmp);
	map<string,int>::iterator name_iter_tmp = class2id.find(class_name_tmp);
	if (name_iter_tmp == class2id.end())
	{
		int id = class2id.size();
		class2id.insert(name_iter_tmp, std::make_pair(class_name_tmp, id));
		return id;
	}
	else
	{
		return name_iter_tmp->second;
	}
}

void loadimg(string path,char* buffer)
{
	cv::Mat img = cv::imread(path, CV_LOAD_IMAGE_COLOR);
	string val;
	int rows = img.rows;
	int cols = img.cols;
	int pos=0;
	for (int c = 0; c < 3; c++)
	{
		for (int row = 0; row < rows; row++)
		{
			for (int col = 0; col < cols; col++)
			{
				buffer[pos++]=img.at<cv::Vec3b>(row,col)[c];
			}
		}
	}

}
void convert(string imgdir,string outputdb,string attachdir,int channel,int width,int height)
{
	leveldb::DB* db;
	leveldb::Options options;
	options.create_if_missing = true;
	options.error_if_exists = true;
	caffe::Datum datum;
	datum.set_channels(channel);
	datum.set_height(height);
	datum.set_width(width);
	int image_size = channel*width*height;
	char buffer[image_size];

	string value;
	CHECK(leveldb::DB::Open(options, outputdb, &db).ok());
	vector<string> filenames;
	list_dir(imgdir.c_str(),filenames);
	string img_log = attachdir+"image_filename";
	ofstream writefile(img_log.c_str());
	for(int i=0;i<filenames.size();i++)
	{
		string path= imgdir;
		path.append(filenames[i]);//算出绝对路径

		loadimg(path,buffer);

		int labelid = get_labelid(filenames[i]);

		datum.add_label(labelid);
		datum.set_data(buffer,image_size);
		datum.SerializeToString(&value);
		snprintf(buffer, image_size, "%05d", i);
		printf("\nclassid:%d classname:%s abspath:%s",labelid,get_classname(filenames[i]).c_str(),path.c_str());
		db->Put(leveldb::WriteOptions(),string(buffer),value);
		//printf("%d %s\n",i,fileNames[i].c_str());

		assert(writefile.is_open());
		writefile<<i<<" "<<filenames[i]<<"\n";

	}
	delete db;
	writefile.close();

	img_log = attachdir+"image_classname";
	writefile.open(img_log.c_str());
	set<string>::iterator iter = all_class_name.begin();
	while(iter != all_class_name.end())
	{
		assert(writefile.is_open());
		writefile<<(*iter)<<"\n";
		//printf("%s\n",(*iter).c_str());
		iter++;
	}
	writefile.close();

}

int main(int argc, char** argv)
{
	if (argc < 6)
	{
	    LOG(ERROR) << "convert_imagedata src_dir dst_dir attach_dir channel width height";
	    return 0;
	}
//./convert_imagedata.bin  /home/linger/imdata/collarTest/ /home/linger/linger/testfile/dbtest/  /home/linger/linger/testfile/test_attachment/ 3 250 250
	//   ./convert_imagedata.bin /home/linger/imdata/collar_train/ /home/linger/linger/testfile/crop_train_db/ /home/linger/linger/testfile/crop_train_attachment/ 3 50 50
	google::InitGoogleLogging(argv[0]);
	string src_dir = argv[1];
	string src_dst = argv[2];
	string attach_dir = argv[3];
	int channel = atoi(argv[4]);
	int width = atoi(argv[5]);
	int height = atoi(argv[6]);

	//for test
	/*
	src_dir = "/home/linger/imdata/collarTest/";
	src_dst = "/home/linger/linger/testfile/dbtest/";
	attach_dir = "/home/linger/linger/testfile/";
	channel = 3;
	width = 250;
	height = 250;
	 */

	convert(src_dir,src_dst,attach_dir,channel,width,height);



}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/118443.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • AAA认证略解[通俗易懂]

    AAA认证略解[通俗易懂]AAA是authentication(认证)、aurhorization(授权)和accounting(计费)的简称。主要是给网络接入服务器(NAS)提供一个访问控制的管理框架。定义:AAA作为网络安全的一种管理机制,以模块化的方式提供认证、授权、计费服务。其中:认证:确认访问用户的身份,判断访问者是否为合法的网络用户。授权:对不同的用户赋予不同的权限,同时限制用户可以使用的服务。计费:记录用户在网络中的所有活动,包括使用的服务类型、起始时间、数据流量等,用于收集用户对网络资源的使用情况,并且可以实

    2022年5月30日
    39
  • SSAS(2)_SSA全称

    SSAS(2)_SSA全称上1篇通过书中实验练习,开发了一个SSASCube。这里,基于这个Cube,再深入小结、试验有关SSASCube开发的扩展知识:维度属性间的关系及维度的层次结构(Hierarchies)维度与度量的关系多维数据集(Cube)KPI的实现多维数据集(Cube)行为(Action)的实现,例如:钻取多维数据集(Cube)的本地化与视图多维表达式(MDX)的应用书名:MCTSSel

    2025年7月27日
    0
  • 鼠标悬停下划线显示特效,html鼠标悬停显示下划线

    鼠标悬停下划线显示特效,html鼠标悬停显示下划线html:(index.html)<!DOCTYPEhtml><htmllang=”en”><head><metacharset=”UTF-8″><title>鼠标悬停下划线</title><linkrel=”stylesheet”href=”css/style.css”>&l…

    2022年5月16日
    49
  • Android Key获取方式

    Android Key获取方式在很多情况下,比如应用百度SDK开发Android定位或者实现网页交互,均需要获取一个key来进行调试。简单说一下在Androidstudio和eclipse中如何获取key以及如何查看相关信息,笔者是在Mac下获取的,windows也一样。1.Androidstudio中创建获取Key1>随便新建一个Android项目,点击Build下拉GenerateSignedAPK

    2022年7月23日
    18
  • 查找-散列查找

    查找-散列查找1.散列的相关概念散列技术是在记录的存储位置和它的关键字之间建立一个确定的对应关系f,使得每个关键字key对应一个存储位置f(key)。查找时,根据这个确定的对应关系找到给定值key的映射f(key),若查找集合中存在这个记录,则必定在f(key)的位置上。这里我们把这种对应关系f称为散列函数,又称为哈希(Hash)函数。按这个思想,采用散列技术将记录存储在一块连续的存储空间中,这块连续存储空间称为

    2022年5月14日
    42
  • jboss安装与配置_下载qq和安装

    jboss安装与配置_下载qq和安装JBoss下载与JBoss安装一.              下载与安装JBoss在本文中,我们下载的JBoss版本为:4.2.1.GA。下载地址:http://www.jboss.org/jbossas/downloads/在如上的下载页中下载JBoss-4.2.1.GA.zip文件。下载完成后,将其解压缩后即可完成安装,解压缩后将其放置到

    2022年10月3日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号