Ask Your Question
0

reading a sequence of files within a folder

asked 2015-03-23 02:46:44 -0500

KansaiRobot gravatar image

updated 2015-03-24 09:55:47 -0500

theodore gravatar image

Hello and thanks always.

This question has been asked several times on the internet it seems but none of the replies work so I come here dedicated only to opencv.

I want to open a series of images stored on a file (or what they call a "sequence of files")

I read in the opencv documentation (and also on several forums) to use video capture as:

Parameters:
filename – name of the opened video file (eg. video.avi) or image sequence (eg. img_%02d.jpg, which will read samples like img_00.jpg, img_01.jpg, img_02.jpg, ...)

This however doesnt work. My files don't get recognized.

Let me give you the format of the names of my files.

s640_016_1@5.jpg

so I tried "s640_%03d_%01d@%01d.jpg"

Do this "%0x" thing really work? Do I have to use escape characters? I have tried putting \ or like this

Or if not How can I read a sequence of files in a folder???

Thanks a thousand

edit retag flag offensive close merge delete

Comments

1

Have tried with a single (and not three) %03d?

FooBar gravatar imageFooBar ( 2015-03-23 03:01:17 -0500 )edit

apparently for some reason it works for

s640_01%01d_1@5.jpg

which gives me a very limited (10 at max) sequence of files. But not for others...

KansaiRobot gravatar imageKansaiRobot ( 2015-03-23 03:23:21 -0500 )edit

@KansaiRobot, mark answers if it was helpful

Spark gravatar imageSpark ( 2015-03-23 05:45:46 -0500 )edit

2 answers

Sort by » oldest newest most voted
9

answered 2015-03-23 08:32:31 -0500

theodore gravatar image

updated 2015-03-24 07:24:53 -0500

edit: It seems that there is an embedded function (many thanks to @berak for pointing that out) that does this job, have a look on the example below:

int main()
{
    vector<String> filenames; // notice here that we are using the Opencv's embedded "String" class
    String folder = "<some_folder_path>"; // again we are using the Opencv's embedded "String" class

    glob(folder, filenames); // new function that does the job ;-)

    for(size_t i = 0; i < filenames.size(); ++i)
    {
        Mat src = imread(filenames[i]);

        if(!src.data)
            cerr << "Problem loading image!!!" << endl;

        /* do whatever you want with your images here */
    }
}

this is what I am using so far with success:

// 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

/* Returns a list of files in a directory (except the ones that begin with a dot) */

void 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
} // GetFilesInDirectory

int main()
{
    string folder = "/documents/images/";
    vector<string> filenames;

    readFilenames(filenames, folder);

    for(size_t i = 0; i < filenames.size(); ++i)
    {
        Mat src = imread(folder + filenames[i]);

        if(!src.data)
            cerr << "Problem loading image!!!" << endl;

        /* do whatever you want with your images here */
    }
}

an alternative is to use the boost library check below:

// files you need to include, do not forget to include the -lboost_filesystem and -lboost_system libraries otherwise you will get quite some errors/complaints during the compilation
#include <boost/filesystem.hpp>
using namespace boost::filesystem;

void readFilenamesBoost(vector<string> &filenames, const string &folder)
{
    path directory(folder);
    directory_iterator itr(directory), end_itr;

    string current_file = itr->path().string();

    for(;itr != end_itr; ++itr)
    {
// If it's not a directory, list it. If you want to list directories too, just remove this check.
       if (is_regular_file(itr->path()))
       {
       // assign current file name to current_file and echo it out to the console.
//            string full_file_name = itr->path().string(); // returns full path
            string filename = itr->path().filename().string(); // returns just filename
            filenames.push_back(filename);
       }
    }
}

int main()
{
    string folder = "/documents/images/";
    vector<string> filenames;

    readFilenamesBoost(filenames, folder);

    for(size_t i = 0; i < filenames.size(); ++i)
    {
        Mat src = imread(folder + filenames[i]);

        if(!src.data)
            cerr << "Problem loading image!!!" << endl;

        /* do whatever you want with your images here */
    }
}
edit flag offensive delete link more

Comments

3

opencv already has such a function builtin !

berak gravatar imageberak ( 2015-03-23 08:40:35 -0500 )edit
1

@berak, ok I did not know about that. I guess that it is quite new. Very nice.

theodore gravatar imagetheodore ( 2015-03-23 09:01:26 -0500 )edit

I have tested it and it is practical. It would be nice though if there also was the functionality to obtain only the filename and not always the absolute path.

theodore gravatar imagetheodore ( 2015-03-23 09:06:40 -0500 )edit

@berak I am sorry, I don't grasp your comment. To what >>such a function<< are you referring ?? (would help to have the precise name)

@theodore Thanks, I will try your solution. I was hoping opencv had something simpler but if not then listing the files and put them on a vector would help

KansaiRobot gravatar imageKansaiRobot ( 2015-03-23 19:33:34 -0500 )edit
1

@KansaiRobot the function that @berak refers to is the glob(), and you can use it as follows:

vector<String> results; // notice here that we are using the Opencv's embedded "String" class
String patern = "<some_folder_path>"; // again we are using the Opencv's embedded "String" class
glob(patern, results);

and you will get the absolute path of the files within the results vector.

theodore gravatar imagetheodore ( 2015-03-23 20:16:40 -0500 )edit

Thank you very much. I ll post that as the answer (but apparently tomorrow since the site says "New users must wait 2 days to answer own questions"....

KansaiRobot gravatar imageKansaiRobot ( 2015-03-23 21:30:12 -0500 )edit
1

@KansaiRobot I added it this way to the main answer ;-)

theodore gravatar imagetheodore ( 2015-03-24 07:23:17 -0500 )edit
0

answered 2015-03-23 05:39:51 -0500

Spark gravatar image

You can refer to OpenCV samples. Many samples use this such concept. Here is one from \opencv\sources\samples\cpp\stereo_calib.cpp.

  1. Create a text file with list of image names along with path to be processed.
  2. Following code opens the text file and prepares the list of file names.

    FILE* f = fopen("ImageList.txt", "r");
    vector<string> imagelist;
    for(int i = 0; ; i++)
    {
    if(!fgets(buf, sizeof(buf)-3, f))
        break;
    size_t len = strlen(buf);
    
    while(len > 0 && isspace(buf[len-1]))
        buf[--len] = '\0';
    
    if(buf[0] == '#')
        continue;
    
    imagelist.push_back(buf);
    }
    fclose(f);
    
  3. Start accessing images by imread(imagelist[i])

edit flag offensive delete link more

Comments

The solution given by Theodor takes into account all files with extension e.g. .png ? In order to read and to show the second image in the folder for example how I use it ?

harfbuzz gravatar imageharfbuzz ( 2016-10-13 10:39:14 -0500 )edit

thanks a lot,

harfbuzz gravatar imageharfbuzz ( 2016-10-13 10:41:50 -0500 )edit
Login/Signup to Answer

Question Tools

2 followers

Stats

Asked: 2015-03-23 02:46:44 -0500

Seen: 20,345 times

Last updated: Mar 24 '15