OpenCV获取文件夹下所有文件名

本文介绍了OpenCV中Directory类的使用方法,该类能够帮助开发者遍历指定目录下的所有文件及子文件夹中的文件。文章详细展示了如何利用GetListFiles、GetListFolders和GetListFilesR函数获取文件列表,并提供了一个递归遍历文件夹的示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、OpenCV中有实现遍历文件夹下所有文件的类Directory,它里面包括3个成员函数:(1)、GetListFiles:遍历指定文件夹下的所有文件,不包括指定文件夹内的文件夹;(2)、GetListFolders:遍历指定文件夹下的所有文件夹,不包括指定文件夹下的文件;(3)、GetListFilesR:遍历指定文件夹下的所有文件,包括指定文件夹内的文件夹。

若要使用Directory类,则需包含contrib.hpp头文件,此类的实现在contrib模块。

        string path1 = "E:\\代码转化\\synopsis\\坐标信息2"

       string exten1 = "*.txt";

       bool addPath1 = false; 
       vector<string> filenames = dir.GetListFiles(path1, exten1, addPath1);  

注:这样获得的 filenames中,只存储 文件夹 path1 下的文件名,不是全部路径;

      下面的代码可以获得 path1 下的文件的完整的路径    ;

      但是两者存储的顺序都很奇怪:例如path1下有12个txt文件,则输出后的顺序都是:1.txt,10.txt,11.txt,12.txt,2.txt,3.txt等等


二、 

void GetAllFileInfo(char* path, vector<char*> &filesPathVector)
{
    //find the first file
    _tfinddata_t c_file;
    intptr_t hFile;
   
char root[MAX_PATH];
strcpy(root,path);
strcat(root,"\\*.*");
   
   
    hFile=_tfindfirst(CA2CT(root),&c_file);
    if( hFile  == -1)
        return;
 
    //search all files recursively.
    do
    {
        if(_tcslen(c_file.name)==1&&c_file.name[0]==_T('.')
            ||_tcslen(c_file.name)==2&&c_file.name[0]==_T('.')&&c_file.name[1]==_T('.'))
            continue;
     


char* fullPath=new char[MAX_PATH];
   strcpy(fullPath,path);
   strcat(fullPath,"\\");


char* name=(char*)malloc(2*wcslen(c_file.name)+1);
wcstombs(name,c_file.name,2*wcslen(c_file.name)+1);
strcat(fullPath,name);


        if(c_file.attrib&_A_SUBDIR)
        {
            GetAllFileInfo(fullPath,filesPathVector);
        }
        else
        {
            //store full file path in vector.
//char pr=*fullPath;
            filesPathVector.push_back(fullPath);



            //print file info
        
        }
    }
    while( _tfindnext( hFile, &c_file ) == 0);
    //close search handle
    _findclose(hFile);
}


