批量的处理图片,这些图片存在在一个文件夹中,如何对这个文件夹中的数据进行批处理是非常重要的,下面介绍几种常用的方法。
1. sprintf()函数法
这种方法最为简单,他是将路径的名字存放在一个数组中
//input为输入文件夹的路径,i为第几幅图像
//图像的命名格式都是1.jpg,2.jpg,...
sprintf(filename, "%s\\%d.jpg", input, i)
示例:
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;
void Resize(int m, int n) {
char filename[256];
char filename2[256];
for (int i = 1; i <= 10; i++) {
//input中有10个文件
sprintf(filename,"%s\\%d.jpg","input",i);
Mat img = imread(filename);
// imshow("img", img);
Mat res;
resize(img, res, Size(m, n));
//输出
sprintf(filename2, "%s\\%d_resize.jpg","output",i);
imwrite(filename2, res);
}
}
int main() {
Resize(24, 24);
return 0;
}
2. windows中使用dir方法
在DOS的环境下将文件夹中的图像名称生成一个txt文档,这样就可以批量处理这个txt文档从而对图像进行批量处理。
dir /b > example.txt
即输出到example.txt文件中。
//DOS环境下
C:\WINDOWS\system32>cd C:\Users\AAA\Desktop\example
C:\Users\AAA\Desktop\example>dir /b > example.txt
3. c/c++中调用cmd的dir方法
这种方法要比上面的方法要好用的多,因为不必来回折腾,而且非常的方便。
代码如下:
需要注意这一行语句,就是将字符串的最后一个\n去掉,可以单步调式去观察。
output.back().resize(output.back().size() - 1);
#include<iostream>
#include<string>
#include<vector>
using namespace std;
void getDir(string filename, vector<string> &output){
FILE* pipe = NULL;
string pCmd = "dir /B " + filename;
char buf[256];
pipe = _popen(pCmd.c_str(), "rt");
if (pipe == NULL) {
cout << "file is not exist" << filename << endl;
exit(1);
}
while (!feof(pipe))
if (fgets(buf, 256, pipe) != NULL) {
output.push_back(string(buf));
output.back().resize(output.back().size() - 1); //将\n去掉
}
_pclose(pipe);
}
int main() {
vector<string>output; //output就是输出的路径集合
getDir("example", output);
for (auto c : output)
cout << c << endl;
}
输出的结果如下,输出了一系列的图片名称:
0_GaussianBlur.jpg
0_Perspective.jpg
0_Rotate108.jpg
0_Rotate144.jpg
0_Rotate180.jpg
0_Rotate216.jpg
0_Rotate252.jpg
0_Rotate288.jpg
0_Rotate324.jpg
0_Rotate36.jpg
0_Rotate360.jpg
0_Rotate72.jpg
example.txt
IMG_20151003_17250_GaussianBlur.jpg
IMG_20151003_17250_Perspective.jpg
IMG_20151003_17250_Rotate108.jpg
IMG_20151003_17250_Rotate144.jpg
IMG_20151003_17250_Rotate180.jpg
IMG_20151003_17250_Rotate216.jpg
IMG_20151003_17250_Rotate252.jpg
IMG_20151003_17250_Rotate288.jpg
IMG_20151003_17250_Rotate324.jpg
IMG_20151003_17250_Rotate36.jpg
IMG_20151003_17250_Rotate360.jpg
4.OpenCV的类方法
OpenCV中有实现遍历文件夹下所有文件的类Directory,它里面包括3个成员函数:
(1)、GetListFiles:遍历指定文件夹下的所有文件,不包括指定文件夹内的文件夹;
(2)、GetListFolders:遍历指定文件夹下的所有文件夹,不包括指定文件夹下的文件;
(3)、GetListFilesR:遍历指定文件夹下的所有文件,包括指定文件夹内的文件夹。
若要使用Directory类,则需包含contrib.hpp头文件,此类的实现在contrib模块。
注意:OpenCV3中没有这个模块,因为安全性移除了,可以安装,此种方法具体可见:
OpenCV中有实现遍历文件夹下所有文件的类Directory,它里面包括3个成员函数:(1)、GetListFiles:遍历指定文件夹下的所有文件,不包括指定文件夹内的文件夹;(2)、GetListFolders:遍历指定文件夹下的所有文件夹,不包括指定文件夹下的文件;(3)、GetListFilesR:遍历指定文件夹下的所有文件,包括指定文件夹内的文件夹。
若要使用Directory类,则需包含contrib.hpp头文件,此类的实现在contrib模块。
下面为测试代码:
1. cv::Directory dir;
2.
3. string path1 = "E:/data/image";
4. string exten1 = "*.bmp";//"*"
5. bool addPath1 = false;//true;
6.
7. vector<string> filenames = dir.GetListFiles(path1, exten1, addPath1);
8.
9. cout<<"file names: "<<endl;
10. for (int i = 0; i < filenames.size(); i++)
11. cout<<filenames[i]<<endl;
12.
13. string path2 = "E:/data/image";
14. string exten2 = "*";//"Image*";//"*"
15. bool addPath2 = true;//false
16.
17. vector<string> foldernames = dir.GetListFolders(path2, exten2, addPath2);
18.
19. cout<<"folder names: "<<endl;
20. for (int i = 0; i < foldernames.size(); i++)
21. cout<<foldernames[i]<<endl;
22.
23. string path3 = "E:/data/image";
24. string exten3 = "*";
25. bool addPath3 = true;//false
26.
27. vector<string> allfilenames = dir.GetListFilesR(path3, exten3, addPath3);
28.
29. cout<<"all file names: "<<endl;
30. for (int i = 0; i < allfilenames.size(); i++)
31. cout<<allfilenames[i]<<endl;
32.