# How to read directory with images by VideoCapture?

I know it is not officially supported yet, but I would like to read images in a directory numbered as 1.png, 2.png ... 137.png using VideoCapture.

While browsing the source code I saw CvCapture_Images class which can read images one by one using a printf like pattern. I can't seem to make it work. I have tried:

VideoCapture cap("c:/fullpath/1.png");


and

VideoCapture cap("c:/fullpath/%d.png");


Neither of them worked, the first one was able to read only 1.png but not the rest of the images. Latter one was not able to open the capture at all.

How can I make VideoCapture work to read images named nicely?

Because I don't have enough reputation I can't add this as an answer, so here it goes, you can do either:

VideoCapture cap("c:/fullpath/1.png");


OR

VideoCapture cap("c:/fullpath/%1d.png");


the reason it didn't work the first time is that there is a bug with CvCapture_Images [1] where fullpath contains digits the first method fails. The latter method works as long as you specify using %#d format, i.e. don't forget to put at least one digit before d.

See the sammy's alternative answer below.

edit retag close merge delete

Sort by » oldest newest most voted

That's an interesting feature in OpenCV, so bad it's not documented.

I've spent a few hours trying to figure it out, some time ago. But this is how you should use it:

VideoCapture cap("c:/fullpath/%03d.png");


Supposing your images are 001.png, 002.png, etc. You can also use something like

VideoCapture cap("c:/fullpath/Image_%03d.png"); // for Image_001.png, etc


If your files are 1.png, 2.png, ..., 10.png, ...101.png, you have to convert them to a proper naming format, all having the same number of digits in name. Total Commander (Multi-rename) for Windows and any command line utility in Linux wil do the job for you.

more

I already included the answer in my question 1 hour ago :) I don't have the reputation to upvote you but I will accept your answer. There is a bug with VideoCapture though.

( 2012-07-25 08:43:48 -0500 )edit

Yeah, I saw that I posted the answer just minutes after you. My mistake

( 2012-07-25 08:51:58 -0500 )edit
( 2014-07-28 13:46:54 -0500 )edit
1

I think the proper explanation for: 'VideoCapture cap("c:/fullpath/Image_%03d.png")'

is this: here "image_%03d" shows that program should expect every file name starting as "image_" and after that "%03d" indicates that take 3 digit entries as "001" and accept 'integer increment' i.e. "000", "001", "002"etc. That is why in your case "%1d" works. Similarly if someone has image sequence named as "img-01.jpg", "img-02.jpg", "img-03.jpg" etc. he should use "/img-%02.jpg".

( 2016-10-13 10:47:17 -0500 )edit

I had a similar need as you did, I solved the problem with boost filesystem library.

For file scanning with boost, it would look something like this:

int scanFiles( const path & directory, string filterFileType)
{
int fileCount=0;
if( exists( directory ) )
{
directory_iterator end ;
for( directory_iterator iter(directory) ; iter != end ; ++iter )
if ( (is_regular_file( *iter ) && iter->path().extension().string() == filterFileType))
{
cout << iter->path().filename().string() << endl ; //this is the one of scanned file names
fileCount++;
}
}
return fileCount;
}


Basically what that function does (at least in my app), returns the count of files with a specified extension. So scanFiles("labels", "png"); will return me the number of png files in directory labels.

While scanning you can return or update global Mat variable and use it to do your stuff.

But I don't think that OpenCV can scan through files natively.

more

Basically check this out, they have a nice tutorial for the filesystem as well: http://www.boost.org/doc/libs/1500/libs/filesystem/doc/index.htm

( 2012-07-13 08:08:37 -0500 )edit

If your images have different size, be sure to capture the largest first (by naming it 001 e.g.), otherwise you may get a memory access fault. Further the step size is not adapted by VideoCapture (opencv 2.4.2.). After

 cap >> Img;


you may need

 // correct false step size for images of different size
Img.step = Img.elemSize()*Img.cols;

more

If you are working in Windows and don't want to use boost you can do it like that (include Windows.h beforehand):

WIN32_FIND_DATA found;
HANDLE hfind;

vector<Mat> images;
int fileCount=0;

hfind=FindFirstFile("C:\\path\\baseFilename???.jpg",&found);
if(hfind!=INVALID_HANDLE_VALUE)
do
{
fileCount++;
}while(FindNextFile(hfind,&found));


Hope someone will find it useful. I wish VideoCapture worked like that. I mean, it would use wildcards and load all the files in the directory in alphabetical order even if some consecutive files are missing.

more

Official site

GitHub

Wiki

Documentation