diff --git a/src/util/util.cpp b/src/util/util.cpp index b293c2a..df37418 100644 --- a/src/util/util.cpp +++ b/src/util/util.cpp @@ -1,127 +1,127 @@ #include "easypr/util/util.h" #include -#ifdef OS_WINDOWS -#include -#include -#include -#define PATH_DELIMITER '\\' +// #ifdef OS_WINDOWS +#include // 包含windows.h头文件,用于Windows平台的系统调用 +#include // 包含direct.h头文件,用于Windows平台的目录操作 +#include // 包含io.h头文件,用于Windows平台的IO操作 +#define PATH_DELIMITER '\\' // 定义路径分隔符为'\\' #ifdef min -#undef min +#undef min // 如果已经定义了min,取消其定义 #endif #ifdef max -#undef max +#undef max // 如果已经定义了max,取消其定义 #endif #elif defined(OS_LINUX) || defined(OS_UNIX) -#include -#include -#include -#include +#include // 包含cstring头文件,用于字符串操作 +#include // 包含dirent.h头文件,用于目录操作 +#include // 包含sys/stat.h头文件,用于文件状态检查 +#include // 包含unistd.h头文件,用于Unix标准的系统调用 -#define PATH_DELIMITER '/' +#define PATH_DELIMITER '/' // 定义路径分隔符为'/' #endif #ifdef OS_UNIX -#include +#include // 包含sys/timeb.h头文件,用于时间操作 #endif -#include -#include +#include // 包含list头文件,用于list数据结构 +#include // 包含opencv的highgui模块,用于图像IO操作 -namespace easypr { +namespace easypr { // 定义easypr命名空间 -long Utils::getTimestamp() { +long Utils::getTimestamp() { // 定义获取时间戳的函数 #ifdef OS_WINDOWS - return static_cast(cv::getTickCount()); + return static_cast(cv::getTickCount()); // Windows平台下,使用opencv的getTickCount函数获取时间戳 #endif #ifdef OS_LINUX - struct timespec ts; + struct timespec ts; // 定义timespec结构体,用于获取时间 - clock_gettime(CLOCK_MONOTONIC, &ts); + clock_gettime(CLOCK_MONOTONIC, &ts); // 获取当前时间 - return (ts.tv_sec * 1e3 + ts.tv_nsec / 1e6); + return (ts.tv_sec * 1e3 + ts.tv_nsec / 1e6); // 返回毫秒级的时间戳 #endif #ifdef OS_UNIX // there is no function provided by osx to get system tick count. // but considering the purpose by using this function, // we can simply return a millisecond since 1970/1/1 to calc the time elapse. - struct timeb tb; - ftime(&tb); - return long(tb.time * 1e3 + tb.millitm); + struct timeb tb; // 定义timeb结构体,用于获取时间 + ftime(&tb); // 获取当前时间 + return long(tb.time * 1e3 + tb.millitm); // 返回毫秒级的时间戳 #endif } std::string Utils::getFileName(const std::string &path, - const bool postfix /* = false */) { - if (!path.empty()) { - size_t last_slash = utils::get_last_slash(path); - size_t last_dot = path.find_last_of('.'); + const bool postfix /* = false */) { // 定义获取文件名的函数 + if (!path.empty()) { // 如果路径不为空 + size_t last_slash = utils::get_last_slash(path); // 获取路径中最后一个斜杠的位置 + size_t last_dot = path.find_last_of('.'); // 获取路径中最后一个点的位置 if (last_dot < last_slash || last_dot == std::string::npos) { // not found the right dot of the postfix, // return the file name directly - return path.substr(last_slash + 1); + return path.substr(last_slash + 1); // 如果没有找到正确的后缀点,直接返回文件名 } else { // the path has a postfix if (postfix) { // return the file name including postfix - return path.substr(last_slash + 1); + return path.substr(last_slash + 1); // 如果路径有后缀,并且需要返回后缀,返回包含后缀的文件名 } // without postfix - return path.substr(last_slash + 1, last_dot - last_slash - 1); + return path.substr(last_slash + 1, last_dot - last_slash - 1); // 如果路径有后缀,但不需要返回后缀,返回不包含后缀的文件名 } } - return ""; + return ""; // 如果路径为空,返回空字符串 } std::vector Utils::splitString(const std::string &str, - const char delimiter) { - std::vector splited; - std::string s(str); - size_t pos; + const char delimiter) { // 定义字符串分割函数 + std::vector splited; // 定义存储分割结果的vector + std::string s(str); // 复制输入的字符串 + size_t pos; // 定义分割位置 - while ((pos = s.find(delimiter)) != std::string::npos) { - std::string sec = s.substr(0, pos); + while ((pos = s.find(delimiter)) != std::string::npos) { // 当找到分隔符时 + std::string sec = s.substr(0, pos); // 获取分隔符前的子串 - if (!sec.empty()) { - splited.push_back(s.substr(0, pos)); + if (!sec.empty()) { // 如果子串不为空 + splited.push_back(s.substr(0, pos)); // 将子串添加到分割结果中 } - s = s.substr(pos + 1); + s = s.substr(pos + 1); // 更新待分割的字符串 } - splited.push_back(s); + splited.push_back(s); // 将最后一个子串添加到分割结果中 - return splited; + return splited; // 返回分割结果 } std::vector Utils::getFiles(const std::string &folder, - const bool all /* = true */) { - std::vector files; - std::list subfolders; - subfolders.push_back(folder); + const bool all /* = true */) { // 定义获取文件列表的函数 + std::vector files; // 定义存储文件列表的vector + std::list subfolders; // 定义存储子文件夹的list + subfolders.push_back(folder); // 将输入的文件夹添加到子文件夹列表中 #ifdef OS_WINDOWS - while (!subfolders.empty()) { - std::string current_folder(subfolders.back()); + while (!subfolders.empty()) { // 当子文件夹列表不为空时 + std::string current_folder(subfolders.back()); // 获取当前处理的文件夹 if (*(current_folder.end() - 1) != '/') { - current_folder.append("/*"); + current_folder.append("/*"); // 如果当前文件夹的路径不以'/'结尾,添加'/*' } else { - current_folder.append("*"); + current_folder.append("*"); // 如果当前文件夹的路径以'/'结尾,添加'*' } - subfolders.pop_back(); + subfolders.pop_back(); // 从子文件夹列表中移除当前处理的文件夹 - struct _finddata_t file_info; - auto file_handler = _findfirst(current_folder.c_str(), &file_info); + struct _finddata_t file_info; // 定义文件信息结构体 + auto file_handler = _findfirst(current_folder.c_str(), &file_info); // 打开当前文件夹 - while (file_handler != -1) { + while (file_handler != -1) { // 当文件夹打开成功时 if (all && (!strcmp(file_info.name, ".") || !strcmp(file_info.name, ".."))) { if (_findnext(file_handler, &file_info) != 0) break; @@ -136,7 +136,7 @@ std::vector Utils::getFiles(const std::string &folder, folder.pop_back(); folder.append(file_info.name); - subfolders.push_back(folder.c_str()); + subfolders.push_back(folder.c_str()); // 如果是子文件夹,并且需要搜索子文件夹,将子文件夹添加到子文件夹列表中 } } else { // it's a file @@ -145,24 +145,24 @@ std::vector Utils::getFiles(const std::string &folder, file_path.assign(current_folder.c_str()).pop_back(); file_path.append(file_info.name); - files.push_back(file_path); + files.push_back(file_path); // 如果是文件,将文件路径添加到文件列表中 } if (_findnext(file_handler, &file_info) != 0) break; } // while - _findclose(file_handler); + _findclose(file_handler); // 关闭文件夹 } #elif defined(OS_LINUX) || defined(OS_UNIX) - while (!subfolders.empty()) { - std::string current_folder(subfolders.back()); + while (!subfolders.empty()) { // 当子文件夹列表不为空时 + std::string current_folder(subfolders.back()); // 获取当前处理的文件夹 if (*(current_folder.end() - 1) != '/') { - current_folder.push_back('/'); + current_folder.push_back('/'); // 如果当前文件夹的路径不以'/'结尾,添加'/' } - DIR* pdir = opendir(current_folder.c_str()); + DIR* pdir = opendir(current_folder.c_str()); // 打开当前文件夹 - subfolders.pop_back(); + subfolders.pop_back(); // 从子文件夹列表中移除当前处理的文件夹 if (!pdir) { continue; @@ -170,9 +170,9 @@ std::vector Utils::getFiles(const std::string &folder, dirent* dir = NULL; - while ((dir = readdir(pdir)) != NULL) { + while ((dir = readdir(pdir)) != NULL) { // 当读取到文件或文件夹时 // iterates the current folder, search file & sub folder - struct stat st; + struct stat st; // 定义文件状态结构体 if (all && (!strcmp(dir->d_name, ".") || !strcmp(dir->d_name, ".."))) { // must ignore . & .. @@ -201,93 +201,93 @@ std::vector Utils::getFiles(const std::string &folder, std::string subfolder(current_folder); subfolder.append(dir->d_name); - subfolders.push_back(subfolder.c_str()); + subfolders.push_back(subfolder.c_str()); // 如果是子文件夹,并且需要搜索子文件夹,将子文件夹添加到子文件夹列表中 } } else { // it's a file - files.push_back(file_path); + files.push_back(file_path); // 如果是文件,将文件路径添加到文件列表中 } } // while - closedir(pdir); + closedir(pdir); // 关闭文件夹 } #endif - return files; + return files; // 返回文件列表 } -bool Utils::mkdir(const std::string folder) { - std::string folder_builder; - std::string sub; +bool Utils::mkdir(const std::string folder) { // 定义创建文件夹的函数 + std::string folder_builder; // 定义文件夹路径构造器 + std::string sub; // 定义子路径 sub.reserve(folder.size()); - for (auto it = folder.begin(); it != folder.end(); ++it) { + for (auto it = folder.begin(); it != folder.end(); ++it) { // 遍历输入的文件夹路径 const char c = *it; sub.push_back(c); - if (c == PATH_DELIMITER || it == folder.end() - 1) { - folder_builder.append(sub); + if (c == PATH_DELIMITER || it == folder.end() - 1) { // 当遇到路径分隔符或路径结束时 + folder_builder.append(sub); // 将子路径添加到文件夹路径构造器中 #ifdef OS_WINDOWS - if (0 != ::_access(folder_builder.c_str(), 0)) { + if (0 != ::_access(folder_builder.c_str(), 0)) { // 如果文件夹不存在 #else - if (0 != ::access(folder_builder.c_str(), 0)) { + if (0 != ::access(folder_builder.c_str(), 0)) { // 如果文件夹不存在 #endif // this folder not exist #ifdef OS_WINDOWS - if (0 != ::_mkdir(folder_builder.c_str())) { + if (0 != ::_mkdir(folder_builder.c_str())) { // 如果创建文件夹失败 #else - if (0 != ::mkdir(folder_builder.c_str(), S_IRWXU)) { + if (0 != ::mkdir(folder_builder.c_str(), S_IRWXU)) { // 如果创建文件夹失败 #endif // create failed - return false; + return false; // 返回失败 } } - sub.clear(); + sub.clear(); // 清空子路径 } } - return true; + return true; // 返回成功 } -bool Utils::imwrite(const std::string &file, const cv::Mat &image) { - auto folder = file.substr(0, utils::get_last_slash(file)); - Utils::mkdir(folder); - return cv::imwrite(file, image); +bool Utils::imwrite(const std::string &file, const cv::Mat &image) { // 定义图像写入函数 + auto folder = file.substr(0, utils::get_last_slash(file)); // 获取文件所在的文件夹 + Utils::mkdir(folder); // 创建文件所在的文件夹 + return cv::imwrite(file, image); // 写入图像 } #ifdef OS_WINDOWS -std::string Utils::utf8_to_gbk(const char* utf8) { - int len = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0); - wchar_t* wszGBK = new wchar_t[len + 1]; - memset(wszGBK, 0, len * 2 + 2); - MultiByteToWideChar(CP_UTF8, 0, utf8, -1, wszGBK, len); - len = WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, NULL, 0, NULL, NULL); - char* szGBK = new char[len + 1]; - memset(szGBK, 0, len + 1); - WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, szGBK, len, NULL, NULL); - std::string strTemp(szGBK); +std::string Utils::utf8_to_gbk(const char* utf8) { // 定义UTF-8到GBK的转换函数 + int len = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0); // 获取转换后的长度 + wchar_t* wszGBK = new wchar_t[len + 1]; // 定义存储转换结果的宽字符数组 + memset(wszGBK, 0, len * 2 + 2); // 初始化宽字符数组 + MultiByteToWideChar(CP_UTF8, 0, utf8, -1, wszGBK, len); // 将UTF-8字符串转换为宽字符字符串 + len = WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, NULL, 0, NULL, NULL); // 获取转换后的长度 + char* szGBK = new char[len + 1]; // 定义存储转换结果的字符数组 + memset(szGBK, 0, len + 1); // 初始化字符数组 + WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, szGBK, len, NULL, NULL); // 将宽字符字符串转换为GBK字符串 + std::string strTemp(szGBK); // 将GBK字符串转换为std::string if (wszGBK) - delete[] wszGBK; + delete[] wszGBK; // 删除宽字符数组 if (szGBK) - delete[] szGBK; - return strTemp; + delete[] szGBK; // 删除字符数组 + return strTemp; // 返回转换结果 } #endif -std::size_t Utils::get_last_slash(const std::string &path) { +std::size_t Utils::get_last_slash(const std::string &path) { // 定义获取路径中最后一个斜杠的位置的函数 #ifdef OS_WINDOWS - size_t last_slash_1 = path.find_last_of("\\"); - size_t last_slash_2 = path.find_last_of("/"); + size_t last_slash_1 = path.find_last_of("\\"); // 获取路径中最后一个'\\'的位置 + size_t last_slash_2 = path.find_last_of("/"); // 获取路径中最后一个'/'的位置 size_t last_slash; if (last_slash_1 != std::string::npos && last_slash_2 != std::string::npos) { // C:/path\\to/file.postfix - last_slash = std::max(last_slash_1, last_slash_2); + last_slash = std::max(last_slash_1, last_slash_2); // 如果路径中既有'\\'又有'/',取最后出现的一个 } else { // C:\\path\\to\\file.postfix // C:/path/to/file.postfix last_slash = - (last_slash_1 == std::string::npos) ? last_slash_2 : last_slash_1; + (last_slash_1 == std::string::npos) ? last_slash_2 : last_slash_1; // 如果路径中只有'\\'或只有'/',取出现的那一个 } #else - size_t last_slash = path.find_last_of('/'); + size_t last_slash = path.find_last_of('/'); // 获取路径中最后一个'/'的位置 #endif - return last_slash; + return last_slash; // 返回最后一个斜杠的位置 } } // namespace easypr \ No newline at end of file