如果你有 C++17,这会很容易,因为标准中有文件系统库(std::filesystem)。否则,我会建议您获得非常相似的 boost::filesystem(您应该很好地将所有 std::filesystem 替换为 boost::filesystem)。
要从某个文件夹加载所有图像,有 2 个辅助函数:
#include <filesystem> //for boost change this to #include <boost/filesystem> and all std:: to boost::
#include <opencv2/opencv.hpp>
bool isSupportedFileType(const std::filesystem::path& pathToFile,
const std::vector<std::string>& extensions)
{
auto extension = pathToFile.extension().string();
std::transform(extension.begin(), extension.end(), extension.begin(), [](char c)
{
return static_cast<char>(std::tolower(c));
});
return std::find(extensions.begin(), extensions.end(), extension) != extensions.end();
}
std::tuple<std::vector<cv::Mat>, std::vector<std::filesystem::path>> loadImages(const std::filesystem::path& path,
const std::vector<std::string>& extensions)
{
std::vector<cv::Mat> images;
std::vector<std::filesystem::path> names;
for (const auto& dirIt : filesystem::DirectoryIterator(path))
{
if (std::filesystem::is_regular_file(dirIt.path()) && isSupportedFileType(dirIt.path(), extensions))
{
auto mask = cv::imread(dirIt.path().string(), cv::IMREAD_UNCHANGED);
if (mask.data != nullptr) //there can be problem and image is not loaded
{
images.emplace_back(std::move(mask));
names.emplace_back(dirIt.path().stem());
}
}
}
return {images, names};
}
你可以这样使用它(假设 C++17):
auto [images, names] = loadImages("/photos/field_new/", {".jpg", ".jpeg"});
或 (C++11)
auto tupleImageName = loadImages("/photos/field_new/", {".jpg", ".jpeg"});
auto images = std::get<0>(tupleImageName);
auto names = std::get<1>(tupleImageName);
要保存你可以使用这个功能:
void saveImages(const std::filesystem::path& path,
const std::vector<cv::Mat>& images,
const std::vector<std::filesystem::path>& names)
{
for(auto i = 0u; i < images.size(); ++i)
{
cv::imwrite((path / names[i]).string(), images[i]);
}
}
像这样:
saveImages("pathToResults",images,names);
在此保存功能中,如果图像数量与名称相同,最好执行一些验证,否则可能会出现超出矢量边界的问题。