<think>我们有一个任务:使用C++和OpenCV读取一个文件夹中的所有图像。根据引用内容,有多种方法可以实现这个目标。下面我们将介绍两种主要方法:方法一:使用glob函数获取所有图像路径,然后逐一读取(如引用[1]和[2]所示)方法二:如果图像有规律的数字命名,可以使用循环和sprintf来构建路径(如引用[3]所示)我们更推荐方法一,因为方法一不需要图像名称有规律,可以读取任意名称的图像文件。下面我们详细介绍方法一:步骤:1.包含必要的头文件:<opencv2/opencv.hpp>和<iostream>2.使用cv::glob函数获取文件夹中所有匹配模式的文件路径(例如,模式可以是"folder_path/*.png")3.遍历这些路径,使用cv::imread读取图像并存储到容器中(如std::vector<cv::Mat>)注意:在读取图像时,我们可能需要检查图像是否成功读取(避免空图像)。根据引用[1]和[2],我们可以编写如下代码:```cpp#include<opencv2/opencv.hpp>#include<iostream>#include<vector>intmain(){//设置图像路径模式,例如读取所有png图像cv::Stringpattern="your_folder_path/*.png";//请替换为你的文件夹路径和文件扩展名//存储文件名的容器std::vector<cv::String>fileNames;//使用glob函数获取所有匹配的文件路径cv::glob(pattern,fileNames,false);//false表示不递归搜索子目录//存储图像的容器std::vector<cv::Mat>images;//遍历所有文件路径for(size_ti=0;i<fileNames.size();i++){//读取图像cv::Matimg=cv::imread(fileNames[i]);//检查图像是否成功读取if(img.empty()){std::cerr<<"Failedtoreadimage:"<<fileNames[i]<<std::endl;continue;}//将图像存入容器images.push_back(img);//显示图像(可选)cv::imshow("Image",img);cv::waitKey(1000);//显示1000毫秒,即1秒cv::destroyAllWindows();//关闭窗口}return0;}```说明:-请将"your_folder_path/*.png"替换为实际的文件夹路径和文件扩展名(如*.jpg,*.png等)。-如果文件夹中有多种格式的图片,可以使用多个模式多次调用glob,或者使用一个模式匹配多种扩展名(例如"folder_path/*.*"),但这样可能会读取非图像文件,所以最好确保文件夹中只有图像文件。另外,引用[3]提供了一种基于数字命名规则的读取方法,适用于图像文件名是连续数字的情况。例如:```cpp#include<opencv2/opencv.hpp>#include<iostream>#include<cstdio>//forsprintfintmain(){//假设图像文件名是1.jpg,2.jpg,...存放在"E:\\Download\\Images\\"charfilePath[100];std::vector<cv::Mat>images;for(inti=1;i<=10;i++){//假设有10张图片sprintf(filePath,"E:\\Download\\Images\\%d.jpg",i);cv::Matimg=cv::imread(filePath);if(img.empty()){std::cerr<<"Failedtoreadimage:"<<filePath<<std::endl;break;//或者continue}images.push_back(img);//显示图像(可选)cv::imshow("Image",img);cv::waitKey(1000);cv::destroyAllWindows();}return0;}```但这种方法不够灵活,如果文件名不是数字或者有间断,就可能读取失败。因此,我们推荐使用第一种方法(glob)。注意:OpenCV的glob函数在Windows和Linux下都可用,但路径字符串的格式可能不同(Windows使用反斜杠,Linux使用正斜杠)。在Windows中,路径中的反斜杠需要转义(即使用两个反斜杠),或者使用正斜杠(OpenCV支持正斜杠)。例如,在Windows中:cv::Stringpattern="C:\\my_images\\*.jpg";//需要转义或者cv::Stringpattern="C:/my_images/*.jpg";//使用正斜杠,推荐这样我们就可以读取一个文件夹中的所有图像了。相关问题:1.如何读取文件夹中的图像?2.如何批量处理图像并保存到另一个文件夹?3.如何提高批量读取图像的性能(例如使用多线程)?4.读取图像时如何跳过损坏的文件?5.如何支持多种图像格式(如同时读取jpg和png)?</think>以下是如何使用C++和OpenCV读取文件夹中所有图像的解决方案,结合了引用中的最佳实践: ### 解决方案 #### 方法1:使用`glob`函数(推荐) ```cpp #include <opencv2/opencv.hpp> #include <vector> int main() { // 设置图像路径模式(支持通配符*) cv::String pattern = "your_folder_path/*.png"; // 修改为你的路径和格式 // 获取匹配的文件名列表 std::vector<cv::String> fileNames; cv::glob(pattern, fileNames, false); // false表示不递归子目录 // 存储图像的容器 std::vector<cv::Mat> images; for (size_t i = 0; i < fileNames.size(); i++) { // 读取图像 cv::Mat img = cv::imread(fileNames[i], cv::IMREAD_COLOR); // 检查是否读取成功 if (img.empty()) { std::cerr << "Failed to read: " << fileNames[i] << std::endl; continue; } images.push_back(img); // 存入容器 // 显示图像(可选) cv::imshow("Image Viewer", img); cv::waitKey(500); // 显示500毫秒 } cv::destroyAllWindows(); return 0; } ``` **特点**: - 自动获取所有匹配文件路径 - 支持各种图像格式(`.jpg`, `.png`等) - 无需预先知道文件数量 - 内置空图像检查[^1][^2] #### 方法2:数字序列命名法(适用于规律命名) ```cpp #include <opencv2/opencv.hpp> #include <cstdio> // for sprintf int main() { std::vector<cv::Mat> images; char filePath[256]; // 假设图像名为 1.jpg, 2.jpg... for (int i = 1; i <= 100; i++) { // 修改循环范围 sprintf(filePath, "your_folder_path/%d.jpg", i); // 修改路径格式 cv::Mat img = cv::imread(filePath); if (!img.empty()) { images.push_back(img); // 可添加处理代码... } } return 0; } ``` **适用场景**:已知图像命名规律和数量时[^3] ### 关键说明 1. **路径格式注意**: - Windows路径需转义:`"C:\\folder\\*.jpg"` - 或使用正斜杠:`"C:/folder/*.jpg"` 2. **扩展名支持**: ```cpp cv::glob("folder/*.*", fileNames); // 读取所有文件 cv::glob("folder/*.{png,jpg}", fileNames); // 多格式支持 ``` 3. **递归读取子目录**: ```cpp cv::glob(pattern, fileNames, true); // 第三个参数设为true ``` 4. **性能优化**: - 移除`imshow`和`waitKey`可提升速度 - 预分配内存:`images.reserve(fileNames.size());` ### 常见问题解决 - **读取失败检查**:始终验证`img.empty()` - **内存管理**:大型数据集建议使用`std::vector<cv::Mat>`而非数组 - **编码问题**:路径包含中文时需确保系统区域设置正确 > 提示:在实际应用中,推荐使用方法1的`glob`方式,因其更灵活且能自动处理文件系统差异[^1][^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值