python & c++ 批量命名文件夹内的图像

目的:

对于做SLAM也好,还是做深度学习也好,涉及到大量的数据,系统对数据处理的时候,需要对比较规范的数据格式进行处理,往往我们提取的图像数据命名并不是那么规范,因此需要对采集的图像信息规范命名。
以python2为例:
本来我提取的数据为按照时间戳作为图像名保存的图像序列,现在想把它改成按照 000000.png 000001.png ...这样的形式进行处理,这样就可以进行类似kitti的形式跑这个数据集。

方法

# -*- coding:utf8 -*-

import os

class BatchRename():
    '''
    批量重命名文件夹中的图片文件

    '''
    def __init__(self):
        self.path = '/home/andy/data/kitti_test'

    def rename(self):
        filelist = os.listdir(self.path)
        total_num = len(filelist)
        i = 0
        for item in filelist:
            if item.endswith('.png'):
                src = os.path.join(os.path.abspath(self.path), item)
                dst = os.path.join(os.path.abspath(self.path), str(i).zfill(6) + '.png')
                # 上句是核心,如果仅仅是想命名为按照顺序的图像,比如1.png,2.png,那就改成下面的形式
                # dst = os.path.join(os.path.abspath(self.path), str(i) + '.png')
                try:
                    os.rename(src, dst)
                    print 'converting %s to %s ...' % (src, dst)
                    i = i + 1
                except:
                    continue
        print 'total %d to rename & converted %d jpgs' % (total_num, i)

if __name__ == '__main__':
    demo = BatchRename()
    demo.rename()

出现的问题:

对原本的数据命名的时候,并没有按照其原先排列的顺序进行命名,这让我感到很懵逼…暂时没有解决这个问题。

解决方案:

用python没能解决上述问题,主要是不知道这里面的机制是什么。下面使用c++的方式进行rename:

#include   
#include   //对系统文件进行操作的头文件
#include   
#include 
#include 

using namespace std;

const int N = 6;   //整型格式化输出为字符串后的长度,例如,N=6,则整型转为长度为6的字符串,12转为为000012

const string FileType = ".png";    // 需要查找的文件类型,注意修改

			   /* 函数说明 整型转固定格式的字符串
			   输入:
			   n 需要输出的字符串长度
			   i 需要结构化的整型
			   输出:
			   返回转化后的字符串
			   */
string int2string(int n, int i)
{
	char s[BUFSIZ];
	sprintf(s, "%d", i);
	int l = strlen(s);  // 整型的位数

	if (l > n)
	{
		cout << "整型的长度大于需要格式化的字符串长度!";
	}
	else
	{
		stringstream M_num;
		for (int i = 0; i < n - l; i++)
			M_num << "0";
		M_num << i;

		return M_num.str();
	}
}

int main()
{
	_finddata_t c_file;   // 查找文件的类

	string File_Directory = "D:\\data\\src";   //文件夹目录,注意使用的是双斜杠

	string buffer = File_Directory + "\\*" + FileType;

	//long hFile;  //win7系统,_findnext()返回类型可以是long型
	intptr_t hFile;   //win10系统 ,_findnext()返回类型为intptr_t ,不能是long型

	hFile = _findfirst(buffer.c_str(), &c_file);   //找第一个文件

	if (hFile == -1L)   // 检查文件夹目录下存在需要查找的文件
		printf("No %s files in current directory!\n", FileType);
	else
	{
		printf("Listing of files:\n");

		int i = 0;
		string newfullFilePath;
		string oldfullFilePath;
		string str_name;
		do
		{
			oldfullFilePath.clear();
			newfullFilePath.clear();
			str_name.clear();

			//旧名字
			oldfullFilePath = File_Directory + "\\" + c_file.name;

			//新名字
			//++i; //从000001.png开始,如果需要取消注释
			str_name = int2string(N, i);    //整型转字符串
			++i;//从 000000.png开始,如果需要从000001.png,则注释这行,取消上面注释
			newfullFilePath = File_Directory + "\\" + str_name + FileType;

			/*重命名函数rename(const char* _OldFileName,const char* _NewFileName)
			第一个参数为旧文件路径,第二个参数为新文件路径*/
			int c = rename(oldfullFilePath.c_str(), newfullFilePath.c_str());

			if (c == 0)
				puts("File successfully renamed");
			else
				perror("Error renaming file");

		} while (_findnext(hFile, &c_file) == 0);  //如果找到下个文件的名字成功的话就返回0,否则返回-1  
		_findclose(hFile);
	}

	return 0;
}

把图像名保存到txt

如果想把所有图像的名字保存到txt中,那就使用下面的方式:

# -*- coding:utf8 -*-
import os
f = open('/home/andy/a.txt','w')#改成你想保存的txt的路径及名字
for root, dirs, files, in os.walk('/home/andy/rgb',True):
	for file in files:
		f.writelines(file)
		f.write('\n')

至于这步,是有个缺陷的,那就是具有随机性,而不具有顺序性,你会发现你保存的txt里面的名字和你的图像序列并不是对应的,txt的文件名顺序不符合原来的图像顺序,是随机的。不知道是否满足你的需求,我的方法是由于我是按照时间戳命名的,那我就按时间对这个txt进行升序操作就可以了。方法是使用notepad++,一步就解决问题。

你可能感兴趣的:(python,python,c++,文件夹处理)