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 <iostream>  
#include <io.h>  //對系統文件進行操作的頭文件
#include <string>  
#include <sstream>
#include <vector>

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++,一步就解決問題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章