Ask Your Question
3

load multiple images from a single folder

asked 2015-08-30 04:47:16 -0600

Fabrizio gravatar image

updated 2020-10-23 08:10:59 -0600

Hi everyone, I'm using opencv and C++ and I need to load multiple images from a single folder. In particular, I want to store images in a Vector<mat> object using push_back method.

Can someone help me?

Best regards, Fabrizio

edit retag flag offensive close merge delete

2 answers

Sort by ยป oldest newest most voted
9

answered 2015-08-30 05:06:13 -0600

berak gravatar image

updated 2015-08-30 05:26:25 -0600

with the help of glob it is pretty easy:

cv::String path("lfw3d_9000/*.jpg"); //select only jpg
vector<cv::String> fn;
vector<cv::Mat> data;
cv::glob(path,fn,true); // recurse
for (size_t k=0; k<fn.size(); ++k)
{
     cv::Mat im = cv::imread(fn[k]);
     if (im.empty()) continue; //only proceed if sucsessful
     // you probably want to do some preprocessing
     data.push_back(im);
}
edit flag offensive delete link more

Comments

1

here i have a question. according to my need i made a correction to source of the function glob as below (definition summary)

typedef bool ( *GlobCallback )( String filename );

void glob(String pattern, GlobCallback onFileFound, bool recursive)
{
// instead of adding filenames to vector. calls defined function.
}

here is my implemention.you can see and try. what is your opinion about it. may I make a Pull Request to add this functionality by overload or another function.

sturkmen gravatar imagesturkmen ( 2015-08-30 13:28:25 -0600 )edit
0

answered 2017-06-14 02:42:53 -0600

From elsewhere, but even more complete:

Yes, Boost is great, but it's a bit bloaty. So, just for completenessapplied to reading images in a directory for OpenCV:

// you need these includes for the function
//#include <windows.h> // for windows systems
#include <dirent.h> // for linux systems
#include <sys/stat.h> // for linux systems
#include <algorithm>    // std::sort
#include <opencv2/opencv.hpp>
#include <iostream>   //cout

using namespace std;

/* Returns a list of files in a directory (except the ones that begin with a dot) */
int readFilenames(std::vector<string> &filenames, const string &directory)
{
#ifdef WINDOWS
    HANDLE dir;
    WIN32_FIND_DATA file_data;

    if ((dir = FindFirstFile((directory + "/*").c_str(), &file_data)) == INVALID_HANDLE_VALUE)
        return; /* No files found */

    do {
        const string file_name = file_data.cFileName;
        const string full_file_name = directory + "/" + file_name;
        const bool is_directory = (file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;

        if (file_name[0] == '.')
            continue;

        if (is_directory)
            continue;

        filenames.push_back(full_file_name);
    } while (FindNextFile(dir, &file_data));

    FindClose(dir);
#else
    DIR *dir;
    class dirent *ent;
    class stat st;

    dir = opendir(directory.c_str());
    while ((ent = readdir(dir)) != NULL) {
        const string file_name = ent->d_name;
        const string full_file_name = directory + "/" + file_name;

        if (file_name[0] == '.')
            continue;

        if (stat(full_file_name.c_str(), &st) == -1)
            continue;

        const bool is_directory = (st.st_mode & S_IFDIR) != 0;

        if (is_directory)
            continue;

//        filenames.push_back(full_file_name); // returns full path
        filenames.push_back(file_name); // returns just filename
    }
    closedir(dir);
#endif
    std::sort (filenames.begin(), filenames.end()); //optional, sort the filenames
    return(filenames.size()); //Return how many we found
} // GetFilesInDirectory


void help(const char **argv) {
  cout << "\n\n"
       << "Call:\n" << argv[0] << " <directory path>\n\n"
       << "Given a directory of images, create a vector of\n"
       << "their names, read and display them. Filter out\n"
       << "non-images\n"
       << endl;
}

int main( int argc, const char** argv )
{
    if(argc != 2) {
        cerr << "\nIncorrect number of parameters: " << argc << ", should be 2\n" << endl;
        help(argv);
        return -1;
    }
    string folder = argv[1];
    cout << "Reading in directory " << folder << endl;
    vector<string> filenames;

    int num_files = readFilenames(filenames, folder);
    cout << "Number of files = " << num_files << endl;
    cv::namedWindow( "image", 1 );
    for(size_t i = 0; i < filenames.size(); ++i)
    {
        cout << folder + filenames[i] << " #" << i << endl;
        cv::Mat src = cv::imread(folder + filenames[i]);

        if(!src.data) { //Protect against no file
            cerr << folder + filenames[i] << ", file #" << i << ", is not an image" << endl;
            continue;
        }
        cv::imshow("image", src);
        cv::waitKey(250); //For fun, wait 250ms, or a quarter of a second, but you can put in "0" for no wait or -1 to wait for keypresses
        /* do whatever you want with your images here */
    }
}
edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2015-08-30 04:47:16 -0600

Seen: 23,516 times

Last updated: Aug 30 '15