Ask Your Question
8

How to read directory with images by VideoCapture?

asked 2012-07-13 06:28:06 -0600

Baris Evrim Demiroz gravatar image

updated 2012-07-26 02:15:20 -0600

Kirill Kornyakov gravatar image

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?

Answer

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 flag offensive close merge delete

4 answers

Sort by ยป oldest newest most voted
12

answered 2012-07-25 07:33:38 -0600

sammy gravatar image

updated 2012-07-25 07:34:14 -0600

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.

edit flag offensive delete link more

Comments

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.

Baris Evrim Demiroz gravatar imageBaris Evrim Demiroz ( 2012-07-25 08:43:48 -0600 )edit

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

sammy gravatar imagesammy ( 2012-07-25 08:51:58 -0600 )edit
ben2316 gravatar imageben2316 ( 2014-07-28 13:46:54 -0600 )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".

pythonuser gravatar imagepythonuser ( 2016-10-13 10:47:17 -0600 )edit
0

answered 2014-07-11 18:02:09 -0600

Witek gravatar image

updated 2014-07-11 18:05:03 -0600

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++;
        images.push_back(imread(found.cFileName)); 
    }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.

edit flag offensive delete link more
2

answered 2013-05-30 06:10:52 -0600

Holger gravatar image

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;
edit flag offensive delete link more
4

answered 2012-07-13 08:00:56 -0600

XCoder gravatar image

updated 2012-07-13 09:55:02 -0600

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.

edit flag offensive delete link more

Comments

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

XCoder gravatar imageXCoder ( 2012-07-13 08:08:37 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2012-07-13 06:28:06 -0600

Seen: 32,638 times

Last updated: Jul 11 '14