我有一个从文件夹中读取图像的程序。我使用for来访问文件的所有索引并将它们存储到向量中:
for(int i=0; i<labels.size(); i++){
ostringstream stringStream;
stringStream << setfill ('0') << setw (4) << i;
num2string = stringStream.str();
string img = "C:\\opencvAssets/detected/BioID_"+num2string+".pgm";
//cout<< img <<" \n";
images.push_back(imread(img, CV_LOAD_IMAGE_GRAYSCALE)); //labels.push_back(i);
}
我遇到了一些麻烦,因为文件夹中缺少某些文件。因此,对于接近是令人望而却步的。如何读取所有文件并将它们存储到矢量中?
答案 0 :(得分:4)
首先,您需要扫描目录并获取文件:
您可以使用FindFirstFile和FindNextFile
bool find_files(){
WIN32_FIND_DATA FindFileData;
string img = "C:\\opencvAssets/detected/BioID_*.pgm";
HANDLE hFind = FindFirstFile(img.c_str(), &FindFileData);
if(hFind == INVALID_HANDLE_VALUE){
return false;
}
else do{
cout<<FindFileData.cFileName<<endl;
} while (FindNextFile(hFind, &FindFileData));
FindClose(hFind);
return true;
}
修改强>
对于Linux:,您可以检查here如何迭代目录,但最好的方法是使用fork
和execv
运行{{1命令并使用管道获取输出。 like this
<强> EDIT2 强> 从终端,您可以找到所有这样的文件:
find
因此,您可以通过重定向到文件或使用find path/to/dir -name 'BioID_*.pgm'
和fork
来运行它。如果您不是一个简单的解决方案,请使用execv
并重定向到文件,并使用所有已创建的文件名打开该文件。
答案 1 :(得分:3)
补丁:
if (Cv::mat m = imread(img, CV_LOAD_IMAGE_GRAYSCALE)) images.push_back(m);
但是对于严肃的任务,请使用boost :: filesystem来限制对实际现有文件的访问。
答案 2 :(得分:3)
在Linux上你可以这样做:
1)创建DIR指针, 使用opendir()
打开目录DIR * ptr = opendir(path_of_directory);
2)创建struct dirent指针, 使用readdir();
从目录中读取文件struct dirent * ptr = readdir(ptr); //传递DIR指针
3)在while循环中运行上面的内容。推送向量中的数据,该向量作为参考传递给此函数或返回向量。
4)确保“。”并且“..”不是文件,所以不要在向量中推送它。 //要检查这个,你可以使用std :: strcmp(dirent_pointer-&gt; d_name,“。”)== 0 所以.. if(!std :: strcmp(ptr-&gt; d_name,“。”)== 0)
希望有所帮助
答案 3 :(得分:2)
与SHR的示例一样,您需要扫描目录并获取文件。 您可以在每个Unix平台上使用特定于Windows的实现或dirent.h中的函数。
有关Unix上dirent.h的更多信息,请参阅this question。
答案 4 :(得分:1)
您可以使用boost :: filesystem。但是,这不是一个仅头文件库,您可能有要求不与外部库链接,或者这样做可能非常不方便。 在Windows上(看起来像你)我喜欢使用这个类来获得与给定模式匹配的所有文件名。
#pragma once
#include <string>
#include <vector>
#include <windows.h>
#pragma comment(lib, "User32.lib")
#undef tstring
#undef tcout
#if defined(_UNICODE) || defined(UNICODE)
#define tstring std::wstring
#define tcout std::wcout
#else
#define tstring std::string
#define tcout std::cout
#endif
class FileFinder {
WIN32_FIND_DATA ffd;
HANDLE _handle;
public:
FileFinder(LPCTSTR pattern) { _handle = FindFirstFile(pattern, &ffd); }
~FileFinder() { FindClose(_handle); }
const TCHAR *FindFirst() const {
return _handle != INVALID_HANDLE_VALUE ? ffd.cFileName : nullptr;
}
const TCHAR *FindNext() {
return FindNextFile(_handle, &ffd) ? ffd.cFileName : nullptr;
}
std::vector<tstring> GetAllNames() {
std::vector<tstring> result;
for (auto name = FindFirst(); name; name = FindNext())
result.push_back(name);
return result;
}
};
遵循RAII范例,不会因异常而泄漏资源。 它的用法示例可能是这样的。
#include <tchar.h>
#include <iostream>
#include "FileFinder.h"
int _tmain(int argc, TCHAR *argv[]) {
DWORD dwError = 0;
if (argc != 2) {
_tprintf(TEXT("\nUsage: %s <directory name>\n"), argv[0]);
return -1;
}
tstring pattern(argv[1]);
pattern.erase(pattern.find_last_not_of(TEXT("\\")) + 1);
pattern += TEXT("\\*.pgm");
if (pattern.length() > MAX_PATH) {
_tprintf(TEXT("\nDirectory path is too long.\n"));
return -1;
}
FileFinder finder(pattern.c_str());
auto files = finder.GetAllNames();
for (const auto &f : files)
tcout << f << std::endl;
return 0;
}