从目录中/在目录中加载/保存多个图像-opencv c ++

时间:2018-07-30 11:05:06

标签: c++ image opencv save load

我想从目录中加载很多图像(虽然不是顺序名称)。编辑它们,然后尽可能使用原始名称将它们保存在其他目录中。 我这样加载它们:

glob("/photos/field_new/*.jpg", fn, false);
size_t count = fn.size(); //number of jpg files in images folder
for (size_t i=0; i<count; i++)
    images.push_back(imread(fn[i]));

任何想法如何将它们保存在目录/ photos / results /中? 并尽可能使用其原始名称?

1 个答案:

答案 0 :(得分:0)

如果您具有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);

在此保存功能中,如果图像数量与名称相同,最好进行一些验证,否则可能会出现在矢量边界之外的问题。