Linux&C++以时间批量重命名图片数据集

题目来源于计算机视觉life从零开始学SLAM作业1。我们知道,SLAM与SFM不同,SLAM是按时间序列来处理图像。所以,当我们有一个数据集且要把它用到我们的SLAM系统中,有时候数据集的命名方式可能不太友好,比如TUM的RGBD数据集中的RGB数据,是以时间命名的,为了能够把该数据集用到我们的系统上,而且又想比较方便地读取图片,我们可以批量重命名这些图像数据。(实际上,有更好的方法,用c艹实在是太笨拙了)

实际上如果是只想简单地将图片赋值为0.png、1.png…是不需要靠编程就可以实现的,见此链接

那如果用编程实现呢?有两种思路,一种是由于TUM数据集是以时间来命名的,所以可以直接把名字转换成double类型、排序最后遍历改名。第二种思路是根据修改时间来,我觉得这个会更加靠谱,因为不是所有数据集都是以时间(数字)来命名,根据修改时间来排序,岂不是更好?实际上,是我too toung too naive,由于采集时间之密集,time_t存储的时间位数不足以区分两张图像。

总体思路:于是先遍历当前文件夹的所有文件,然后把名字提取出来,把string类型的名字和long类型的时间,存进map<string,long>里,后续把map转成pair类型的vector,用sort()函数排序,最后遍历所有数,使用rename改名。

#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <map>
#include <algorithm>
#include <vector>

using namespace std;
map<string,long> mymap;
int num = 0;
struct cmp
{
    bool operator()(const pair<string,long> &p1,const pair<string,long> &p2)
    {
        return p1.second < p2.second;
    }
};
// 递归列出所有目录及文件
void scan_all_image(char *dir)
{
     DIR *p_dir = NULL;
     struct dirent *p_entry = NULL;
     struct stat statbuf;
     if((p_dir = opendir(dir)) == NULL)
     {
         printf("can't open dir.\n");
         return;
     }
     chdir (dir);

     int skip_two = 2; //需要跳过"."和".."文件
     while(NULL != (p_entry = readdir(p_dir))) { // 获取下一级目录信息
         lstat(p_entry->d_name, &statbuf); // 获取下一级成员属性
         //先跳过"."和".."文件
         if(skip_two != 0)
         {
             skip_two --;
             continue;
         }
         //输出信息
         //第一种方法:以修改时间排序 在这里不可行,精度不够,但是在时间相隔较大的图片中,是ok的
      //   cout <<"image name: " << p_entry->d_name << "  " << "modify_time : " <<long_modify_time <<  endl;
      //   mymap[p_entry->d_name] = long_modify_time;//存进map里

         string img_nam = p_entry->d_name;
         string img_cut = img_nam.substr(8, 9);   //截取s中从pos开始(包括0)的n个字符的子串,并返回
         cout <<img_cut << endl;
         long image_name = (long)(atof(img_cut.c_str()) * 1000000);
         //第二种方法:以名字排序
         cout <<"image name: " << p_entry->d_name << "  " << "time : " <<image_name <<  endl;
         mymap[p_entry->d_name] = image_name;//存进map里
     }
    chdir(".."); // 回到上级目录  
    closedir(p_dir);
}

int rename_all_image(string argv)
{
    vector<pair<string,long>>vect(mymap.begin(),mymap.end());   //把map打包成vector,方便后面用sort排序
    sort(vect.begin(),vect.end(),cmp());    //排序

    for(vector<pair<string,long>>::iterator it = vect.begin(); it != vect.end(); it ++)//遍历所有文件
    {
        cout <<"map  time  :  " << it->second << endl;
        string new_name =  argv + to_string(num) + ".png";
        string old_name = argv + it->first;
        cout << "old name :" << it->first << "  new name :" <<  to_string(num) + ".png" << endl;
        if (!rename(old_name.c_str(), new_name.c_str()))//使用rename改名
        {
            std::cout << "rename success "<< std::endl;
        }
        else
        {
            std::cout << "rename error "<< std::endl;
        }
        num++;
    }
}
int main(int argc, char* argv[])
{
    scan_all_image(argv[1]);    //发现所有文件,并存入map
    rename_all_image(argv[1]); //重命名所有图像
    return 0;
}

效果如下,挺妥。
在这里插入图片描述

参考:
https://blog.csdn.net/huangjiazhi_/article/details/80501233
https://www.cnblogs.com/achao123456/p/9676524.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这里提供一种基于Windows操作系统的C代码示例,可以批量重命名指定目录下的所有.tif格式图片,将它们改名为指定前缀加上自增序号的格式,如"prefix_001.tif", "prefix_002.tif"等。 ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <dirent.h> #include <windows.h> int main() { char* dir_path = "C:\\directory\\to\\images"; //指定目录路径 char* prefix = "new_prefix"; //指定新前缀 int count = 1; //文件计数器,从1开始 int prefix_len = strlen(prefix); char old_file_path[MAX_PATH], new_file_path[MAX_PATH]; struct dirent* entry; DIR* dir = opendir(dir_path); if (dir == NULL) { //目录打开失败 printf("Error: failed to open directory.\n"); return -1; } while ((entry = readdir(dir)) != NULL) { //遍历目录下所有文件 if (entry->d_type == DT_REG && strstr(entry->d_name, ".tif") != NULL) { //只处理.tif格式文件 sprintf(old_file_path, "%s\\%s", dir_path, entry->d_name); sprintf(new_file_path, "%s\\%s_%0*d.tif", dir_path, prefix, prefix_len, count); //生成新文件名 if (rename(old_file_path, new_file_path) != 0) { //重命名失败 printf("Error: failed to rename file %s.\n", entry->d_name); } else { printf("Renamed file %s to %s.\n", entry->d_name, new_file_path); count++; //计数器加1 } } } closedir(dir); return 0; } ``` 上述代码中,使用了Windows系统的文件重命名函数`rename()`,它的参数分别为旧文件名和新文件名,如果重命名成功则返回0,否则返回非零值。新文件名的生成使用了`sprintf()`函数,其中`%s`表示字符串格式,`%0*d`表示补零格式,具体可以参考C语言格式化输出的相关资料。 运行代码时需要将`dir_path`和`prefix`变量修改为实际值,同时需要注意目录路径中的反斜杠`\`需要转义为双反斜杠`\\`,否则会被视为转义字符导致路径错误。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值