zhaohaoyi_branch
heureux 11 months ago
parent 494b46daee
commit 3e7dd9deaa

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