How to Read Files in Sequence from a Directory in Opencv

How to read files in sequence from a directory in OpenCV?

If you're using a recent version of OpenCV, you're better off avoiding OS-specific methods:

vector<string> fn; // std::string in opencv2.4, but cv::String in 3.0
string path = "e:/code/vlc/faces2/*.png";
cv::glob(path,fn,false);
// Now you got a list of filenames in fn.

(Ohh, and again, avoid deprecated C-API functions like cvLoad like hell, please!!)

How to read files in sequence from a directory in OpenCV and use it for processing?

Try to use CV::String instead of std::string.

Add #include "cvstd.hpp", then

cv::String new_folder_string(folder).
std::vector<cv::String> new_filename_vector.
glob(new_folder_string, new_filename_vector, false);

Some info here(glob function), here(String class in OpenCV), here(example of use of glob with cv::String) and here(berak's suggestion).

EDIT: I forgot to mention that you need to switch also filename from std::string to cv::String.

OpenCV: Reading image series from a folder

From my experiences the VideoCapture can read a sequence of images even without specifing the format.
E.g. the following works fine:

std::string pathToData("cap_00000000.bmp");
cv::VideoCapture sequence(pathToData);

the images are sequentially read:

Mat image;
sequence >> image; // Reads cap_00000001.bmp

HOWEVER: This only works if the images are located within the folder of the executable file. I could not figure out to specify a directory like this:

std::string pathToData("c:\\path\\cap_00000000.bmp");
std::string pathToData("c://path//cap_00000000.bmp");
// etc.

Seems to be a bug. An offical example can be found here:

http://kevinhughes.ca/tutorials/reading-image-sequences-with-opencv/
https://github.com/Itseez/opencv/pull/823/files

Reading an ordered sequence of images in a folder using OpenCV

1) You can use VideoCapture with a filename:

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, ...)

2) Or simply change the name of the image to load according to a counter.

#include <opencv2/opencv.hpp>
#include <string>
#include <iomanip>
#include <sstream>

int main()
{
std::string folder = "your_folder_with_images";
std::string suffix = ".jpg";
int counter = 0;

cv::Mat myImage;

while (1)
{
std::stringstream ss;
ss << std::setw(4) << std::setfill('0') << counter; // 0000, 0001, 0002, etc...
std::string number = ss.str();

std::string name = folder + number + suffix;
myImage = cv::imread(name);

cv::imshow("HEYO", myImage);
int c = cv::waitKey(1);

counter++;
}
return 0;
}

3) Or you can use the function glob to store all the filenames matching a given pattern in a vector, and then scan the vector. This will work also for non-consecutive numbers.

#include <opencv2/opencv.hpp>
using namespace cv;

int main()
{
String folder = "your_folder_with_images/*.jpg";
vector<String> filenames;

glob(folder, filenames);

Mat myImage;

for (size_t i = 0; i < filenames.size(); ++i)
{
myImage = imread(filenames[i]);
imshow("HEYO", myImage);
int c = cv::waitKey(1);
}

return 0;
}

How to read images from a directory with Python and OpenCV?

You have post at least three questions about get filenames with "PostPath". Badly.

A better way is use glob.glob to get the specific type of filenames.

$ tree .
├── a.txt
├── feature.py
├── img01.jpg
├── img01.png
├── imgs
│   ├── img02.jpg
│   └── img02.png
├── tt01.py
├── tt02.py
└── utils.py

1 directory, 9 files

From current directory:

import glob
import itertools

def getFilenames(exts):
fnames = [glob.glob(ext) for ext in exts]
fnames = list(itertools.chain.from_iterable(fnames))
return fnames

## get `.py` and `.txt` in current folder
exts = ["*.py","*.txt"]
res = getFilenames(exts)
print(res)
# ['utils.py', 'tt02.py', 'feature.py', 'tt01.py', 'a.txt']

# get `.png` in current folder and subfolders
exts = ["*.png","*/*.png"]
res = getFilenames(exts)
print(res)
# ['img01.png', 'imgs/img02.png']

How to read the first image in folder using opencv (python)

Just remove the for-loop's last line: prev = curr and prev = cv2.imread(frames[0]).

But you can speed up your for-loop. If print function is not crucial, then you can do:

diff = [compute_DIFF(prev, cv2.cvtColor(cv2.imread(frame_curr), cv2.COLOR_BGR2GRAY)) for i, frame_curr in enumerate(frames)]

Code:



def cal_for_frames(video_path):
frames = glob(os.path.join(video_path, '*.jpg')).sort()
prev = cv2.cvtColor(cv2.imread(frames[0]), cv2.COLOR_BGR2GRAY)
print(prev.dtype, prev.shape)

diff = [compute_DIFF(prev, cv2.cvtColor(cv2.imread(frame_curr), cv2.COLOR_BGR2GRAY)) for i, frame_curr in enumerate(frames)]

return diff

Python/OpenCV - how to load all images from folder in alphabetical order

Luckily, python lists have a built-in sort function that can sort strings using ASCII values. It is as simple as putting this before your loop:

filenames = [img for img in glob.glob("images/*.jpg")]

filenames.sort() # ADD THIS LINE

images = []
for img in filenames:
n= cv2.imread(img)
images.append(n)
print (img)

EDIT: Knowing a little more about python now than I did when I first answered this, you could actually simplify this a lot:

filenames = glob.glob("images/*.jpg")
filenames.sort()
images = [cv2.imread(img) for img in filenames]

for img in images:
print img

Should be much faster too. Yay list comprehensions!



Related Topics



Leave a reply



Submit