绪论
本文记录Windows下 C++ 利用 OpenCvglob函数得到文件夹下所有文件的绝对路径(含文件名)。本文还含有 std::string::find()等函数的记录。如果是 Python 就很简单了。但是 C++还是不简单的。
#include <opencv2/opencv.hpp>//#include <opencv2/core/utility.hpp>#include<vector>#include<string>using namespace std;std::vector<cv::String> filePathNames; //path of folder, you can replace "*.*" by "*.jpg" or "*.png"std::string folderPath = "C:/codes/*.*"; cv::glob(folderPath, fileNames); // cv::string 似乎没有 find ,replace的方法std::string stdFilePath = cvFilePath; // cv::string --->> std::string
glob 函数的原型如下
void cv::glob(cv::String pattern, std::vector<cv::String>& result, bool recursive = false)
注意 pattern 和 result 都是 cv :: String 类型。 但是 pattern 呢,即使我们传进去的参数时 std::string ,它也会自动生成一个 cv::string 的 copy。result 参数呢?因为它被当作非 const 引用,所以必须用匹配的类型。
当参数recursive为false时,仅仅遍历指定文件夹内符合模式的文件,
当recursive为true时,会同时遍历指定文件夹的子文件夹。
最后,补充一个代码,来自这篇博文:
由于 glob 遍历图像名称不是按顺序进行遍历的;
在读取图像序列的时候经常要按顺序读取,如在多目标跟踪中;
这时可以sort进行排序;
//获取文件夹下所有图像名称,// 图像名称按升序排列int imageNameLists(string filePath, vector<string>& nameArr){vector<cv::String> fn;cv::glob(filePath, fn, false);size_t count = fn.size();if (count==0){cout << "file " << filePath << " not exits"<<endl;return -1;}for (int i = 0; i < count; ++i){//1.获取不带路径的文件名,000001.jpgstring::size_type iPos = fn[i].find_last_of('/') + 1;string filename = fn[i].substr(iPos, fn[i].length() - iPos);//cout << filename << endl;//2.获取不带后缀的文件名,000001string name = filename.substr(0, filename.rfind("."));//cout << name << endl;nameArr.emplace_back(name);}sort(nameArr.begin(), nameArr.end(),[](string a, string b) {return stoi(a) < stoi(b); });return 0;}
std::string::find() std::string::rfind()
由于对 std::string::find() std::string::rfind() 方法不熟悉,做个记录。
下面的 pos 参数是从 主串查找起点的 索引(从 0 开始),返回的是模式串在主串中的位置。
注意 (3),模式串 s 可以不被完全使用,可以用参数 n 指定只用模式串的前 n 个字符组成的子串作为模式串。
(1)size_t find (const string& str, size_t pos = 0) const; //查找对象–string类对象
(2)size_t find (const char s, size_t pos = 0) const; //查找对象–字符串
(3)size_t find (const char s, size_t pos, size_t n) const; //查找对象–字符串的前n个字符
(4)size_t find (char c, size_t pos = 0) const; //查找对象–字符
结果:找到 – 返回 第一个字符的索引
(5)string::rfind(string, pos) 是从pos开始由右往左找,返回找到的位置。
#include <iostream> // std::cout#include <string> // std::stringint main (){std::string str ("There are two needles in this haystack with needles.");std::string str2 ("needle");// different member versions of find in the same order as above:std::size_t found = str.find(str2);if (found!=std::string::npos)std::cout << "first 'needle' found at: " << found << '\n';// 主串是 str = "There are two needles in this haystack with needles."// 模式串是"needles are small"的前7个字符found=str.find("needles are small",found+1,7);if (found!=std::string::npos)std::cout << "second 'needle' found at: " << found << '\n';found=str.find("haystack");if (found!=std::string::npos)std::cout << "'haystack' also found at: " << found << '\n';found=str.find('.');if (found!=std::string::npos)std::cout << "Period found at: " << found << '\n';// let's replace the first needle:str.replace(str.find(str2),str2.length(),"preposition"); //replace 用法std::cout << str << '\n';found = str.rfind(str2);if (found != std::string::npos)std::cout << "From right to left, needle' found at: " << found << '\n';return 0;}
结果如下所示:
结果:first 'needle' found at: 14second 'needle' found at: 44'haystack' also found at: 30Period found at: 51There are two prepositions in this haystack with needlesFrom right to left, needle' found at: 44
vector emplace_back() 和 push_back() 的区别
C++ STL vector 数据结构,emplace_back() 和 push_back() 的区别,就在于底层实现的机制不同。push_back()向容器尾部添加元素时,首先会创建这个元素,然后再将这个元素拷贝或者移动到容器中(如果是拷贝的话,事后会自行销毁先前创建的这个元素);而 emplace_back() 在实现时,则是直接在容器尾部创建这个元素,省去了拷贝或移动元素的过程。
std::string::npos
npos是一个常数,表示size_t的最大值(Maximum value for size_t)。许多容器都提供这个东西,用来表示不存在的位置
stoi
把数字字符串转换成 int 输出。