zhaohaoyi_branch
heureux 10 months ago
parent 494b46daee
commit 3e7dd9deaa

@ -1,127 +1,127 @@
#include "easypr/util/util.h"
#include <string>
#ifdef OS_WINDOWS
#include <windows.h>
#include <direct.h>
#include <io.h>
#define PATH_DELIMITER '\\'
// #ifdef OS_WINDOWS
#include <windows.h> // 包含windows.h头文件用于Windows平台的系统调用
#include <direct.h> // 包含direct.h头文件用于Windows平台的目录操作
#include <io.h> // 包含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 <cstring>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
#include <cstring> // 包含cstring头文件用于字符串操作
#include <dirent.h> // 包含dirent.h头文件用于目录操作
#include <sys/stat.h> // 包含sys/stat.h头文件用于文件状态检查
#include <unistd.h> // 包含unistd.h头文件用于Unix标准的系统调用
#define PATH_DELIMITER '/'
#define PATH_DELIMITER '/' // 定义路径分隔符为'/'
#endif
#ifdef OS_UNIX
#include <sys/timeb.h>
#include <sys/timeb.h> // 包含sys/timeb.h头文件用于时间操作
#endif
#include <list>
#include <opencv2/highgui/highgui.hpp>
#include <list> // 包含list头文件用于list数据结构
#include <opencv2/highgui/highgui.hpp> // 包含opencv的highgui模块用于图像IO操作
namespace easypr {
namespace easypr { // 定义easypr命名空间
long Utils::getTimestamp() {
long Utils::getTimestamp() { // 定义获取时间戳的函数
#ifdef OS_WINDOWS
return static_cast<long>(cv::getTickCount());
return static_cast<long>(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<std::string> Utils::splitString(const std::string &str,
const char delimiter) {
std::vector<std::string> splited;
std::string s(str);
size_t pos;
const char delimiter) { // 定义字符串分割函数
std::vector<std::string> 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<std::string> Utils::getFiles(const std::string &folder,
const bool all /* = true */) {
std::vector<std::string> files;
std::list<std::string> subfolders;
subfolders.push_back(folder);
const bool all /* = true */) { // 定义获取文件列表的函数
std::vector<std::string> files; // 定义存储文件列表的vector
std::list<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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
Loading…
Cancel
Save