目的:
對於做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++,一步就解決問題。