C++获取指定路径文件夹下的所有图片-windows和linux下各自的处理方案

使用场景

获取某路径下的图片,再逐张传入TensorRT进行识别,但是如果要做连续帧处理,需要将图片序列从小到大排序, 因为原来读取进去的图片列表是乱序的。

Code

两个版本的不同点在于GetImagePaths函数的实现。

Windows

// 防止使用strcpy报warning
#define _CRT_SECURE_NO_WARNINGS
#include 
#include 
#include 
#include 


using namespace std;

/**
 * @brief 图像文件结构体
 */
struct ImageFile
{
	std::string file_name; /*!< 文件名 */
	int order_number; /*!< 文件序号, 取文件名 */
};

/**
* @brief 排序函数,从小到大
* @param img1  图片1
* @param img2  图片2
* @return 返回图片1的序号是否小于图片2
*	-- True 表示图片1小于图片2
*   -- False 表示图片1大于图片2
*/
bool SortByImageFiles(const ImageFile img1, const ImageFile img2)
{
	return img1.order_number < img2.order_number;
}

/**
* @brief 字符分割函数, this function adapt from: https://blog.csdn.net/mary19920410/article/details/77372828
* @param str  进行分割的字符串
* @param delim  分割符
* @return 返回分割后的字符vector
*/
vector<string> split(const string& str, const string& delim)
{
	vector<string> res;
	if ("" == str) return res;
	char* strs = new char[str.length() + 1]; 
	strcpy(strs, str.c_str());

	char* d = new char[delim.length() + 1];
	strcpy(d, delim.c_str());

	char* p = strtok(strs, d);
	while (p) {
		string s = p; 
		res.push_back(s); 
		p = strtok(NULL, d);
	}

	return res;
}

/**
* @brief 字符分割函数
* @param folder_path  文件夹路径
* @param file_format  文件类型
* @param file_names  ImageFile类型的vector,用于存放图片集合
*/
void GetImagePaths(std::string folder_path, std::string file_format, std::vector<ImageFile>& file_names)
{
	intptr_t hFile = 0;
	_finddata_t fileInfo;
	std::string file_path = folder_path;
	file_path = file_path.append(file_format);
	hFile = _findfirst(file_path.c_str(), &fileInfo);
	ImageFile temp_path;
	vector<string> split_result;
	if (hFile != -1) {
		//cout << "----原顺序----" << endl;
		do {
			if ((fileInfo.attrib & _A_SUBDIR)) {
				continue;
			}
			else {
				temp_path.file_name = folder_path + fileInfo.name;
				split_result = split(fileInfo.name, ".");
				temp_path.order_number = atoi(split_result[0].c_str());
				file_names.push_back(temp_path);
				//cout << temp_path.file_name << endl;
			}

		} while (_findnext(hFile, &fileInfo) == 0);
		std::sort(file_names.begin(), file_names.end(), SortByImageFiles);
	
		_findclose(hFile);
	}
}

int main()
{
	std::vector<ImageFile> file_names;
	GetImagePaths("F://output//output2//", "*.jpg", file_names);
	//cout << "----新顺序----"<
	for (auto lin : file_names) {
		cout << lin.file_name << endl;
	}
	return 0;
}

Linux

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;


struct ImageFile
{
    std::string file_name; /*!< 文件名 */
    int order_number; /*!< 文件序号, 取文件名 */
};
/**
* @brief 排序函数,从小到大
* @param img1  图片1
* @param img2  图片2
* @return 返回图片1的序号是否小于图片2
*	-- True 表示图片1小于图片2
*   -- False 表示图片1大于图片2
*/
bool SortByImageFiles(const ImageFile img1, const ImageFile img2)
{
    return img1.order_number < img2.order_number;
}

/**
* @brief 字符分割函数, this function adapt from: https://blog.csdn.net/mary19920410/article/details/77372828
* @param str  进行分割的字符串
* @param delim  分割符
* @return 返回分割后的字符vector
*/
vector<string> split(const string& str, const string& delim)
{
    vector<string> res;
    if ("" == str) return res;
    char* strs = new char[str.length() + 1];
    strcpy(strs, str.c_str());

    char* d = new char[delim.length() + 1];
    strcpy(d, delim.c_str());

    char* p = strtok(strs, d);
    while (p) {
        string s = p;
        res.push_back(s);
        p = strtok(NULL, d);
    }

    return res;
}

/**
* @brief 字符分割函数
* @param folder_path  文件夹路径
* @param file_format  文件类型
* @param file_names  ImageFile类型的vector,用于存放图片集合
*/
void GetImagePaths(char *folder_path, char *file_format, std::vector<ImageFile>& file_names) {
    DIR *dp;
    struct dirent *dirp;
    if ((dp=opendir(folder_path))==NULL)
        printf("cant open folder");
    ImageFile temp_path;
    vector<string> split_result;
    std::string file_name;
    while (((dirp = readdir(dp))) != NULL)
    {
        file_name = dirp->d_name;
        split_result = split(file_name, ".");
        if (split_result.size() >= 1)
        {
            if(split_result[1] == file_format){
                temp_path.file_name = folder_path;
                temp_path.file_name += file_name;
                temp_path.order_number = atoi(split_result[0].c_str());
                file_names.push_back(temp_path);
            }
        }
    }
    std::sort(file_names.begin(), file_names.end(), SortByImageFiles);
}

int main() {
    std::vector<ImageFile> file_names;
    GetImagePaths("/home/john/PycharmProjects/echi/test_img/", "jpg", file_names);
    for (auto lin : file_names) {
        cout << lin.file_name << endl;
    }
    return 0;
}

执行结果 - Windows

原顺序(乱序)
C++获取指定路径文件夹下的所有图片-windows和linux下各自的处理方案_第1张图片
新顺序(升序)
C++获取指定路径文件夹下的所有图片-windows和linux下各自的处理方案_第2张图片

问题汇总

  1. _finddata_t是一个windows下的结构体, 只适用于windows系统。Linux使用dirent.h实现。

你可能感兴趣的:(cpp,c++)