Commit 2475c919 authored by liucong's avatar liucong
Browse files

重新Cpp代码格式化

parent 466992ff
...@@ -9,22 +9,14 @@ using namespace cv::dnn; ...@@ -9,22 +9,14 @@ using namespace cv::dnn;
namespace migraphxSamples namespace migraphxSamples
{ {
DB::DB() DB::DB() {}
{
}
DB::~DB() DB::~DB() { configurationFile.release(); }
{
configurationFile.release();
}
ErrorCode DB::Initialize(InitializationParameterOfDB InitializationParameterOfDB) ErrorCode DB::Initialize(InitializationParameterOfDB InitializationParameterOfDB)
{ {
// 读取配置文件 // 读取配置文件
std::string configFilePath=InitializationParameterOfDB.configFilePath; std::string configFilePath = InitializationParameterOfDB.configFilePath;
if(!Exists(configFilePath)) if(!Exists(configFilePath))
{ {
LOG_ERROR(stdout, "no configuration file!\n"); LOG_ERROR(stdout, "no configuration file!\n");
...@@ -32,67 +24,67 @@ ErrorCode DB::Initialize(InitializationParameterOfDB InitializationParameterOfDB ...@@ -32,67 +24,67 @@ ErrorCode DB::Initialize(InitializationParameterOfDB InitializationParameterOfDB
} }
if(!configurationFile.open(configFilePath, cv::FileStorage::READ)) if(!configurationFile.open(configFilePath, cv::FileStorage::READ))
{ {
LOG_ERROR(stdout, "fail to open configuration file\n"); LOG_ERROR(stdout, "fail to open configuration file\n");
return FAIL_TO_OPEN_CONFIG_FILE; return FAIL_TO_OPEN_CONFIG_FILE;
} }
LOG_INFO(stdout, "succeed to open configuration file\n"); LOG_INFO(stdout, "succeed to open configuration file\n");
// 获取配置文件参数 // 获取配置文件参数
cv::FileNode netNode = configurationFile["OcrDB"]; cv::FileNode netNode = configurationFile["OcrDB"];
std::string modelPath = (string)netNode["ModelPath"]; std::string modelPath = (string)netNode["ModelPath"];
dbParameter.BinaryThreshold = (float)netNode["BinaryThreshold"]; dbParameter.BinaryThreshold = (float)netNode["BinaryThreshold"];
dbParameter.BoxThreshold = (float)netNode["BoxThreshold"]; dbParameter.BoxThreshold = (float)netNode["BoxThreshold"];
dbParameter.UnclipRatio = (float)netNode["UnclipRatio"]; dbParameter.UnclipRatio = (float)netNode["UnclipRatio"];
dbParameter.LimitSideLen = (int)netNode["LimitSideLen"]; dbParameter.LimitSideLen = (int)netNode["LimitSideLen"];
dbParameter.ScoreMode = (string)netNode["ScoreMode"]; dbParameter.ScoreMode = (string)netNode["ScoreMode"];
// 加载模型 // 加载模型
if(!Exists(modelPath)) if(!Exists(modelPath))
{ {
LOG_ERROR(stdout,"%s not exist!\n",modelPath.c_str()); LOG_ERROR(stdout, "%s not exist!\n", modelPath.c_str());
return MODEL_NOT_EXIST; return MODEL_NOT_EXIST;
} }
migraphx::onnx_options onnx_options; migraphx::onnx_options onnx_options;
onnx_options.map_input_dims["x"] = {1,3,2496,2496}; // 设置最大shape onnx_options.map_input_dims["x"] = {1, 3, 2496, 2496}; // 设置最大shape
net = migraphx::parse_onnx(modelPath, onnx_options); net = migraphx::parse_onnx(modelPath, onnx_options);
LOG_INFO(stdout,"succeed to load model: %s\n",GetFileName(modelPath).c_str()); LOG_INFO(stdout, "succeed to load model: %s\n", GetFileName(modelPath).c_str());
// 获取模型输入/输出节点信息 // 获取模型输入/输出节点信息
std::unordered_map<std::string, migraphx::shape> inputs=net.get_inputs(); std::unordered_map<std::string, migraphx::shape> inputs = net.get_inputs();
std::unordered_map<std::string, migraphx::shape> outputs=net.get_outputs(); std::unordered_map<std::string, migraphx::shape> outputs = net.get_outputs();
inputName=inputs.begin()->first; inputName = inputs.begin()->first;
inputShape=inputs.begin()->second; inputShape = inputs.begin()->second;
int N=inputShape.lens()[0]; int N = inputShape.lens()[0];
int C=inputShape.lens()[1]; int C = inputShape.lens()[1];
int H=inputShape.lens()[2]; int H = inputShape.lens()[2];
int W=inputShape.lens()[3]; int W = inputShape.lens()[3];
inputSize=cv::Size(W,H); inputSize = cv::Size(W, H);
// 设置模型为GPU模式 // 设置模型为GPU模式
migraphx::target gpuTarget = migraphx::gpu::target{}; migraphx::target gpuTarget = migraphx::gpu::target{};
// 编译模型 // 编译模型
migraphx::compile_options options; migraphx::compile_options options;
options.device_id=0; // 设置GPU设备,默认为0号设备 options.device_id = 0; // 设置GPU设备,默认为0号设备
options.offload_copy=true; options.offload_copy = true;
net.compile(gpuTarget,options); net.compile(gpuTarget, options);
LOG_INFO(stdout,"succeed to compile model: %s\n",GetFileName(modelPath).c_str()); LOG_INFO(stdout, "succeed to compile model: %s\n", GetFileName(modelPath).c_str());
// warm up // warm up
std::unordered_map<std::string, migraphx::argument> inputData; std::unordered_map<std::string, migraphx::argument> inputData;
inputData[inputName]=migraphx::argument{inputShape}; inputData[inputName] = migraphx::argument{inputShape};
net.eval(inputData); net.eval(inputData);
// log // log
LOG_INFO(stdout,"InputMaxSize:%dx%d\n",inputSize.width,inputSize.height); LOG_INFO(stdout, "InputMaxSize:%dx%d\n", inputSize.width, inputSize.height);
LOG_INFO(stdout,"InputName:%s\n",inputName.c_str()); LOG_INFO(stdout, "InputName:%s\n", inputName.c_str());
return SUCCESS; return SUCCESS;
} }
ErrorCode DB::Infer(const cv::Mat &img, std::vector<cv::Mat> &imgList) ErrorCode DB::Infer(const cv::Mat& img, std::vector<cv::Mat>& imgList)
{ {
if(img.empty()||img.type()!=CV_8UC3) if(img.empty() || img.type() != CV_8UC3)
{ {
LOG_ERROR(stdout, "image error!\n"); LOG_ERROR(stdout, "image error!\n");
return IMAGE_ERROR; return IMAGE_ERROR;
...@@ -102,13 +94,13 @@ ErrorCode DB::Infer(const cv::Mat &img, std::vector<cv::Mat> &imgList) ...@@ -102,13 +94,13 @@ ErrorCode DB::Infer(const cv::Mat &img, std::vector<cv::Mat> &imgList)
cv::Mat resizeImg; cv::Mat resizeImg;
img.copyTo(srcImage); img.copyTo(srcImage);
int w = srcImage.cols; int w = srcImage.cols;
int h = srcImage.rows; int h = srcImage.rows;
float ratio = 1.f; float ratio = 1.f;
int maxWH = std::max(h, w); int maxWH = std::max(h, w);
if (maxWH > dbParameter.LimitSideLen) if(maxWH > dbParameter.LimitSideLen)
{ {
if (h > w) if(h > w)
{ {
ratio = float(dbParameter.LimitSideLen) / float(h); ratio = float(dbParameter.LimitSideLen) / float(h);
} }
...@@ -116,77 +108,80 @@ ErrorCode DB::Infer(const cv::Mat &img, std::vector<cv::Mat> &imgList) ...@@ -116,77 +108,80 @@ ErrorCode DB::Infer(const cv::Mat &img, std::vector<cv::Mat> &imgList)
{ {
ratio = float(dbParameter.LimitSideLen) / float(w); ratio = float(dbParameter.LimitSideLen) / float(w);
} }
} }
int resizeH = int(float(h) * ratio); int resizeH = int(float(h) * ratio);
int resizeW = int(float(w) * ratio); int resizeW = int(float(w) * ratio);
resizeH = std::max(int(round(float(resizeH) / 32) * 32), 32); resizeH = std::max(int(round(float(resizeH) / 32) * 32), 32);
resizeW = std::max(int(round(float(resizeW) / 32) * 32), 32); resizeW = std::max(int(round(float(resizeW) / 32) * 32), 32);
cv::resize(srcImage, resizeImg, cv::Size(resizeW, resizeH)); cv::resize(srcImage, resizeImg, cv::Size(resizeW, resizeH));
float ratioH = float(resizeH) / float(h); float ratioH = float(resizeH) / float(h);
float ratioW = float(resizeW) / float(w); float ratioW = float(resizeW) / float(w);
resizeImg.convertTo(resizeImg, CV_32FC3, 1.0/255.0); resizeImg.convertTo(resizeImg, CV_32FC3, 1.0 / 255.0);
std::vector<cv::Mat> bgrChannels(3); std::vector<cv::Mat> bgrChannels(3);
cv::split(resizeImg, bgrChannels); cv::split(resizeImg, bgrChannels);
std::vector<float> mean = {0.485f, 0.456f, 0.406f}; std::vector<float> mean = {0.485f, 0.456f, 0.406f};
std::vector<float> scale = {1 / 0.229f, 1 / 0.224f, 1 / 0.225f}; std::vector<float> scale = {1 / 0.229f, 1 / 0.224f, 1 / 0.225f};
for (auto i = 0; i < bgrChannels.size(); i++) for(auto i = 0; i < bgrChannels.size(); i++)
{ {
bgrChannels[i].convertTo(bgrChannels[i], CV_32FC1, 1.0 * scale[i], bgrChannels[i].convertTo(
(0.0 - mean[i]) * scale[i]); bgrChannels[i], CV_32FC1, 1.0 * scale[i], (0.0 - mean[i]) * scale[i]);
} }
cv::merge(bgrChannels, resizeImg); cv::merge(bgrChannels, resizeImg);
int rh = resizeImg.rows; int rh = resizeImg.rows;
int rw = resizeImg.cols; int rw = resizeImg.cols;
cv::Mat inputBlob; cv::Mat inputBlob;
inputBlob = cv::dnn::blobFromImage(resizeImg); inputBlob = cv::dnn::blobFromImage(resizeImg);
std::vector<std::size_t> inputShapeOfInfer={1,3,rh,rw}; std::vector<std::size_t> inputShapeOfInfer = {1, 3, rh, rw};
// 创建输入数据 // 创建输入数据
std::unordered_map<std::string, migraphx::argument> inputData; std::unordered_map<std::string, migraphx::argument> inputData;
inputData[inputName]= migraphx::argument{migraphx::shape(inputShape.type(),inputShapeOfInfer), (float*)inputBlob.data}; inputData[inputName] = migraphx::argument{migraphx::shape(inputShape.type(), inputShapeOfInfer),
(float*)inputBlob.data};
// 推理 // 推理
std::vector<migraphx::argument> inferenceResults = net.eval(inputData); std::vector<migraphx::argument> inferenceResults = net.eval(inputData);
// 获取推理结果 // 获取推理结果
migraphx::argument result = inferenceResults[0]; migraphx::argument result = inferenceResults[0];
// 转换为vector // 转换为vector
migraphx::shape outputShape = result.get_shape(); migraphx::shape outputShape = result.get_shape();
int shape[]={outputShape.lens()[0],outputShape.lens()[1],outputShape.lens()[2],outputShape.lens()[3]}; int shape[] = {
outputShape.lens()[0], outputShape.lens()[1], outputShape.lens()[2], outputShape.lens()[3]};
int n2 = outputShape.lens()[2]; int n2 = outputShape.lens()[2];
int n3 = outputShape.lens()[3]; int n3 = outputShape.lens()[3];
int n = n2 * n3; int n = n2 * n3;
std::vector<float> out(n); std::vector<float> out(n);
memcpy(out.data(),result.data(),sizeof(float)*outputShape.elements()); memcpy(out.data(), result.data(), sizeof(float) * outputShape.elements());
out.resize(n); out.resize(n);
std::vector<float> pred(n, 0.0); std::vector<float> pred(n, 0.0);
std::vector<unsigned char> cbuf(n, ' '); std::vector<unsigned char> cbuf(n, ' ');
for (int i = 0; i < n; i++) for(int i = 0; i < n; i++)
{ {
pred[i] = (float)(out[i]); pred[i] = (float)(out[i]);
cbuf[i] = (unsigned char)((out[i]) * 255); cbuf[i] = (unsigned char)((out[i]) * 255);
} }
cv::Mat cbufMap(n2, n3, CV_8UC1, (unsigned char *)cbuf.data()); cv::Mat cbufMap(n2, n3, CV_8UC1, (unsigned char*)cbuf.data());
cv::Mat predMap(n2, n3, CV_32F, (float *)pred.data()); cv::Mat predMap(n2, n3, CV_32F, (float*)pred.data());
const double threshold = dbParameter.BinaryThreshold * 255; const double threshold = dbParameter.BinaryThreshold * 255;
const double maxvalue = 255; const double maxvalue = 255;
cv::Mat bitMap; cv::Mat bitMap;
cv::threshold(cbufMap, bitMap, threshold, maxvalue, cv::THRESH_BINARY); cv::threshold(cbufMap, bitMap, threshold, maxvalue, cv::THRESH_BINARY);
std::vector<std::vector<std::vector<int>>> boxes; std::vector<std::vector<std::vector<int>>> boxes;
DBPostProcessor postProcessor; DBPostProcessor postProcessor;
boxes = postProcessor.BoxesFromBitmap(predMap, bitMap, dbParameter.BoxThreshold, dbParameter.UnclipRatio, dbParameter.ScoreMode); boxes = postProcessor.BoxesFromBitmap(
predMap, bitMap, dbParameter.BoxThreshold, dbParameter.UnclipRatio, dbParameter.ScoreMode);
boxes = postProcessor.FilterTagDetRes(boxes, ratioH, ratioW, srcImage); boxes = postProcessor.FilterTagDetRes(boxes, ratioH, ratioW, srcImage);
std::vector<migraphxSamples::OCRPredictResult> ocrResults; std::vector<migraphxSamples::OCRPredictResult> ocrResults;
for (int i = 0; i < boxes.size(); i++) for(int i = 0; i < boxes.size(); i++)
{ {
OCRPredictResult res; OCRPredictResult res;
res.box = boxes[i]; res.box = boxes[i];
...@@ -194,7 +189,7 @@ ErrorCode DB::Infer(const cv::Mat &img, std::vector<cv::Mat> &imgList) ...@@ -194,7 +189,7 @@ ErrorCode DB::Infer(const cv::Mat &img, std::vector<cv::Mat> &imgList)
} }
Utility::sorted_boxes(ocrResults); Utility::sorted_boxes(ocrResults);
for (int j = 0; j < ocrResults.size(); j++) for(int j = 0; j < ocrResults.size(); j++)
{ {
cv::Mat cropImg; cv::Mat cropImg;
cropImg = Utility::GetRotateCropImage(img, ocrResults[j].box); cropImg = Utility::GetRotateCropImage(img, ocrResults[j].box);
...@@ -202,339 +197,361 @@ ErrorCode DB::Infer(const cv::Mat &img, std::vector<cv::Mat> &imgList) ...@@ -202,339 +197,361 @@ ErrorCode DB::Infer(const cv::Mat &img, std::vector<cv::Mat> &imgList)
} }
} }
void DBPostProcessor::GetContourArea(const std::vector<std::vector<float>> &box, void DBPostProcessor::GetContourArea(const std::vector<std::vector<float>>& box,
float unclip_ratio, float &distance) { float unclip_ratio,
int pts_num = 4; float& distance)
float area = 0.0f; {
float dist = 0.0f; int pts_num = 4;
for (int i = 0; i < pts_num; i++) { float area = 0.0f;
area += box[i][0] * box[(i + 1) % pts_num][1] - float dist = 0.0f;
box[i][1] * box[(i + 1) % pts_num][0]; for(int i = 0; i < pts_num; i++)
dist += sqrtf((box[i][0] - box[(i + 1) % pts_num][0]) * {
(box[i][0] - box[(i + 1) % pts_num][0]) + area += box[i][0] * box[(i + 1) % pts_num][1] - box[i][1] * box[(i + 1) % pts_num][0];
(box[i][1] - box[(i + 1) % pts_num][1]) * dist += sqrtf(
(box[i][1] - box[(i + 1) % pts_num][1])); (box[i][0] - box[(i + 1) % pts_num][0]) * (box[i][0] - box[(i + 1) % pts_num][0]) +
} (box[i][1] - box[(i + 1) % pts_num][1]) * (box[i][1] - box[(i + 1) % pts_num][1]));
area = fabs(float(area / 2.0)); }
area = fabs(float(area / 2.0));
distance = area * unclip_ratio / dist;
distance = area * unclip_ratio / dist;
} }
cv::RotatedRect DBPostProcessor::UnClip(std::vector<std::vector<float>> box, cv::RotatedRect DBPostProcessor::UnClip(std::vector<std::vector<float>> box,
const float &unclip_ratio) { const float& unclip_ratio)
float distance = 1.0; {
float distance = 1.0;
GetContourArea(box, unclip_ratio, distance);
GetContourArea(box, unclip_ratio, distance);
ClipperLib::ClipperOffset offset;
ClipperLib::Path p; ClipperLib::ClipperOffset offset;
p << ClipperLib::IntPoint(int(box[0][0]), int(box[0][1])) ClipperLib::Path p;
<< ClipperLib::IntPoint(int(box[1][0]), int(box[1][1])) p << ClipperLib::IntPoint(int(box[0][0]), int(box[0][1]))
<< ClipperLib::IntPoint(int(box[2][0]), int(box[2][1])) << ClipperLib::IntPoint(int(box[1][0]), int(box[1][1]))
<< ClipperLib::IntPoint(int(box[3][0]), int(box[3][1])); << ClipperLib::IntPoint(int(box[2][0]), int(box[2][1]))
offset.AddPath(p, ClipperLib::jtRound, ClipperLib::etClosedPolygon); << ClipperLib::IntPoint(int(box[3][0]), int(box[3][1]));
offset.AddPath(p, ClipperLib::jtRound, ClipperLib::etClosedPolygon);
ClipperLib::Paths soln;
offset.Execute(soln, distance); ClipperLib::Paths soln;
std::vector<cv::Point2f> points; offset.Execute(soln, distance);
std::vector<cv::Point2f> points;
for (int j = 0; j < soln.size(); j++) {
for (int i = 0; i < soln[soln.size() - 1].size(); i++) { for(int j = 0; j < soln.size(); j++)
points.emplace_back(soln[j][i].X, soln[j][i].Y); {
for(int i = 0; i < soln[soln.size() - 1].size(); i++)
{
points.emplace_back(soln[j][i].X, soln[j][i].Y);
}
}
cv::RotatedRect res;
if(points.size() <= 0)
{
res = cv::RotatedRect(cv::Point2f(0, 0), cv::Size2f(1, 1), 0);
}
else
{
res = cv::minAreaRect(points);
} }
} return res;
cv::RotatedRect res;
if (points.size() <= 0) {
res = cv::RotatedRect(cv::Point2f(0, 0), cv::Size2f(1, 1), 0);
} else {
res = cv::minAreaRect(points);
}
return res;
} }
float **DBPostProcessor::Mat2Vec(cv::Mat mat) { float** DBPostProcessor::Mat2Vec(cv::Mat mat)
auto **array = new float *[mat.rows]; {
for (int i = 0; i < mat.rows; ++i) auto** array = new float*[mat.rows];
array[i] = new float[mat.cols]; for(int i = 0; i < mat.rows; ++i)
for (int i = 0; i < mat.rows; ++i) { array[i] = new float[mat.cols];
for (int j = 0; j < mat.cols; ++j) { for(int i = 0; i < mat.rows; ++i)
array[i][j] = mat.at<float>(i, j); {
for(int j = 0; j < mat.cols; ++j)
{
array[i][j] = mat.at<float>(i, j);
}
} }
}
return array; return array;
} }
std::vector<std::vector<int>> std::vector<std::vector<int>>
DBPostProcessor::OrderPointsClockwise(std::vector<std::vector<int>> pts) { DBPostProcessor::OrderPointsClockwise(std::vector<std::vector<int>> pts)
std::vector<std::vector<int>> box = pts; {
std::sort(box.begin(), box.end(), XsortInt); std::vector<std::vector<int>> box = pts;
std::sort(box.begin(), box.end(), XsortInt);
std::vector<std::vector<int>> leftmost = {box[0], box[1]}; std::vector<std::vector<int>> leftmost = {box[0], box[1]};
std::vector<std::vector<int>> rightmost = {box[2], box[3]}; std::vector<std::vector<int>> rightmost = {box[2], box[3]};
if (leftmost[0][1] > leftmost[1][1]) if(leftmost[0][1] > leftmost[1][1])
std::swap(leftmost[0], leftmost[1]); std::swap(leftmost[0], leftmost[1]);
if (rightmost[0][1] > rightmost[1][1]) if(rightmost[0][1] > rightmost[1][1])
std::swap(rightmost[0], rightmost[1]); std::swap(rightmost[0], rightmost[1]);
std::vector<std::vector<int>> rect = {leftmost[0], rightmost[0], rightmost[1], std::vector<std::vector<int>> rect = {leftmost[0], rightmost[0], rightmost[1], leftmost[1]};
leftmost[1]}; return rect;
return rect;
} }
std::vector<std::vector<float>> DBPostProcessor::Mat2Vector(cv::Mat mat) { std::vector<std::vector<float>> DBPostProcessor::Mat2Vector(cv::Mat mat)
std::vector<std::vector<float>> img_vec; {
std::vector<float> tmp; std::vector<std::vector<float>> img_vec;
std::vector<float> tmp;
for (int i = 0; i < mat.rows; ++i) { for(int i = 0; i < mat.rows; ++i)
tmp.clear(); {
for (int j = 0; j < mat.cols; ++j) { tmp.clear();
tmp.push_back(mat.at<float>(i, j)); for(int j = 0; j < mat.cols; ++j)
{
tmp.push_back(mat.at<float>(i, j));
}
img_vec.push_back(tmp);
} }
img_vec.push_back(tmp); return img_vec;
}
return img_vec;
} }
bool DBPostProcessor::XsortFp32(std::vector<float> a, std::vector<float> b) { bool DBPostProcessor::XsortFp32(std::vector<float> a, std::vector<float> b)
if (a[0] != b[0]) {
return a[0] < b[0]; if(a[0] != b[0])
return false; return a[0] < b[0];
return false;
} }
bool DBPostProcessor::XsortInt(std::vector<int> a, std::vector<int> b) { bool DBPostProcessor::XsortInt(std::vector<int> a, std::vector<int> b)
if (a[0] != b[0]) {
return a[0] < b[0]; if(a[0] != b[0])
return false; return a[0] < b[0];
return false;
} }
std::vector<std::vector<float>> std::vector<std::vector<float>> DBPostProcessor::GetMiniBoxes(cv::RotatedRect box, float& ssid)
DBPostProcessor::GetMiniBoxes(cv::RotatedRect box, float &ssid) { {
ssid = std::max(box.size.width, box.size.height); ssid = std::max(box.size.width, box.size.height);
cv::Mat points; cv::Mat points;
cv::boxPoints(box, points); cv::boxPoints(box, points);
auto array = Mat2Vector(points); auto array = Mat2Vector(points);
std::sort(array.begin(), array.end(), XsortFp32); std::sort(array.begin(), array.end(), XsortFp32);
std::vector<float> idx1 = array[0], idx2 = array[1], idx3 = array[2], std::vector<float> idx1 = array[0], idx2 = array[1], idx3 = array[2], idx4 = array[3];
idx4 = array[3]; if(array[3][1] <= array[2][1])
if (array[3][1] <= array[2][1]) { {
idx2 = array[3]; idx2 = array[3];
idx3 = array[2]; idx3 = array[2];
} else { }
idx2 = array[2]; else
idx3 = array[3]; {
} idx2 = array[2];
if (array[1][1] <= array[0][1]) { idx3 = array[3];
idx1 = array[1]; }
idx4 = array[0]; if(array[1][1] <= array[0][1])
} else { {
idx1 = array[0]; idx1 = array[1];
idx4 = array[1]; idx4 = array[0];
} }
else
array[0] = idx1; {
array[1] = idx2; idx1 = array[0];
array[2] = idx3; idx4 = array[1];
array[3] = idx4; }
return array; array[0] = idx1;
array[1] = idx2;
array[2] = idx3;
array[3] = idx4;
return array;
} }
float DBPostProcessor::PolygonScoreAcc(std::vector<cv::Point> contour, float DBPostProcessor::PolygonScoreAcc(std::vector<cv::Point> contour, cv::Mat pred)
cv::Mat pred) { {
int width = pred.cols; int width = pred.cols;
int height = pred.rows; int height = pred.rows;
std::vector<float> box_x; std::vector<float> box_x;
std::vector<float> box_y; std::vector<float> box_y;
for (int i = 0; i < contour.size(); ++i) { for(int i = 0; i < contour.size(); ++i)
box_x.push_back(contour[i].x); {
box_y.push_back(contour[i].y); box_x.push_back(contour[i].x);
} box_y.push_back(contour[i].y);
}
int xmin =
clamp(int(std::floor(*(std::min_element(box_x.begin(), box_x.end())))), 0, int xmin =
width - 1); clamp(int(std::floor(*(std::min_element(box_x.begin(), box_x.end())))), 0, width - 1);
int xmax = int xmax = clamp(int(std::ceil(*(std::max_element(box_x.begin(), box_x.end())))), 0, width - 1);
clamp(int(std::ceil(*(std::max_element(box_x.begin(), box_x.end())))), 0, int ymin =
width - 1); clamp(int(std::floor(*(std::min_element(box_y.begin(), box_y.end())))), 0, height - 1);
int ymin = int ymax =
clamp(int(std::floor(*(std::min_element(box_y.begin(), box_y.end())))), 0, clamp(int(std::ceil(*(std::max_element(box_y.begin(), box_y.end())))), 0, height - 1);
height - 1);
int ymax = cv::Mat mask;
clamp(int(std::ceil(*(std::max_element(box_y.begin(), box_y.end())))), 0, mask = cv::Mat::zeros(ymax - ymin + 1, xmax - xmin + 1, CV_8UC1);
height - 1);
cv::Point* rook_point = new cv::Point[contour.size()];
cv::Mat mask;
mask = cv::Mat::zeros(ymax - ymin + 1, xmax - xmin + 1, CV_8UC1); for(int i = 0; i < contour.size(); ++i)
{
cv::Point *rook_point = new cv::Point[contour.size()]; rook_point[i] = cv::Point(int(box_x[i]) - xmin, int(box_y[i]) - ymin);
}
for (int i = 0; i < contour.size(); ++i) { const cv::Point* ppt[1] = {rook_point};
rook_point[i] = cv::Point(int(box_x[i]) - xmin, int(box_y[i]) - ymin); int npt[] = {int(contour.size())};
}
const cv::Point *ppt[1] = {rook_point}; cv::fillPoly(mask, ppt, npt, 1, cv::Scalar(1));
int npt[] = {int(contour.size())};
cv::Mat croppedImg;
cv::fillPoly(mask, ppt, npt, 1, cv::Scalar(1)); pred(cv::Rect(xmin, ymin, xmax - xmin + 1, ymax - ymin + 1)).copyTo(croppedImg);
float score = cv::mean(croppedImg, mask)[0];
cv::Mat croppedImg;
pred(cv::Rect(xmin, ymin, xmax - xmin + 1, ymax - ymin + 1)) delete[] rook_point;
.copyTo(croppedImg); return score;
float score = cv::mean(croppedImg, mask)[0];
delete[] rook_point;
return score;
} }
float DBPostProcessor::BoxScoreFast(std::vector<std::vector<float>> box_array, float DBPostProcessor::BoxScoreFast(std::vector<std::vector<float>> box_array, cv::Mat pred)
cv::Mat pred) { {
auto array = box_array; auto array = box_array;
int width = pred.cols; int width = pred.cols;
int height = pred.rows; int height = pred.rows;
float box_x[4] = {array[0][0], array[1][0], array[2][0], array[3][0]}; float box_x[4] = {array[0][0], array[1][0], array[2][0], array[3][0]};
float box_y[4] = {array[0][1], array[1][1], array[2][1], array[3][1]}; float box_y[4] = {array[0][1], array[1][1], array[2][1], array[3][1]};
int xmin = clamp(int(std::floor(*(std::min_element(box_x, box_x + 4)))), 0, int xmin = clamp(int(std::floor(*(std::min_element(box_x, box_x + 4)))), 0, width - 1);
width - 1); int xmax = clamp(int(std::ceil(*(std::max_element(box_x, box_x + 4)))), 0, width - 1);
int xmax = clamp(int(std::ceil(*(std::max_element(box_x, box_x + 4)))), 0, int ymin = clamp(int(std::floor(*(std::min_element(box_y, box_y + 4)))), 0, height - 1);
width - 1); int ymax = clamp(int(std::ceil(*(std::max_element(box_y, box_y + 4)))), 0, height - 1);
int ymin = clamp(int(std::floor(*(std::min_element(box_y, box_y + 4)))), 0,
height - 1); cv::Mat mask;
int ymax = clamp(int(std::ceil(*(std::max_element(box_y, box_y + 4)))), 0, mask = cv::Mat::zeros(ymax - ymin + 1, xmax - xmin + 1, CV_8UC1);
height - 1);
cv::Point root_point[4];
cv::Mat mask; root_point[0] = cv::Point(int(array[0][0]) - xmin, int(array[0][1]) - ymin);
mask = cv::Mat::zeros(ymax - ymin + 1, xmax - xmin + 1, CV_8UC1); root_point[1] = cv::Point(int(array[1][0]) - xmin, int(array[1][1]) - ymin);
root_point[2] = cv::Point(int(array[2][0]) - xmin, int(array[2][1]) - ymin);
cv::Point root_point[4]; root_point[3] = cv::Point(int(array[3][0]) - xmin, int(array[3][1]) - ymin);
root_point[0] = cv::Point(int(array[0][0]) - xmin, int(array[0][1]) - ymin); const cv::Point* ppt[1] = {root_point};
root_point[1] = cv::Point(int(array[1][0]) - xmin, int(array[1][1]) - ymin); int npt[] = {4};
root_point[2] = cv::Point(int(array[2][0]) - xmin, int(array[2][1]) - ymin); cv::fillPoly(mask, ppt, npt, 1, cv::Scalar(1));
root_point[3] = cv::Point(int(array[3][0]) - xmin, int(array[3][1]) - ymin);
const cv::Point *ppt[1] = {root_point}; cv::Mat croppedImg;
int npt[] = {4}; pred(cv::Rect(xmin, ymin, xmax - xmin + 1, ymax - ymin + 1)).copyTo(croppedImg);
cv::fillPoly(mask, ppt, npt, 1, cv::Scalar(1));
auto score = cv::mean(croppedImg, mask)[0];
cv::Mat croppedImg; return score;
pred(cv::Rect(xmin, ymin, xmax - xmin + 1, ymax - ymin + 1))
.copyTo(croppedImg);
auto score = cv::mean(croppedImg, mask)[0];
return score;
} }
std::vector<std::vector<std::vector<int>>> DBPostProcessor::BoxesFromBitmap( std::vector<std::vector<std::vector<int>>>
const cv::Mat pred, const cv::Mat bitmap, const float &box_thresh, DBPostProcessor::BoxesFromBitmap(const cv::Mat pred,
const float &det_db_unclip_ratio, const std::string &det_db_score_mode) { const cv::Mat bitmap,
const int min_size = 3; const float& box_thresh,
const int max_candidates = 2000; const float& det_db_unclip_ratio,
const std::string& det_db_score_mode)
{
const int min_size = 3;
const int max_candidates = 2000;
int width = bitmap.cols; int width = bitmap.cols;
int height = bitmap.rows; int height = bitmap.rows;
std::vector<std::vector<cv::Point>> contours; std::vector<std::vector<cv::Point>> contours;
std::vector<cv::Vec4i> hierarchy; std::vector<cv::Vec4i> hierarchy;
cv::findContours(bitmap, contours, hierarchy, cv::RETR_LIST, cv::findContours(bitmap, contours, hierarchy, cv::RETR_LIST, cv::CHAIN_APPROX_SIMPLE);
cv::CHAIN_APPROX_SIMPLE);
int num_contours = int num_contours = contours.size() >= max_candidates ? max_candidates : contours.size();
contours.size() >= max_candidates ? max_candidates : contours.size();
std::vector<std::vector<std::vector<int>>> boxes; std::vector<std::vector<std::vector<int>>> boxes;
for (int _i = 0; _i < num_contours; _i++) { for(int _i = 0; _i < num_contours; _i++)
if (contours[_i].size() <= 2) { {
continue; if(contours[_i].size() <= 2)
} {
float ssid; continue;
cv::RotatedRect box = cv::minAreaRect(contours[_i]); }
auto array = GetMiniBoxes(box, ssid); float ssid;
cv::RotatedRect box = cv::minAreaRect(contours[_i]);
auto array = GetMiniBoxes(box, ssid);
auto box_for_unclip = array; auto box_for_unclip = array;
// end get_mini_box // end get_mini_box
if (ssid < min_size) { if(ssid < min_size)
continue; {
} continue;
}
float score; float score;
if (det_db_score_mode == "slow") if(det_db_score_mode == "slow")
/* compute using polygon*/ /* compute using polygon*/
score = PolygonScoreAcc(contours[_i], pred); score = PolygonScoreAcc(contours[_i], pred);
else else
score = BoxScoreFast(array, pred); score = BoxScoreFast(array, pred);
if (score < box_thresh) if(score < box_thresh)
continue; continue;
// start for unclip // start for unclip
cv::RotatedRect points = UnClip(box_for_unclip, det_db_unclip_ratio); cv::RotatedRect points = UnClip(box_for_unclip, det_db_unclip_ratio);
if (points.size.height < 1.001 && points.size.width < 1.001) { if(points.size.height < 1.001 && points.size.width < 1.001)
continue; {
} continue;
// end for unclip }
// end for unclip
cv::RotatedRect clipbox = points;
auto cliparray = GetMiniBoxes(clipbox, ssid); cv::RotatedRect clipbox = points;
auto cliparray = GetMiniBoxes(clipbox, ssid);
if (ssid < min_size + 2)
continue; if(ssid < min_size + 2)
continue;
int dest_width = pred.cols;
int dest_height = pred.rows; int dest_width = pred.cols;
std::vector<std::vector<int>> intcliparray; int dest_height = pred.rows;
std::vector<std::vector<int>> intcliparray;
for (int num_pt = 0; num_pt < 4; num_pt++) {
std::vector<int> a{int(clampf(roundf(cliparray[num_pt][0] / float(width) *
float(dest_width)),
0, float(dest_width))),
int(clampf(roundf(cliparray[num_pt][1] /
float(height) * float(dest_height)),
0, float(dest_height)))};
intcliparray.push_back(a);
}
boxes.push_back(intcliparray);
} // end for for(int num_pt = 0; num_pt < 4; num_pt++)
return boxes; {
std::vector<int> a{
int(clampf(roundf(cliparray[num_pt][0] / float(width) * float(dest_width)),
0,
float(dest_width))),
int(clampf(roundf(cliparray[num_pt][1] / float(height) * float(dest_height)),
0,
float(dest_height)))};
intcliparray.push_back(a);
}
boxes.push_back(intcliparray);
} // end for
return boxes;
} }
std::vector<std::vector<std::vector<int>>> DBPostProcessor::FilterTagDetRes( std::vector<std::vector<std::vector<int>>> DBPostProcessor::FilterTagDetRes(
std::vector<std::vector<std::vector<int>>> boxes, float ratio_h, std::vector<std::vector<std::vector<int>>> boxes, float ratio_h, float ratio_w, cv::Mat srcimg)
float ratio_w, cv::Mat srcimg) { {
int oriimg_h = srcimg.rows; int oriimg_h = srcimg.rows;
int oriimg_w = srcimg.cols; int oriimg_w = srcimg.cols;
std::vector<std::vector<std::vector<int>>> root_points; std::vector<std::vector<std::vector<int>>> root_points;
for (int n = 0; n < boxes.size(); n++) { for(int n = 0; n < boxes.size(); n++)
boxes[n] = OrderPointsClockwise(boxes[n]); {
for (int m = 0; m < boxes[0].size(); m++) { boxes[n] = OrderPointsClockwise(boxes[n]);
boxes[n][m][0] /= ratio_w; for(int m = 0; m < boxes[0].size(); m++)
boxes[n][m][1] /= ratio_h; {
boxes[n][m][0] /= ratio_w;
boxes[n][m][0] = int(_min(_max(boxes[n][m][0], 0), oriimg_w - 1)); boxes[n][m][1] /= ratio_h;
boxes[n][m][1] = int(_min(_max(boxes[n][m][1], 0), oriimg_h - 1));
boxes[n][m][0] = int(_min(_max(boxes[n][m][0], 0), oriimg_w - 1));
boxes[n][m][1] = int(_min(_max(boxes[n][m][1], 0), oriimg_h - 1));
}
}
for(int n = 0; n < boxes.size(); n++)
{
int rect_width, rect_height;
rect_width = int(sqrt(pow(boxes[n][0][0] - boxes[n][1][0], 2) +
pow(boxes[n][0][1] - boxes[n][1][1], 2)));
rect_height = int(sqrt(pow(boxes[n][0][0] - boxes[n][3][0], 2) +
pow(boxes[n][0][1] - boxes[n][3][1], 2)));
if(rect_width <= 4 || rect_height <= 4)
continue;
root_points.push_back(boxes[n]);
} }
} return root_points;
for (int n = 0; n < boxes.size(); n++) {
int rect_width, rect_height;
rect_width = int(sqrt(pow(boxes[n][0][0] - boxes[n][1][0], 2) +
pow(boxes[n][0][1] - boxes[n][1][1], 2)));
rect_height = int(sqrt(pow(boxes[n][0][0] - boxes[n][3][0], 2) +
pow(boxes[n][0][1] - boxes[n][3][1], 2)));
if (rect_width <= 4 || rect_height <= 4)
continue;
root_points.push_back(boxes[n]);
}
return root_points;
} }
} } // namespace migraphxSamples
\ No newline at end of file \ No newline at end of file
...@@ -20,20 +20,20 @@ typedef struct _DBParameter ...@@ -20,20 +20,20 @@ typedef struct _DBParameter
int LimitSideLen; int LimitSideLen;
std::string ScoreMode; std::string ScoreMode;
}DBParameter; } DBParameter;
class DB class DB
{ {
public: public:
DB(); DB();
~DB(); ~DB();
ErrorCode Initialize(InitializationParameterOfDB InitializationParameterOfDB); ErrorCode Initialize(InitializationParameterOfDB InitializationParameterOfDB);
ErrorCode Infer(const cv::Mat &img, std::vector<cv::Mat> &imgList); ErrorCode Infer(const cv::Mat& img, std::vector<cv::Mat>& imgList);
private: private:
cv::FileStorage configurationFile; cv::FileStorage configurationFile;
migraphx::program net; migraphx::program net;
...@@ -41,65 +41,69 @@ private: ...@@ -41,65 +41,69 @@ private:
std::string inputName; std::string inputName;
migraphx::shape inputShape; migraphx::shape inputShape;
DBParameter dbParameter; DBParameter dbParameter;
}; };
class DBPostProcessor { class DBPostProcessor
public: {
void GetContourArea(const std::vector<std::vector<float>> &box, public:
float unclip_ratio, float &distance); void
GetContourArea(const std::vector<std::vector<float>>& box, float unclip_ratio, float& distance);
cv::RotatedRect UnClip(std::vector<std::vector<float>> box, cv::RotatedRect UnClip(std::vector<std::vector<float>> box, const float& unclip_ratio);
const float &unclip_ratio);
float **Mat2Vec(cv::Mat mat); float** Mat2Vec(cv::Mat mat);
std::vector<std::vector<int>> std::vector<std::vector<int>> OrderPointsClockwise(std::vector<std::vector<int>> pts);
OrderPointsClockwise(std::vector<std::vector<int>> pts);
std::vector<std::vector<float>> GetMiniBoxes(cv::RotatedRect box, std::vector<std::vector<float>> GetMiniBoxes(cv::RotatedRect box, float& ssid);
float &ssid);
float BoxScoreFast(std::vector<std::vector<float>> box_array, cv::Mat pred); float BoxScoreFast(std::vector<std::vector<float>> box_array, cv::Mat pred);
float PolygonScoreAcc(std::vector<cv::Point> contour, cv::Mat pred); float PolygonScoreAcc(std::vector<cv::Point> contour, cv::Mat pred);
std::vector<std::vector<std::vector<int>>> std::vector<std::vector<std::vector<int>>>
BoxesFromBitmap(const cv::Mat pred, const cv::Mat bitmap, BoxesFromBitmap(const cv::Mat pred,
const float &box_thresh, const float &det_db_unclip_ratio, const cv::Mat bitmap,
const std::string &det_db_score_mode); const float& box_thresh,
const float& det_db_unclip_ratio,
const std::string& det_db_score_mode);
std::vector<std::vector<std::vector<int>>> std::vector<std::vector<std::vector<int>>>
FilterTagDetRes(std::vector<std::vector<std::vector<int>>> boxes, FilterTagDetRes(std::vector<std::vector<std::vector<int>>> boxes,
float ratio_h, float ratio_w, cv::Mat srcimg); float ratio_h,
float ratio_w,
cv::Mat srcimg);
private: private:
static bool XsortInt(std::vector<int> a, std::vector<int> b); static bool XsortInt(std::vector<int> a, std::vector<int> b);
static bool XsortFp32(std::vector<float> a, std::vector<float> b); static bool XsortFp32(std::vector<float> a, std::vector<float> b);
std::vector<std::vector<float>> Mat2Vector(cv::Mat mat); std::vector<std::vector<float>> Mat2Vector(cv::Mat mat);
inline int _max(int a, int b) { return a >= b ? a : b; } inline int _max(int a, int b) { return a >= b ? a : b; }
inline int _min(int a, int b) { return a >= b ? b : a; } inline int _min(int a, int b) { return a >= b ? b : a; }
template <class T> inline T clamp(T x, T min, T max) { template <class T>
if (x > max) inline T clamp(T x, T min, T max)
return max; {
if (x < min) if(x > max)
return min; return max;
return x; if(x < min)
} return min;
return x;
}
inline float clampf(float x, float min, float max) { inline float clampf(float x, float min, float max)
if (x > max) {
return max; if(x > max)
if (x < min) return max;
return min; if(x < min)
return x; return min;
} return x;
}
}; };
} } // namespace migraphxSamples
#endif #endif
\ No newline at end of file
...@@ -6,20 +6,14 @@ ...@@ -6,20 +6,14 @@
namespace migraphxSamples namespace migraphxSamples
{ {
SVTR::SVTR() SVTR::SVTR() {}
{
}
SVTR::~SVTR() SVTR::~SVTR() { configurationFile.release(); }
{
configurationFile.release();
}
ErrorCode SVTR::Initialize(InitializationParameterOfSVTR InitializationParameterOfSVTR) ErrorCode SVTR::Initialize(InitializationParameterOfSVTR InitializationParameterOfSVTR)
{ {
// 读取配置文件 // 读取配置文件
std::string configFilePath=InitializationParameterOfSVTR.configFilePath; std::string configFilePath = InitializationParameterOfSVTR.configFilePath;
if(!Exists(configFilePath)) if(!Exists(configFilePath))
{ {
LOG_ERROR(stdout, "no configuration file!\n"); LOG_ERROR(stdout, "no configuration file!\n");
...@@ -27,58 +21,58 @@ ErrorCode SVTR::Initialize(InitializationParameterOfSVTR InitializationParameter ...@@ -27,58 +21,58 @@ ErrorCode SVTR::Initialize(InitializationParameterOfSVTR InitializationParameter
} }
if(!configurationFile.open(configFilePath, cv::FileStorage::READ)) if(!configurationFile.open(configFilePath, cv::FileStorage::READ))
{ {
LOG_ERROR(stdout, "fail to open configuration file\n"); LOG_ERROR(stdout, "fail to open configuration file\n");
return FAIL_TO_OPEN_CONFIG_FILE; return FAIL_TO_OPEN_CONFIG_FILE;
} }
LOG_INFO(stdout, "succeed to open configuration file\n"); LOG_INFO(stdout, "succeed to open configuration file\n");
// 获取配置文件参数 // 获取配置文件参数
cv::FileNode netNode = configurationFile["OcrSVTR"]; cv::FileNode netNode = configurationFile["OcrSVTR"];
std::string modelPath = (std::string)netNode["ModelPath"]; std::string modelPath = (std::string)netNode["ModelPath"];
std::string dictPath = (std::string)netNode["DictPath"]; std::string dictPath = (std::string)netNode["DictPath"];
// 加载模型 // 加载模型
if(!Exists(modelPath)) if(!Exists(modelPath))
{ {
LOG_ERROR(stdout,"%s not exist!\n",modelPath.c_str()); LOG_ERROR(stdout, "%s not exist!\n", modelPath.c_str());
return MODEL_NOT_EXIST; return MODEL_NOT_EXIST;
} }
migraphx::onnx_options onnx_options; migraphx::onnx_options onnx_options;
onnx_options.map_input_dims["x"]={1,3,48,320}; // 设置最大shape onnx_options.map_input_dims["x"] = {1, 3, 48, 320}; // 设置最大shape
net = migraphx::parse_onnx(modelPath, onnx_options); net = migraphx::parse_onnx(modelPath, onnx_options);
LOG_INFO(stdout,"succeed to load model: %s\n",GetFileName(modelPath).c_str()); LOG_INFO(stdout, "succeed to load model: %s\n", GetFileName(modelPath).c_str());
// 获取模型输入/输出节点信息 // 获取模型输入/输出节点信息
std::unordered_map<std::string, migraphx::shape> inputs=net.get_inputs(); std::unordered_map<std::string, migraphx::shape> inputs = net.get_inputs();
std::unordered_map<std::string, migraphx::shape> outputs=net.get_outputs(); std::unordered_map<std::string, migraphx::shape> outputs = net.get_outputs();
inputName=inputs.begin()->first; inputName = inputs.begin()->first;
inputShape=inputs.begin()->second; inputShape = inputs.begin()->second;
int N=inputShape.lens()[0]; int N = inputShape.lens()[0];
int C=inputShape.lens()[1]; int C = inputShape.lens()[1];
int H=inputShape.lens()[2]; int H = inputShape.lens()[2];
int W=inputShape.lens()[3]; int W = inputShape.lens()[3];
inputSize=cv::Size(W,H); inputSize = cv::Size(W, H);
// 设置模型为GPU模式 // 设置模型为GPU模式
migraphx::target gpuTarget = migraphx::gpu::target{}; migraphx::target gpuTarget = migraphx::gpu::target{};
// 编译模型 // 编译模型
migraphx::compile_options options; migraphx::compile_options options;
options.device_id=0; // 设置GPU设备,默认为0号设备 options.device_id = 0; // 设置GPU设备,默认为0号设备
options.offload_copy=true; options.offload_copy = true;
net.compile(gpuTarget,options); net.compile(gpuTarget, options);
LOG_INFO(stdout,"succeed to compile model: %s\n",GetFileName(modelPath).c_str()); LOG_INFO(stdout, "succeed to compile model: %s\n", GetFileName(modelPath).c_str());
// warm up // warm up
std::unordered_map<std::string, migraphx::argument> inputData; std::unordered_map<std::string, migraphx::argument> inputData;
inputData[inputName]=migraphx::argument{inputShape}; inputData[inputName] = migraphx::argument{inputShape};
net.eval(inputData); net.eval(inputData);
std::ifstream in(dictPath); std::ifstream in(dictPath);
std::string line; std::string line;
if (in) if(in)
{ {
while (getline(in, line)) while(getline(in, line))
{ {
charactorDict.push_back(line); charactorDict.push_back(line);
} }
...@@ -92,15 +86,16 @@ ErrorCode SVTR::Initialize(InitializationParameterOfSVTR InitializationParameter ...@@ -92,15 +86,16 @@ ErrorCode SVTR::Initialize(InitializationParameterOfSVTR InitializationParameter
} }
// log // log
LOG_INFO(stdout,"InputMaxSize:%dx%d\n",inputSize.width,inputSize.height); LOG_INFO(stdout, "InputMaxSize:%dx%d\n", inputSize.width, inputSize.height);
LOG_INFO(stdout,"InputName:%s\n",inputName.c_str()); LOG_INFO(stdout, "InputName:%s\n", inputName.c_str());
return SUCCESS; return SUCCESS;
} }
ErrorCode SVTR::Infer(cv::Mat &img, std::string &resultsChar, float &resultsdScore, float &maxWHRatio) ErrorCode
SVTR::Infer(cv::Mat& img, std::string& resultsChar, float& resultsdScore, float& maxWHRatio)
{ {
if(img.empty()||img.type()!=CV_8UC3) if(img.empty() || img.type() != CV_8UC3)
{ {
LOG_ERROR(stdout, "image error!\n"); LOG_ERROR(stdout, "image error!\n");
return IMAGE_ERROR; return IMAGE_ERROR;
...@@ -114,8 +109,8 @@ ErrorCode SVTR::Infer(cv::Mat &img, std::string &resultsChar, float &resultsdSco ...@@ -114,8 +109,8 @@ ErrorCode SVTR::Infer(cv::Mat &img, std::string &resultsChar, float &resultsdSco
int imgC = 3, imgH = 48; int imgC = 3, imgH = 48;
int resizeW; int resizeW;
int imgW = int((48 * maxWHRatio)); int imgW = int((48 * maxWHRatio));
ratio = float(srcImage.cols) / float(srcImage.rows); ratio = float(srcImage.cols) / float(srcImage.rows);
if (ceil(imgH * ratio) > imgW) if(ceil(imgH * ratio) > imgW)
{ {
resizeW = imgW; resizeW = imgW;
} }
...@@ -124,59 +119,64 @@ ErrorCode SVTR::Infer(cv::Mat &img, std::string &resultsChar, float &resultsdSco ...@@ -124,59 +119,64 @@ ErrorCode SVTR::Infer(cv::Mat &img, std::string &resultsChar, float &resultsdSco
resizeW = int(ceil(imgH * ratio)); resizeW = int(ceil(imgH * ratio));
} }
cv::resize(srcImage, resizeImg, cv::Size(resizeW, imgH)); cv::resize(srcImage, resizeImg, cv::Size(resizeW, imgH));
cv::copyMakeBorder(resizeImg, resizeImg, 0, 0, 0, cv::copyMakeBorder(resizeImg,
int(imgW - resizeImg.cols), cv::BORDER_CONSTANT, resizeImg,
{127, 127, 127}); 0,
0,
resizeImg.convertTo(resizeImg, CV_32FC3, 1.0/255.0); 0,
int(imgW - resizeImg.cols),
cv::BORDER_CONSTANT,
{127, 127, 127});
resizeImg.convertTo(resizeImg, CV_32FC3, 1.0 / 255.0);
std::vector<cv::Mat> bgrChannels(3); std::vector<cv::Mat> bgrChannels(3);
cv::split(resizeImg, bgrChannels); cv::split(resizeImg, bgrChannels);
std::vector<float> mean = {0.485f, 0.456f, 0.406f}; std::vector<float> mean = {0.485f, 0.456f, 0.406f};
std::vector<float> scale = {1 / 0.229f, 1 / 0.224f, 1 / 0.225f}; std::vector<float> scale = {1 / 0.229f, 1 / 0.224f, 1 / 0.225f};
for (auto i = 0; i < bgrChannels.size(); i++) for(auto i = 0; i < bgrChannels.size(); i++)
{ {
bgrChannels[i].convertTo(bgrChannels[i], CV_32FC1, 1.0 * scale[i], bgrChannels[i].convertTo(
(0.0 - mean[i]) * scale[i]); bgrChannels[i], CV_32FC1, 1.0 * scale[i], (0.0 - mean[i]) * scale[i]);
} }
cv::merge(bgrChannels, resizeImg); cv::merge(bgrChannels, resizeImg);
cv::Mat inputBlob = cv::dnn::blobFromImage(resizeImg); cv::Mat inputBlob = cv::dnn::blobFromImage(resizeImg);
std::vector<std::size_t> inputShapeOfInfer={1,3,48,resizeW}; std::vector<std::size_t> inputShapeOfInfer = {1, 3, 48, resizeW};
// 创建输入数据 // 创建输入数据
std::unordered_map<std::string, migraphx::argument> inputData; std::unordered_map<std::string, migraphx::argument> inputData;
inputData[inputName]= migraphx::argument{migraphx::shape(inputShape.type(),inputShapeOfInfer), (float*)inputBlob.data}; inputData[inputName] = migraphx::argument{migraphx::shape(inputShape.type(), inputShapeOfInfer),
(float*)inputBlob.data};
// 推理 // 推理
std::vector<migraphx::argument> inferenceResults = net.eval(inputData); std::vector<migraphx::argument> inferenceResults = net.eval(inputData);
// 获取推理结果 // 获取推理结果
migraphx::argument result = inferenceResults[0]; migraphx::argument result = inferenceResults[0];
migraphx::shape outputShape = result.get_shape(); migraphx::shape outputShape = result.get_shape();
int n2 = outputShape.lens()[1]; int n2 = outputShape.lens()[1];
int n3 = outputShape.lens()[2]; int n3 = outputShape.lens()[2];
int n = n2 * n3; int n = n2 * n3;
std::vector<float> out(n); std::vector<float> out(n);
memcpy(out.data(),result.data(),sizeof(float)*outputShape.elements()); memcpy(out.data(), result.data(), sizeof(float) * outputShape.elements());
out.resize(n); out.resize(n);
int argmaxIdx; int argmaxIdx;
int lastIndex = 0; int lastIndex = 0;
float score = 0.f; float score = 0.f;
int count = 0; int count = 0;
float maxValue = 0.0f; float maxValue = 0.0f;
for (int j = 0; j < n2; j++) for(int j = 0; j < n2; j++)
{ {
argmaxIdx = int(std::distance(&out[(j) * n3], argmaxIdx =
std::max_element(&out[(j) * n3], &out[(j + 1) * n3]))); int(std::distance(&out[(j)*n3], std::max_element(&out[(j)*n3], &out[(j + 1) * n3])));
maxValue = float(*std::max_element(&out[(j) * n3], maxValue = float(*std::max_element(&out[(j)*n3], &out[(j + 1) * n3]));
&out[(j + 1) * n3]));
if(argmaxIdx > 0 && (!(n > 0 && argmaxIdx == lastIndex)))
if (argmaxIdx > 0 && (!(n > 0 && argmaxIdx == lastIndex))) {
{ score += maxValue;
score += maxValue; count += 1;
count += 1; resultsChar += charactorDict[argmaxIdx];
resultsChar += charactorDict[argmaxIdx]; }
}
lastIndex = argmaxIdx; lastIndex = argmaxIdx;
} }
resultsdScore = score / count; resultsdScore = score / count;
...@@ -184,4 +184,4 @@ ErrorCode SVTR::Infer(cv::Mat &img, std::string &resultsChar, float &resultsdSco ...@@ -184,4 +184,4 @@ ErrorCode SVTR::Infer(cv::Mat &img, std::string &resultsChar, float &resultsdSco
return SUCCESS; return SUCCESS;
} }
} } // namespace migraphxSamples
...@@ -11,16 +11,17 @@ namespace migraphxSamples ...@@ -11,16 +11,17 @@ namespace migraphxSamples
class SVTR class SVTR
{ {
public: public:
SVTR(); SVTR();
~SVTR(); ~SVTR();
ErrorCode Initialize(InitializationParameterOfSVTR InitializationParameterOfSVTR); ErrorCode Initialize(InitializationParameterOfSVTR InitializationParameterOfSVTR);
ErrorCode Infer(cv::Mat &img, std::string &resultsChar, float &resultsdScore, float &maxWHRatio); ErrorCode
Infer(cv::Mat& img, std::string& resultsChar, float& resultsdScore, float& maxWHRatio);
private: private:
cv::FileStorage configurationFile; cv::FileStorage configurationFile;
migraphx::program net; migraphx::program net;
...@@ -29,8 +30,7 @@ private: ...@@ -29,8 +30,7 @@ private:
migraphx::shape inputShape; migraphx::shape inputShape;
std::string dictPath; std::string dictPath;
std::vector<std::string> charactorDict; std::vector<std::string> charactorDict;
}; };
} } // namespace migraphxSamples
#endif #endif
\ No newline at end of file
...@@ -3,22 +3,17 @@ ...@@ -3,22 +3,17 @@
namespace migraphxSamples namespace migraphxSamples
{ {
VLPR::VLPR() VLPR::VLPR() {}
{
} VLPR::~VLPR() { configurationFile.release(); }
VLPR::~VLPR() ErrorCode VLPR::Initialize(InitializationParameterOfDB initParamOfDB,
{ InitializationParameterOfSVTR initParamOfSVTR)
configurationFile.release();
}
ErrorCode VLPR::Initialize(InitializationParameterOfDB initParamOfDB, InitializationParameterOfSVTR initParamOfSVTR)
{ {
// 初始化DB // 初始化DB
initParamOfDB.configFilePath = CONFIG_FILE; initParamOfDB.configFilePath = CONFIG_FILE;
ErrorCode errorCode=db.Initialize(initParamOfDB); ErrorCode errorCode = db.Initialize(initParamOfDB);
if(errorCode!=SUCCESS) if(errorCode != SUCCESS)
{ {
LOG_ERROR(stdout, "fail to initialize db!\n"); LOG_ERROR(stdout, "fail to initialize db!\n");
exit(-1); exit(-1);
...@@ -27,8 +22,8 @@ ErrorCode VLPR::Initialize(InitializationParameterOfDB initParamOfDB, Initializa ...@@ -27,8 +22,8 @@ ErrorCode VLPR::Initialize(InitializationParameterOfDB initParamOfDB, Initializa
// 初始化SVTR // 初始化SVTR
initParamOfSVTR.configFilePath = CONFIG_FILE; initParamOfSVTR.configFilePath = CONFIG_FILE;
errorCode=svtr.Initialize(initParamOfSVTR); errorCode = svtr.Initialize(initParamOfSVTR);
if(errorCode!=SUCCESS) if(errorCode != SUCCESS)
{ {
LOG_ERROR(stdout, "fail to initialize svtr!\n"); LOG_ERROR(stdout, "fail to initialize svtr!\n");
exit(-1); exit(-1);
...@@ -36,15 +31,16 @@ ErrorCode VLPR::Initialize(InitializationParameterOfDB initParamOfDB, Initializa ...@@ -36,15 +31,16 @@ ErrorCode VLPR::Initialize(InitializationParameterOfDB initParamOfDB, Initializa
LOG_INFO(stdout, "succeed to initialize svtr\n"); LOG_INFO(stdout, "succeed to initialize svtr\n");
} }
ErrorCode VLPR::Infer(cv::Mat &img, std::vector<std::string> &recTexts, std::vector<float> &recTextScores) ErrorCode
VLPR::Infer(cv::Mat& img, std::vector<std::string>& recTexts, std::vector<float>& recTextScores)
{ {
// DB推理 // DB推理
db.Infer(img,imgLists); db.Infer(img, imgLists);
for (int i = 0; i < imgLists.size(); i++) for(int i = 0; i < imgLists.size(); i++)
{ {
float maxWHRatio = float(imgLists[i].cols) / float(imgLists[i].rows); float maxWHRatio = float(imgLists[i].cols) / float(imgLists[i].rows);
// SVTR推理 // SVTR推理
svtr.Infer(imgLists[i], recText, recTextScore, maxWHRatio); svtr.Infer(imgLists[i], recText, recTextScore, maxWHRatio);
recTexts.push_back(recText); recTexts.push_back(recText);
...@@ -52,7 +48,6 @@ ErrorCode VLPR::Infer(cv::Mat &img, std::vector<std::string> &recTexts, std::vec ...@@ -52,7 +48,6 @@ ErrorCode VLPR::Infer(cv::Mat &img, std::vector<std::string> &recTexts, std::vec
} }
return SUCCESS; return SUCCESS;
} }
} } // namespace migraphxSamples
\ No newline at end of file \ No newline at end of file
...@@ -12,24 +12,25 @@ namespace migraphxSamples ...@@ -12,24 +12,25 @@ namespace migraphxSamples
class VLPR class VLPR
{ {
public: public:
VLPR(); VLPR();
~VLPR(); ~VLPR();
ErrorCode Initialize(InitializationParameterOfDB initParamOfDB, InitializationParameterOfSVTR initParamOfSVTR); ErrorCode Initialize(InitializationParameterOfDB initParamOfDB,
InitializationParameterOfSVTR initParamOfSVTR);
ErrorCode Infer(cv::Mat &img, std::vector<std::string> &recTexts, std::vector<float> &recTextScores); ErrorCode
Infer(cv::Mat& img, std::vector<std::string>& recTexts, std::vector<float>& recTextScores);
private: private:
DB db; DB db;
SVTR svtr; SVTR svtr;
cv::FileStorage configurationFile; cv::FileStorage configurationFile;
std::vector<cv::Mat> imgLists; std::vector<cv::Mat> imgLists;
std::string recText; std::string recText;
float recTextScore; float recTextScore;
}; };
} } // namespace migraphxSamples
#endif #endif
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
/******************************************************************************* /*******************************************************************************
* * * *
* Author : Angus Johnson * * Author : Angus Johnson *
* Version : 6.4.2 * * Version : 6.4.2 *
* Date : 27 February 2017 * * Date : 27 February 2017 *
* Website : http://www.angusj.com * * Website : http://www.angusj.com *
* Copyright : Angus Johnson 2010-2017 * * Copyright : Angus Johnson 2010-2017 *
* * * *
* License: * * License: *
* Use, modification & distribution is subject to Boost Software License Ver 1. * * Use, modification & distribution is subject to Boost Software License Ver 1. *
* http://www.boost.org/LICENSE_1_0.txt * * http://www.boost.org/LICENSE_1_0.txt *
* * * *
* Attributions: * * Attributions: *
* The code in this library is an extension of Bala Vatti's clipping algorithm: * * The code in this library is an extension of Bala Vatti's clipping algorithm: *
* "A generic solution to polygon clipping" * * "A generic solution to polygon clipping" *
* Communications of the ACM, Vol 35, Issue 7 (July 1992) pp 56-63. * * Communications of the ACM, Vol 35, Issue 7 (July 1992) pp 56-63. *
* http://portal.acm.org/citation.cfm?id=129906 * * http://portal.acm.org/citation.cfm?id=129906 *
* * * *
* Computer graphics and geometric modeling: implementation and algorithms * * Computer graphics and geometric modeling: implementation and algorithms *
* By Max K. Agoston * * By Max K. Agoston *
* Springer; 1 edition (January 4, 2005) * * Springer; 1 edition (January 4, 2005) *
* http://books.google.com/books?q=vatti+clipping+agoston * * http://books.google.com/books?q=vatti+clipping+agoston *
* * * *
* See also: * * See also: *
* "Polygon Offsetting by Computing Winding Numbers" * * "Polygon Offsetting by Computing Winding Numbers" *
* Paper no. DETC2005-85513 pp. 565-575 * * Paper no. DETC2005-85513 pp. 565-575 *
* ASME 2005 International Design Engineering Technical Conferences * * ASME 2005 International Design Engineering Technical Conferences *
* and Computers and Information in Engineering Conference (IDETC/CIE2005) * * and Computers and Information in Engineering Conference (IDETC/CIE2005) *
* September 24-28, 2005 , Long Beach, California, USA * * September 24-28, 2005 , Long Beach, California, USA *
* http://www.me.berkeley.edu/~mcmains/pubs/DAC05OffsetPolygon.pdf * * http://www.me.berkeley.edu/~mcmains/pubs/DAC05OffsetPolygon.pdf *
* * * *
*******************************************************************************/ *******************************************************************************/
#pragma once #pragma once
...@@ -40,16 +40,16 @@ ...@@ -40,16 +40,16 @@
// use_int32: When enabled 32bit ints are used instead of 64bit ints. This // use_int32: When enabled 32bit ints are used instead of 64bit ints. This
// improve performance but coordinate values are limited to the range +/- 46340 // improve performance but coordinate values are limited to the range +/- 46340
//#define use_int32 // #define use_int32
// use_xyz: adds a Z member to IntPoint. Adds a minor cost to perfomance. // use_xyz: adds a Z member to IntPoint. Adds a minor cost to perfomance.
//#define use_xyz // #define use_xyz
// use_lines: Enables line clipping. Adds a very minor cost to performance. // use_lines: Enables line clipping. Adds a very minor cost to performance.
#define use_lines #define use_lines
// use_deprecated: Enables temporary support for the obsolete functions // use_deprecated: Enables temporary support for the obsolete functions
//#define use_deprecated // #define use_deprecated
#include <cstdlib> #include <cstdlib>
#include <cstring> #include <cstring>
...@@ -61,15 +61,32 @@ ...@@ -61,15 +61,32 @@
#include <stdexcept> #include <stdexcept>
#include <vector> #include <vector>
namespace ClipperLib { namespace ClipperLib
{
enum ClipType { ctIntersection, ctUnion, ctDifference, ctXor }; enum ClipType
enum PolyType { ptSubject, ptClip }; {
ctIntersection,
ctUnion,
ctDifference,
ctXor
};
enum PolyType
{
ptSubject,
ptClip
};
// By far the most widely used winding rules for polygon filling are // By far the most widely used winding rules for polygon filling are
// EvenOdd & NonZero (GDI, GDI+, XLib, OpenGL, Cairo, AGG, Quartz, SVG, Gr32) // EvenOdd & NonZero (GDI, GDI+, XLib, OpenGL, Cairo, AGG, Quartz, SVG, Gr32)
// Others rules include Positive, Negative and ABS_GTR_EQ_TWO (only in OpenGL) // Others rules include Positive, Negative and ABS_GTR_EQ_TWO (only in OpenGL)
// see http://glprogramming.com/red/chapter11.html // see http://glprogramming.com/red/chapter11.html
enum PolyFillType { pftEvenOdd, pftNonZero, pftPositive, pftNegative }; enum PolyFillType
{
pftEvenOdd,
pftNonZero,
pftPositive,
pftNegative
};
#ifdef use_int32 #ifdef use_int32
typedef int cInt; typedef int cInt;
...@@ -84,146 +101,161 @@ typedef unsigned long long ulong64; ...@@ -84,146 +101,161 @@ typedef unsigned long long ulong64;
#endif #endif
struct IntPoint { struct IntPoint
cInt X; {
cInt Y; cInt X;
cInt Y;
#ifdef use_xyz #ifdef use_xyz
cInt Z; cInt Z;
IntPoint(cInt x = 0, cInt y = 0, cInt z = 0) : X(x), Y(y), Z(z){}; IntPoint(cInt x = 0, cInt y = 0, cInt z = 0) : X(x), Y(y), Z(z){};
#else #else
IntPoint(cInt x = 0, cInt y = 0) : X(x), Y(y){}; IntPoint(cInt x = 0, cInt y = 0) : X(x), Y(y){};
#endif #endif
friend inline bool operator==(const IntPoint &a, const IntPoint &b) { friend inline bool operator==(const IntPoint& a, const IntPoint& b)
return a.X == b.X && a.Y == b.Y; {
} return a.X == b.X && a.Y == b.Y;
friend inline bool operator!=(const IntPoint &a, const IntPoint &b) { }
return a.X != b.X || a.Y != b.Y; friend inline bool operator!=(const IntPoint& a, const IntPoint& b)
} {
return a.X != b.X || a.Y != b.Y;
}
}; };
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
typedef std::vector<IntPoint> Path; typedef std::vector<IntPoint> Path;
typedef std::vector<Path> Paths; typedef std::vector<Path> Paths;
inline Path &operator<<(Path &poly, const IntPoint &p) { inline Path& operator<<(Path& poly, const IntPoint& p)
poly.push_back(p); {
return poly; poly.push_back(p);
return poly;
} }
inline Paths &operator<<(Paths &polys, const Path &p) { inline Paths& operator<<(Paths& polys, const Path& p)
polys.push_back(p); {
return polys; polys.push_back(p);
return polys;
} }
std::ostream &operator<<(std::ostream &s, const IntPoint &p); std::ostream& operator<<(std::ostream& s, const IntPoint& p);
std::ostream &operator<<(std::ostream &s, const Path &p); std::ostream& operator<<(std::ostream& s, const Path& p);
std::ostream &operator<<(std::ostream &s, const Paths &p); std::ostream& operator<<(std::ostream& s, const Paths& p);
struct DoublePoint { struct DoublePoint
double X; {
double Y; double X;
DoublePoint(double x = 0, double y = 0) : X(x), Y(y) {} double Y;
DoublePoint(IntPoint ip) : X((double)ip.X), Y((double)ip.Y) {} DoublePoint(double x = 0, double y = 0) : X(x), Y(y) {}
DoublePoint(IntPoint ip) : X((double)ip.X), Y((double)ip.Y) {}
}; };
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
#ifdef use_xyz #ifdef use_xyz
typedef void (*ZFillCallback)(IntPoint &e1bot, IntPoint &e1top, IntPoint &e2bot, typedef void (*ZFillCallback)(
IntPoint &e2top, IntPoint &pt); IntPoint& e1bot, IntPoint& e1top, IntPoint& e2bot, IntPoint& e2top, IntPoint& pt);
#endif #endif
enum InitOptions { enum InitOptions
ioReverseSolution = 1, {
ioStrictlySimple = 2, ioReverseSolution = 1,
ioPreserveCollinear = 4 ioStrictlySimple = 2,
ioPreserveCollinear = 4
}; };
enum JoinType { jtSquare, jtRound, jtMiter }; enum JoinType
enum EndType { {
etClosedPolygon, jtSquare,
etClosedLine, jtRound,
etOpenButt, jtMiter
etOpenSquare, };
etOpenRound enum EndType
{
etClosedPolygon,
etClosedLine,
etOpenButt,
etOpenSquare,
etOpenRound
}; };
class PolyNode; class PolyNode;
typedef std::vector<PolyNode *> PolyNodes; typedef std::vector<PolyNode*> PolyNodes;
class PolyNode { class PolyNode
public: {
PolyNode(); public:
virtual ~PolyNode(){}; PolyNode();
Path Contour; virtual ~PolyNode(){};
PolyNodes Childs; Path Contour;
PolyNode *Parent; PolyNodes Childs;
PolyNode *GetNext() const; PolyNode* Parent;
bool IsHole() const; PolyNode* GetNext() const;
bool IsOpen() const; bool IsHole() const;
int ChildCount() const; bool IsOpen() const;
int ChildCount() const;
private:
// PolyNode& operator =(PolyNode& other); private:
unsigned Index; // node index in Parent.Childs // PolyNode& operator =(PolyNode& other);
bool m_IsOpen; unsigned Index; // node index in Parent.Childs
JoinType m_jointype; bool m_IsOpen;
EndType m_endtype; JoinType m_jointype;
PolyNode *GetNextSiblingUp() const; EndType m_endtype;
void AddChild(PolyNode &child); PolyNode* GetNextSiblingUp() const;
friend class Clipper; // to access Index void AddChild(PolyNode& child);
friend class ClipperOffset; friend class Clipper; // to access Index
friend class ClipperOffset;
}; };
class PolyTree : public PolyNode { class PolyTree : public PolyNode
public: {
~PolyTree() { Clear(); }; public:
PolyNode *GetFirst() const; ~PolyTree() { Clear(); };
void Clear(); PolyNode* GetFirst() const;
int Total() const; void Clear();
int Total() const;
private:
// PolyTree& operator =(PolyTree& other); private:
PolyNodes AllNodes; // PolyTree& operator =(PolyTree& other);
friend class Clipper; // to access AllNodes PolyNodes AllNodes;
friend class Clipper; // to access AllNodes
}; };
bool Orientation(const Path &poly); bool Orientation(const Path& poly);
double Area(const Path &poly); double Area(const Path& poly);
int PointInPolygon(const IntPoint &pt, const Path &path); int PointInPolygon(const IntPoint& pt, const Path& path);
void SimplifyPolygon(const Path &in_poly, Paths &out_polys, void SimplifyPolygon(const Path& in_poly, Paths& out_polys, PolyFillType fillType = pftEvenOdd);
PolyFillType fillType = pftEvenOdd); void SimplifyPolygons(const Paths& in_polys, Paths& out_polys, PolyFillType fillType = pftEvenOdd);
void SimplifyPolygons(const Paths &in_polys, Paths &out_polys, void SimplifyPolygons(Paths& polys, PolyFillType fillType = pftEvenOdd);
PolyFillType fillType = pftEvenOdd);
void SimplifyPolygons(Paths &polys, PolyFillType fillType = pftEvenOdd); void CleanPolygon(const Path& in_poly, Path& out_poly, double distance = 1.415);
void CleanPolygon(Path& poly, double distance = 1.415);
void CleanPolygon(const Path &in_poly, Path &out_poly, double distance = 1.415); void CleanPolygons(const Paths& in_polys, Paths& out_polys, double distance = 1.415);
void CleanPolygon(Path &poly, double distance = 1.415); void CleanPolygons(Paths& polys, double distance = 1.415);
void CleanPolygons(const Paths &in_polys, Paths &out_polys,
double distance = 1.415); void MinkowskiSum(const Path& pattern, const Path& path, Paths& solution, bool pathIsClosed);
void CleanPolygons(Paths &polys, double distance = 1.415); void MinkowskiSum(const Path& pattern, const Paths& paths, Paths& solution, bool pathIsClosed);
void MinkowskiDiff(const Path& poly1, const Path& poly2, Paths& solution);
void MinkowskiSum(const Path &pattern, const Path &path, Paths &solution,
bool pathIsClosed); void PolyTreeToPaths(const PolyTree& polytree, Paths& paths);
void MinkowskiSum(const Path &pattern, const Paths &paths, Paths &solution, void ClosedPathsFromPolyTree(const PolyTree& polytree, Paths& paths);
bool pathIsClosed); void OpenPathsFromPolyTree(PolyTree& polytree, Paths& paths);
void MinkowskiDiff(const Path &poly1, const Path &poly2, Paths &solution);
void ReversePath(Path& p);
void PolyTreeToPaths(const PolyTree &polytree, Paths &paths); void ReversePaths(Paths& p);
void ClosedPathsFromPolyTree(const PolyTree &polytree, Paths &paths);
void OpenPathsFromPolyTree(PolyTree &polytree, Paths &paths); struct IntRect
{
void ReversePath(Path &p); cInt left;
void ReversePaths(Paths &p); cInt top;
cInt right;
struct IntRect { cInt bottom;
cInt left;
cInt top;
cInt right;
cInt bottom;
}; };
// enums that are used internally ... // enums that are used internally ...
enum EdgeSide { esLeft = 1, esRight = 2 }; enum EdgeSide
{
esLeft = 1,
esRight = 2
};
// forward declarations (for stuff used internally) ... // forward declarations (for stuff used internally) ...
struct TEdge; struct TEdge;
...@@ -233,193 +265,199 @@ struct OutPt; ...@@ -233,193 +265,199 @@ struct OutPt;
struct OutRec; struct OutRec;
struct Join; struct Join;
typedef std::vector<OutRec *> PolyOutList; typedef std::vector<OutRec*> PolyOutList;
typedef std::vector<TEdge *> EdgeList; typedef std::vector<TEdge*> EdgeList;
typedef std::vector<Join *> JoinList; typedef std::vector<Join*> JoinList;
typedef std::vector<IntersectNode *> IntersectList; typedef std::vector<IntersectNode*> IntersectList;
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// ClipperBase is the ancestor to the Clipper class. It should not be // ClipperBase is the ancestor to the Clipper class. It should not be
// instantiated directly. This class simply abstracts the conversion of sets of // instantiated directly. This class simply abstracts the conversion of sets of
// polygon coordinates into edge objects that are stored in a LocalMinima list. // polygon coordinates into edge objects that are stored in a LocalMinima list.
class ClipperBase { class ClipperBase
public: {
ClipperBase(); public:
virtual ~ClipperBase(); ClipperBase();
virtual bool AddPath(const Path &pg, PolyType PolyTyp, bool Closed); virtual ~ClipperBase();
bool AddPaths(const Paths &ppg, PolyType PolyTyp, bool Closed); virtual bool AddPath(const Path& pg, PolyType PolyTyp, bool Closed);
virtual void Clear(); bool AddPaths(const Paths& ppg, PolyType PolyTyp, bool Closed);
IntRect GetBounds(); virtual void Clear();
bool PreserveCollinear() { return m_PreserveCollinear; }; IntRect GetBounds();
void PreserveCollinear(bool value) { m_PreserveCollinear = value; }; bool PreserveCollinear() { return m_PreserveCollinear; };
void PreserveCollinear(bool value) { m_PreserveCollinear = value; };
protected:
void DisposeLocalMinimaList(); protected:
TEdge *AddBoundsToLML(TEdge *e, bool IsClosed); void DisposeLocalMinimaList();
virtual void Reset(); TEdge* AddBoundsToLML(TEdge* e, bool IsClosed);
TEdge *ProcessBound(TEdge *E, bool IsClockwise); virtual void Reset();
void InsertScanbeam(const cInt Y); TEdge* ProcessBound(TEdge* E, bool IsClockwise);
bool PopScanbeam(cInt &Y); void InsertScanbeam(const cInt Y);
bool LocalMinimaPending(); bool PopScanbeam(cInt& Y);
bool PopLocalMinima(cInt Y, const LocalMinimum *&locMin); bool LocalMinimaPending();
OutRec *CreateOutRec(); bool PopLocalMinima(cInt Y, const LocalMinimum*& locMin);
void DisposeAllOutRecs(); OutRec* CreateOutRec();
void DisposeOutRec(PolyOutList::size_type index); void DisposeAllOutRecs();
void SwapPositionsInAEL(TEdge *edge1, TEdge *edge2); void DisposeOutRec(PolyOutList::size_type index);
void DeleteFromAEL(TEdge *e); void SwapPositionsInAEL(TEdge* edge1, TEdge* edge2);
void UpdateEdgeIntoAEL(TEdge *&e); void DeleteFromAEL(TEdge* e);
void UpdateEdgeIntoAEL(TEdge*& e);
typedef std::vector<LocalMinimum> MinimaList;
MinimaList::iterator m_CurrentLM; typedef std::vector<LocalMinimum> MinimaList;
MinimaList m_MinimaList; MinimaList::iterator m_CurrentLM;
MinimaList m_MinimaList;
bool m_UseFullRange;
EdgeList m_edges; bool m_UseFullRange;
bool m_PreserveCollinear; EdgeList m_edges;
bool m_HasOpenPaths; bool m_PreserveCollinear;
PolyOutList m_PolyOuts; bool m_HasOpenPaths;
TEdge *m_ActiveEdges; PolyOutList m_PolyOuts;
TEdge* m_ActiveEdges;
typedef std::priority_queue<cInt> ScanbeamList;
ScanbeamList m_Scanbeam; typedef std::priority_queue<cInt> ScanbeamList;
ScanbeamList m_Scanbeam;
}; };
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
class Clipper : public virtual ClipperBase { class Clipper : public virtual ClipperBase
public: {
Clipper(int initOptions = 0); public:
bool Execute(ClipType clipType, Paths &solution, Clipper(int initOptions = 0);
PolyFillType fillType = pftEvenOdd); bool Execute(ClipType clipType, Paths& solution, PolyFillType fillType = pftEvenOdd);
bool Execute(ClipType clipType, Paths &solution, PolyFillType subjFillType, bool Execute(ClipType clipType,
PolyFillType clipFillType); Paths& solution,
bool Execute(ClipType clipType, PolyTree &polytree, PolyFillType subjFillType,
PolyFillType fillType = pftEvenOdd); PolyFillType clipFillType);
bool Execute(ClipType clipType, PolyTree &polytree, PolyFillType subjFillType, bool Execute(ClipType clipType, PolyTree& polytree, PolyFillType fillType = pftEvenOdd);
PolyFillType clipFillType); bool Execute(ClipType clipType,
bool ReverseSolution() { return m_ReverseOutput; }; PolyTree& polytree,
void ReverseSolution(bool value) { m_ReverseOutput = value; }; PolyFillType subjFillType,
bool StrictlySimple() { return m_StrictSimple; }; PolyFillType clipFillType);
void StrictlySimple(bool value) { m_StrictSimple = value; }; bool ReverseSolution() { return m_ReverseOutput; };
void ReverseSolution(bool value) { m_ReverseOutput = value; };
bool StrictlySimple() { return m_StrictSimple; };
void StrictlySimple(bool value) { m_StrictSimple = value; };
// set the callback function for z value filling on intersections (otherwise Z // set the callback function for z value filling on intersections (otherwise Z
// is 0) // is 0)
#ifdef use_xyz #ifdef use_xyz
void ZFillFunction(ZFillCallback zFillFunc); void ZFillFunction(ZFillCallback zFillFunc);
#endif #endif
protected: protected:
virtual bool ExecuteInternal(); virtual bool ExecuteInternal();
private: private:
JoinList m_Joins; JoinList m_Joins;
JoinList m_GhostJoins; JoinList m_GhostJoins;
IntersectList m_IntersectList; IntersectList m_IntersectList;
ClipType m_ClipType; ClipType m_ClipType;
typedef std::list<cInt> MaximaList; typedef std::list<cInt> MaximaList;
MaximaList m_Maxima; MaximaList m_Maxima;
TEdge *m_SortedEdges; TEdge* m_SortedEdges;
bool m_ExecuteLocked; bool m_ExecuteLocked;
PolyFillType m_ClipFillType; PolyFillType m_ClipFillType;
PolyFillType m_SubjFillType; PolyFillType m_SubjFillType;
bool m_ReverseOutput; bool m_ReverseOutput;
bool m_UsingPolyTree; bool m_UsingPolyTree;
bool m_StrictSimple; bool m_StrictSimple;
#ifdef use_xyz #ifdef use_xyz
ZFillCallback m_ZFill; // custom callback ZFillCallback m_ZFill; // custom callback
#endif #endif
void SetWindingCount(TEdge &edge); void SetWindingCount(TEdge& edge);
bool IsEvenOddFillType(const TEdge &edge) const; bool IsEvenOddFillType(const TEdge& edge) const;
bool IsEvenOddAltFillType(const TEdge &edge) const; bool IsEvenOddAltFillType(const TEdge& edge) const;
void InsertLocalMinimaIntoAEL(const cInt botY); void InsertLocalMinimaIntoAEL(const cInt botY);
void InsertEdgeIntoAEL(TEdge *edge, TEdge *startEdge); void InsertEdgeIntoAEL(TEdge* edge, TEdge* startEdge);
void AddEdgeToSEL(TEdge *edge); void AddEdgeToSEL(TEdge* edge);
bool PopEdgeFromSEL(TEdge *&edge); bool PopEdgeFromSEL(TEdge*& edge);
void CopyAELToSEL(); void CopyAELToSEL();
void DeleteFromSEL(TEdge *e); void DeleteFromSEL(TEdge* e);
void SwapPositionsInSEL(TEdge *edge1, TEdge *edge2); void SwapPositionsInSEL(TEdge* edge1, TEdge* edge2);
bool IsContributing(const TEdge &edge) const; bool IsContributing(const TEdge& edge) const;
bool IsTopHorz(const cInt XPos); bool IsTopHorz(const cInt XPos);
void DoMaxima(TEdge *e); void DoMaxima(TEdge* e);
void ProcessHorizontals(); void ProcessHorizontals();
void ProcessHorizontal(TEdge *horzEdge); void ProcessHorizontal(TEdge* horzEdge);
void AddLocalMaxPoly(TEdge *e1, TEdge *e2, const IntPoint &pt); void AddLocalMaxPoly(TEdge* e1, TEdge* e2, const IntPoint& pt);
OutPt *AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &pt); OutPt* AddLocalMinPoly(TEdge* e1, TEdge* e2, const IntPoint& pt);
OutRec *GetOutRec(int idx); OutRec* GetOutRec(int idx);
void AppendPolygon(TEdge *e1, TEdge *e2); void AppendPolygon(TEdge* e1, TEdge* e2);
void IntersectEdges(TEdge *e1, TEdge *e2, IntPoint &pt); void IntersectEdges(TEdge* e1, TEdge* e2, IntPoint& pt);
OutPt *AddOutPt(TEdge *e, const IntPoint &pt); OutPt* AddOutPt(TEdge* e, const IntPoint& pt);
OutPt *GetLastOutPt(TEdge *e); OutPt* GetLastOutPt(TEdge* e);
bool ProcessIntersections(const cInt topY); bool ProcessIntersections(const cInt topY);
void BuildIntersectList(const cInt topY); void BuildIntersectList(const cInt topY);
void ProcessIntersectList(); void ProcessIntersectList();
void ProcessEdgesAtTopOfScanbeam(const cInt topY); void ProcessEdgesAtTopOfScanbeam(const cInt topY);
void BuildResult(Paths &polys); void BuildResult(Paths& polys);
void BuildResult2(PolyTree &polytree); void BuildResult2(PolyTree& polytree);
void SetHoleState(TEdge *e, OutRec *outrec); void SetHoleState(TEdge* e, OutRec* outrec);
void DisposeIntersectNodes(); void DisposeIntersectNodes();
bool FixupIntersectionOrder(); bool FixupIntersectionOrder();
void FixupOutPolygon(OutRec &outrec); void FixupOutPolygon(OutRec& outrec);
void FixupOutPolyline(OutRec &outrec); void FixupOutPolyline(OutRec& outrec);
bool IsHole(TEdge *e); bool IsHole(TEdge* e);
bool FindOwnerFromSplitRecs(OutRec &outRec, OutRec *&currOrfl); bool FindOwnerFromSplitRecs(OutRec& outRec, OutRec*& currOrfl);
void FixHoleLinkage(OutRec &outrec); void FixHoleLinkage(OutRec& outrec);
void AddJoin(OutPt *op1, OutPt *op2, const IntPoint offPt); void AddJoin(OutPt* op1, OutPt* op2, const IntPoint offPt);
void ClearJoins(); void ClearJoins();
void ClearGhostJoins(); void ClearGhostJoins();
void AddGhostJoin(OutPt *op, const IntPoint offPt); void AddGhostJoin(OutPt* op, const IntPoint offPt);
bool JoinPoints(Join *j, OutRec *outRec1, OutRec *outRec2); bool JoinPoints(Join* j, OutRec* outRec1, OutRec* outRec2);
void JoinCommonEdges(); void JoinCommonEdges();
void DoSimplePolygons(); void DoSimplePolygons();
void FixupFirstLefts1(OutRec *OldOutRec, OutRec *NewOutRec); void FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec);
void FixupFirstLefts2(OutRec *InnerOutRec, OutRec *OuterOutRec); void FixupFirstLefts2(OutRec* InnerOutRec, OutRec* OuterOutRec);
void FixupFirstLefts3(OutRec *OldOutRec, OutRec *NewOutRec); void FixupFirstLefts3(OutRec* OldOutRec, OutRec* NewOutRec);
#ifdef use_xyz #ifdef use_xyz
void SetZ(IntPoint &pt, TEdge &e1, TEdge &e2); void SetZ(IntPoint& pt, TEdge& e1, TEdge& e2);
#endif #endif
}; };
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
class ClipperOffset { class ClipperOffset
public: {
ClipperOffset(double miterLimit = 2.0, double roundPrecision = 0.25); public:
~ClipperOffset(); ClipperOffset(double miterLimit = 2.0, double roundPrecision = 0.25);
void AddPath(const Path &path, JoinType joinType, EndType endType); ~ClipperOffset();
void AddPaths(const Paths &paths, JoinType joinType, EndType endType); void AddPath(const Path& path, JoinType joinType, EndType endType);
void Execute(Paths &solution, double delta); void AddPaths(const Paths& paths, JoinType joinType, EndType endType);
void Execute(PolyTree &solution, double delta); void Execute(Paths& solution, double delta);
void Clear(); void Execute(PolyTree& solution, double delta);
double MiterLimit; void Clear();
double ArcTolerance; double MiterLimit;
double ArcTolerance;
private:
Paths m_destPolys; private:
Path m_srcPoly; Paths m_destPolys;
Path m_destPoly; Path m_srcPoly;
std::vector<DoublePoint> m_normals; Path m_destPoly;
double m_delta, m_sinA, m_sin, m_cos; std::vector<DoublePoint> m_normals;
double m_miterLim, m_StepsPerRad; double m_delta, m_sinA, m_sin, m_cos;
IntPoint m_lowest; double m_miterLim, m_StepsPerRad;
PolyNode m_polyNodes; IntPoint m_lowest;
PolyNode m_polyNodes;
void FixOrientations();
void DoOffset(double delta); void FixOrientations();
void OffsetPoint(int j, int &k, JoinType jointype); void DoOffset(double delta);
void DoSquare(int j, int k); void OffsetPoint(int j, int& k, JoinType jointype);
void DoMiter(int j, int k, double r); void DoSquare(int j, int k);
void DoRound(int j, int k); void DoMiter(int j, int k, double r);
void DoRound(int j, int k);
}; };
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
class clipperException : public std::exception { class clipperException : public std::exception
public: {
clipperException(const char *description) : m_descr(description) {} public:
virtual ~clipperException() throw() {} clipperException(const char* description) : m_descr(description) {}
virtual const char *what() const throw() { return m_descr.c_str(); } virtual ~clipperException() throw() {}
virtual const char* what() const throw() { return m_descr.c_str(); }
private: private:
std::string m_descr; std::string m_descr;
}; };
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
} // ClipperLib namespace } // namespace ClipperLib
#endif // clipper_hpp #endif // clipper_hpp
...@@ -25,401 +25,451 @@ ...@@ -25,401 +25,451 @@
#include <sys/stat.h> #include <sys/stat.h>
#endif #endif
namespace migraphxSamples { namespace migraphxSamples
{
std::vector<std::string> Utility::ReadDict(const std::string &path) {
std::ifstream in(path); std::vector<std::string> Utility::ReadDict(const std::string& path)
std::string line; {
std::vector<std::string> m_vec; std::ifstream in(path);
if (in) { std::string line;
while (getline(in, line)) { std::vector<std::string> m_vec;
m_vec.push_back(line); if(in)
{
while(getline(in, line))
{
m_vec.push_back(line);
}
}
else
{
std::cout << "no such label file: " << path << ", exit the program..." << std::endl;
exit(1);
} }
} else { return m_vec;
std::cout << "no such label file: " << path << ", exit the program..."
<< std::endl;
exit(1);
}
return m_vec;
} }
void Utility::VisualizeBboxes(const cv::Mat &srcimg, void Utility::VisualizeBboxes(const cv::Mat& srcimg,
const std::vector<OCRPredictResult> &ocr_result, const std::vector<OCRPredictResult>& ocr_result,
const std::string &save_path) { const std::string& save_path)
cv::Mat img_vis; {
srcimg.copyTo(img_vis); cv::Mat img_vis;
for (int n = 0; n < ocr_result.size(); n++) { srcimg.copyTo(img_vis);
cv::Point rook_points[4]; for(int n = 0; n < ocr_result.size(); n++)
for (int m = 0; m < ocr_result[n].box.size(); m++) { {
rook_points[m] = cv::Point rook_points[4];
cv::Point(int(ocr_result[n].box[m][0]), int(ocr_result[n].box[m][1])); for(int m = 0; m < ocr_result[n].box.size(); m++)
} {
rook_points[m] = cv::Point(int(ocr_result[n].box[m][0]), int(ocr_result[n].box[m][1]));
}
const cv::Point *ppt[1] = {rook_points}; const cv::Point* ppt[1] = {rook_points};
int npt[] = {4}; int npt[] = {4};
cv::polylines(img_vis, ppt, npt, 1, 1, CV_RGB(0, 255, 0), 2, 8, 0); cv::polylines(img_vis, ppt, npt, 1, 1, CV_RGB(0, 255, 0), 2, 8, 0);
} }
cv::imwrite(save_path, img_vis); cv::imwrite(save_path, img_vis);
std::cout << "The detection visualized image saved in " + save_path std::cout << "The detection visualized image saved in " + save_path << std::endl;
<< std::endl;
} }
void Utility::VisualizeBboxes(const cv::Mat &srcimg, void Utility::VisualizeBboxes(const cv::Mat& srcimg,
const StructurePredictResult &structure_result, const StructurePredictResult& structure_result,
const std::string &save_path) { const std::string& save_path)
cv::Mat img_vis; {
srcimg.copyTo(img_vis); cv::Mat img_vis;
img_vis = crop_image(img_vis, structure_result.box); srcimg.copyTo(img_vis);
for (int n = 0; n < structure_result.cell_box.size(); n++) { img_vis = crop_image(img_vis, structure_result.box);
if (structure_result.cell_box[n].size() == 8) { for(int n = 0; n < structure_result.cell_box.size(); n++)
cv::Point rook_points[4]; {
for (int m = 0; m < structure_result.cell_box[n].size(); m += 2) { if(structure_result.cell_box[n].size() == 8)
rook_points[m / 2] = {
cv::Point(int(structure_result.cell_box[n][m]), cv::Point rook_points[4];
int(structure_result.cell_box[n][m + 1])); for(int m = 0; m < structure_result.cell_box[n].size(); m += 2)
} {
const cv::Point *ppt[1] = {rook_points}; rook_points[m / 2] = cv::Point(int(structure_result.cell_box[n][m]),
int npt[] = {4}; int(structure_result.cell_box[n][m + 1]));
cv::polylines(img_vis, ppt, npt, 1, 1, CV_RGB(0, 255, 0), 2, 8, 0); }
} else if (structure_result.cell_box[n].size() == 4) { const cv::Point* ppt[1] = {rook_points};
cv::Point rook_points[2]; int npt[] = {4};
rook_points[0] = cv::Point(int(structure_result.cell_box[n][0]), cv::polylines(img_vis, ppt, npt, 1, 1, CV_RGB(0, 255, 0), 2, 8, 0);
int(structure_result.cell_box[n][1])); }
rook_points[1] = cv::Point(int(structure_result.cell_box[n][2]), else if(structure_result.cell_box[n].size() == 4)
int(structure_result.cell_box[n][3])); {
cv::rectangle(img_vis, rook_points[0], rook_points[1], CV_RGB(0, 255, 0), cv::Point rook_points[2];
2, 8, 0); rook_points[0] = cv::Point(int(structure_result.cell_box[n][0]),
int(structure_result.cell_box[n][1]));
rook_points[1] = cv::Point(int(structure_result.cell_box[n][2]),
int(structure_result.cell_box[n][3]));
cv::rectangle(img_vis, rook_points[0], rook_points[1], CV_RGB(0, 255, 0), 2, 8, 0);
}
} }
}
cv::imwrite(save_path, img_vis); cv::imwrite(save_path, img_vis);
std::cout << "The table visualized image saved in " + save_path << std::endl; std::cout << "The table visualized image saved in " + save_path << std::endl;
} }
// list all files under a directory // list all files under a directory
void Utility::GetAllFiles(const char *dir_name, void Utility::GetAllFiles(const char* dir_name, std::vector<std::string>& all_inputs)
std::vector<std::string> &all_inputs) { {
if (NULL == dir_name) { if(NULL == dir_name)
std::cout << " dir_name is null ! " << std::endl; {
return; std::cout << " dir_name is null ! " << std::endl;
} return;
struct stat s; }
stat(dir_name, &s); struct stat s;
if (!S_ISDIR(s.st_mode)) { stat(dir_name, &s);
std::cout << "dir_name is not a valid directory !" << std::endl; if(!S_ISDIR(s.st_mode))
all_inputs.push_back(dir_name); {
return; std::cout << "dir_name is not a valid directory !" << std::endl;
} else { all_inputs.push_back(dir_name);
struct dirent *filename; // return value for readdir() return;
DIR *dir; // return value for opendir()
dir = opendir(dir_name);
if (NULL == dir) {
std::cout << "Can not open dir " << dir_name << std::endl;
return;
} }
std::cout << "Successfully opened the dir !" << std::endl; else
while ((filename = readdir(dir)) != NULL) { {
if (strcmp(filename->d_name, ".") == 0 || struct dirent* filename; // return value for readdir()
strcmp(filename->d_name, "..") == 0) DIR* dir; // return value for opendir()
continue; dir = opendir(dir_name);
// img_dir + std::string("/") + all_inputs[0]; if(NULL == dir)
all_inputs.push_back(dir_name + std::string("/") + {
std::string(filename->d_name)); std::cout << "Can not open dir " << dir_name << std::endl;
return;
}
std::cout << "Successfully opened the dir !" << std::endl;
while((filename = readdir(dir)) != NULL)
{
if(strcmp(filename->d_name, ".") == 0 || strcmp(filename->d_name, "..") == 0)
continue;
// img_dir + std::string("/") + all_inputs[0];
all_inputs.push_back(dir_name + std::string("/") + std::string(filename->d_name));
}
} }
}
} }
cv::Mat Utility::GetRotateCropImage(const cv::Mat &srcimage, cv::Mat Utility::GetRotateCropImage(const cv::Mat& srcimage, std::vector<std::vector<int>> box)
std::vector<std::vector<int>> box) { {
cv::Mat image; cv::Mat image;
srcimage.copyTo(image); srcimage.copyTo(image);
std::vector<std::vector<int>> points = box; std::vector<std::vector<int>> points = box;
int x_collect[4] = {box[0][0], box[1][0], box[2][0], box[3][0]}; int x_collect[4] = {box[0][0], box[1][0], box[2][0], box[3][0]};
int y_collect[4] = {box[0][1], box[1][1], box[2][1], box[3][1]}; int y_collect[4] = {box[0][1], box[1][1], box[2][1], box[3][1]};
int left = int(*std::min_element(x_collect, x_collect + 4)); int left = int(*std::min_element(x_collect, x_collect + 4));
int right = int(*std::max_element(x_collect, x_collect + 4)); int right = int(*std::max_element(x_collect, x_collect + 4));
int top = int(*std::min_element(y_collect, y_collect + 4)); int top = int(*std::min_element(y_collect, y_collect + 4));
int bottom = int(*std::max_element(y_collect, y_collect + 4)); int bottom = int(*std::max_element(y_collect, y_collect + 4));
cv::Mat img_crop; cv::Mat img_crop;
image(cv::Rect(left, top, right - left, bottom - top)).copyTo(img_crop); image(cv::Rect(left, top, right - left, bottom - top)).copyTo(img_crop);
for (int i = 0; i < points.size(); i++) { for(int i = 0; i < points.size(); i++)
points[i][0] -= left; {
points[i][1] -= top; points[i][0] -= left;
} points[i][1] -= top;
}
int img_crop_width = int(sqrt(pow(points[0][0] - points[1][0], 2) +
pow(points[0][1] - points[1][1], 2))); int img_crop_width =
int img_crop_height = int(sqrt(pow(points[0][0] - points[3][0], 2) + int(sqrt(pow(points[0][0] - points[1][0], 2) + pow(points[0][1] - points[1][1], 2)));
pow(points[0][1] - points[3][1], 2))); int img_crop_height =
int(sqrt(pow(points[0][0] - points[3][0], 2) + pow(points[0][1] - points[3][1], 2)));
cv::Point2f pts_std[4];
pts_std[0] = cv::Point2f(0., 0.); cv::Point2f pts_std[4];
pts_std[1] = cv::Point2f(img_crop_width, 0.); pts_std[0] = cv::Point2f(0., 0.);
pts_std[2] = cv::Point2f(img_crop_width, img_crop_height); pts_std[1] = cv::Point2f(img_crop_width, 0.);
pts_std[3] = cv::Point2f(0.f, img_crop_height); pts_std[2] = cv::Point2f(img_crop_width, img_crop_height);
pts_std[3] = cv::Point2f(0.f, img_crop_height);
cv::Point2f pointsf[4];
pointsf[0] = cv::Point2f(points[0][0], points[0][1]); cv::Point2f pointsf[4];
pointsf[1] = cv::Point2f(points[1][0], points[1][1]); pointsf[0] = cv::Point2f(points[0][0], points[0][1]);
pointsf[2] = cv::Point2f(points[2][0], points[2][1]); pointsf[1] = cv::Point2f(points[1][0], points[1][1]);
pointsf[3] = cv::Point2f(points[3][0], points[3][1]); pointsf[2] = cv::Point2f(points[2][0], points[2][1]);
pointsf[3] = cv::Point2f(points[3][0], points[3][1]);
cv::Mat M = cv::getPerspectiveTransform(pointsf, pts_std);
cv::Mat M = cv::getPerspectiveTransform(pointsf, pts_std);
cv::Mat dst_img;
cv::warpPerspective(img_crop, dst_img, M, cv::Mat dst_img;
cv::Size(img_crop_width, img_crop_height), cv::warpPerspective(
cv::BORDER_REPLICATE); img_crop, dst_img, M, cv::Size(img_crop_width, img_crop_height), cv::BORDER_REPLICATE);
if (float(dst_img.rows) >= float(dst_img.cols) * 1.5) { if(float(dst_img.rows) >= float(dst_img.cols) * 1.5)
cv::Mat srcCopy = cv::Mat(dst_img.rows, dst_img.cols, dst_img.depth()); {
cv::transpose(dst_img, srcCopy); cv::Mat srcCopy = cv::Mat(dst_img.rows, dst_img.cols, dst_img.depth());
cv::flip(srcCopy, srcCopy, 0); cv::transpose(dst_img, srcCopy);
return srcCopy; cv::flip(srcCopy, srcCopy, 0);
} else { return srcCopy;
return dst_img; }
} else
{
return dst_img;
}
} }
std::vector<int> Utility::argsort(const std::vector<float> &array) { std::vector<int> Utility::argsort(const std::vector<float>& array)
const int array_len(array.size()); {
std::vector<int> array_index(array_len, 0); const int array_len(array.size());
for (int i = 0; i < array_len; ++i) std::vector<int> array_index(array_len, 0);
array_index[i] = i; for(int i = 0; i < array_len; ++i)
array_index[i] = i;
std::sort( std::sort(array_index.begin(), array_index.end(), [&array](int pos1, int pos2) {
array_index.begin(), array_index.end(), return (array[pos1] < array[pos2]);
[&array](int pos1, int pos2) { return (array[pos1] < array[pos2]); }); });
return array_index; return array_index;
} }
std::string Utility::basename(const std::string &filename) { std::string Utility::basename(const std::string& filename)
if (filename.empty()) { {
return ""; if(filename.empty())
} {
return "";
}
auto len = filename.length(); auto len = filename.length();
auto index = filename.find_last_of("/\\"); auto index = filename.find_last_of("/\\");
if (index == std::string::npos) { if(index == std::string::npos)
return filename; {
} return filename;
}
if (index + 1 >= len) { if(index + 1 >= len)
{
len--; len--;
index = filename.substr(0, len).find_last_of("/\\"); index = filename.substr(0, len).find_last_of("/\\");
if (len == 0) { if(len == 0)
return filename; {
} return filename;
}
if (index == 0) { if(index == 0)
return filename.substr(1, len - 1); {
} return filename.substr(1, len - 1);
}
if (index == std::string::npos) { if(index == std::string::npos)
return filename.substr(0, len); {
} return filename.substr(0, len);
}
return filename.substr(index + 1, len - index - 1); return filename.substr(index + 1, len - index - 1);
} }
return filename.substr(index + 1, len - index); return filename.substr(index + 1, len - index);
} }
bool Utility::PathExists(const std::string &path) { bool Utility::PathExists(const std::string& path)
{
#ifdef _WIN32 #ifdef _WIN32
struct _stat buffer; struct _stat buffer;
return (_stat(path.c_str(), &buffer) == 0); return (_stat(path.c_str(), &buffer) == 0);
#else #else
struct stat buffer; struct stat buffer;
return (stat(path.c_str(), &buffer) == 0); return (stat(path.c_str(), &buffer) == 0);
#endif // !_WIN32 #endif // !_WIN32
} }
void Utility::CreateDir(const std::string &path) { void Utility::CreateDir(const std::string& path)
{
#ifdef _WIN32 #ifdef _WIN32
_mkdir(path.c_str()); _mkdir(path.c_str());
#else #else
mkdir(path.c_str(), 0777); mkdir(path.c_str(), 0777);
#endif // !_WIN32 #endif // !_WIN32
} }
void Utility::print_result(const std::vector<OCRPredictResult> &ocr_result) { void Utility::print_result(const std::vector<OCRPredictResult>& ocr_result)
for (int i = 0; i < ocr_result.size(); i++) { {
std::cout << i << "\t"; for(int i = 0; i < ocr_result.size(); i++)
// det {
std::vector<std::vector<int>> boxes = ocr_result[i].box; std::cout << i << "\t";
if (boxes.size() > 0) { // det
std::cout << "det boxes: ["; std::vector<std::vector<int>> boxes = ocr_result[i].box;
for (int n = 0; n < boxes.size(); n++) { if(boxes.size() > 0)
std::cout << '[' << boxes[n][0] << ',' << boxes[n][1] << "]"; {
if (n != boxes.size() - 1) { std::cout << "det boxes: [";
std::cout << ','; for(int n = 0; n < boxes.size(); n++)
{
std::cout << '[' << boxes[n][0] << ',' << boxes[n][1] << "]";
if(n != boxes.size() - 1)
{
std::cout << ',';
}
}
std::cout << "] ";
}
// rec
if(ocr_result[i].score != -1.0)
{
std::cout << "rec text: " << ocr_result[i].text << " rec score: " << ocr_result[i].score
<< " ";
} }
}
std::cout << "] ";
}
// rec
if (ocr_result[i].score != -1.0) {
std::cout << "rec text: " << ocr_result[i].text
<< " rec score: " << ocr_result[i].score << " ";
}
// cls // cls
if (ocr_result[i].cls_label != -1) { if(ocr_result[i].cls_label != -1)
std::cout << "cls label: " << ocr_result[i].cls_label {
<< " cls score: " << ocr_result[i].cls_score; std::cout << "cls label: " << ocr_result[i].cls_label
<< " cls score: " << ocr_result[i].cls_score;
}
std::cout << std::endl;
} }
std::cout << std::endl;
}
} }
cv::Mat Utility::crop_image(cv::Mat &img, const std::vector<int> &box) { cv::Mat Utility::crop_image(cv::Mat& img, const std::vector<int>& box)
cv::Mat crop_im; {
int crop_x1 = std::max(0, box[0]); cv::Mat crop_im;
int crop_y1 = std::max(0, box[1]); int crop_x1 = std::max(0, box[0]);
int crop_x2 = std::min(img.cols - 1, box[2] - 1); int crop_y1 = std::max(0, box[1]);
int crop_y2 = std::min(img.rows - 1, box[3] - 1); int crop_x2 = std::min(img.cols - 1, box[2] - 1);
int crop_y2 = std::min(img.rows - 1, box[3] - 1);
crop_im = cv::Mat::zeros(box[3] - box[1], box[2] - box[0], 16);
cv::Mat crop_im_window = crop_im = cv::Mat::zeros(box[3] - box[1], box[2] - box[0], 16);
crop_im(cv::Range(crop_y1 - box[1], crop_y2 + 1 - box[1]), cv::Mat crop_im_window = crop_im(cv::Range(crop_y1 - box[1], crop_y2 + 1 - box[1]),
cv::Range(crop_x1 - box[0], crop_x2 + 1 - box[0])); cv::Range(crop_x1 - box[0], crop_x2 + 1 - box[0]));
cv::Mat roi_img = cv::Mat roi_img = img(cv::Range(crop_y1, crop_y2 + 1), cv::Range(crop_x1, crop_x2 + 1));
img(cv::Range(crop_y1, crop_y2 + 1), cv::Range(crop_x1, crop_x2 + 1)); crop_im_window += roi_img;
crop_im_window += roi_img; return crop_im;
return crop_im;
} }
cv::Mat Utility::crop_image(cv::Mat &img, const std::vector<float> &box) { cv::Mat Utility::crop_image(cv::Mat& img, const std::vector<float>& box)
std::vector<int> box_int = {(int)box[0], (int)box[1], (int)box[2], {
(int)box[3]}; std::vector<int> box_int = {(int)box[0], (int)box[1], (int)box[2], (int)box[3]};
return crop_image(img, box_int); return crop_image(img, box_int);
} }
void Utility::sorted_boxes(std::vector<OCRPredictResult> &ocr_result) { void Utility::sorted_boxes(std::vector<OCRPredictResult>& ocr_result)
std::sort(ocr_result.begin(), ocr_result.end(), Utility::comparison_box); {
if (ocr_result.size() > 0) { std::sort(ocr_result.begin(), ocr_result.end(), Utility::comparison_box);
for (int i = 0; i < ocr_result.size() - 1; i++) { if(ocr_result.size() > 0)
for (int j = i; j > 0; j--) { {
if (abs(ocr_result[j + 1].box[0][1] - ocr_result[j].box[0][1]) < 10 && for(int i = 0; i < ocr_result.size() - 1; i++)
(ocr_result[j + 1].box[0][0] < ocr_result[j].box[0][0])) { {
std::swap(ocr_result[i], ocr_result[i + 1]); for(int j = i; j > 0; j--)
{
if(abs(ocr_result[j + 1].box[0][1] - ocr_result[j].box[0][1]) < 10 &&
(ocr_result[j + 1].box[0][0] < ocr_result[j].box[0][0]))
{
std::swap(ocr_result[i], ocr_result[i + 1]);
}
}
} }
}
} }
}
} }
std::vector<int> Utility::xyxyxyxy2xyxy(std::vector<std::vector<int>> &box) { std::vector<int> Utility::xyxyxyxy2xyxy(std::vector<std::vector<int>>& box)
int x_collect[4] = {box[0][0], box[1][0], box[2][0], box[3][0]}; {
int y_collect[4] = {box[0][1], box[1][1], box[2][1], box[3][1]}; int x_collect[4] = {box[0][0], box[1][0], box[2][0], box[3][0]};
int left = int(*std::min_element(x_collect, x_collect + 4)); int y_collect[4] = {box[0][1], box[1][1], box[2][1], box[3][1]};
int right = int(*std::max_element(x_collect, x_collect + 4)); int left = int(*std::min_element(x_collect, x_collect + 4));
int top = int(*std::min_element(y_collect, y_collect + 4)); int right = int(*std::max_element(x_collect, x_collect + 4));
int bottom = int(*std::max_element(y_collect, y_collect + 4)); int top = int(*std::min_element(y_collect, y_collect + 4));
std::vector<int> box1(4, 0); int bottom = int(*std::max_element(y_collect, y_collect + 4));
box1[0] = left; std::vector<int> box1(4, 0);
box1[1] = top; box1[0] = left;
box1[2] = right; box1[1] = top;
box1[3] = bottom; box1[2] = right;
return box1; box1[3] = bottom;
return box1;
} }
std::vector<int> Utility::xyxyxyxy2xyxy(std::vector<int> &box) { std::vector<int> Utility::xyxyxyxy2xyxy(std::vector<int>& box)
int x_collect[4] = {box[0], box[2], box[4], box[6]}; {
int y_collect[4] = {box[1], box[3], box[5], box[7]}; int x_collect[4] = {box[0], box[2], box[4], box[6]};
int left = int(*std::min_element(x_collect, x_collect + 4)); int y_collect[4] = {box[1], box[3], box[5], box[7]};
int right = int(*std::max_element(x_collect, x_collect + 4)); int left = int(*std::min_element(x_collect, x_collect + 4));
int top = int(*std::min_element(y_collect, y_collect + 4)); int right = int(*std::max_element(x_collect, x_collect + 4));
int bottom = int(*std::max_element(y_collect, y_collect + 4)); int top = int(*std::min_element(y_collect, y_collect + 4));
std::vector<int> box1(4, 0); int bottom = int(*std::max_element(y_collect, y_collect + 4));
box1[0] = left; std::vector<int> box1(4, 0);
box1[1] = top; box1[0] = left;
box1[2] = right; box1[1] = top;
box1[3] = bottom; box1[2] = right;
return box1; box1[3] = bottom;
return box1;
} }
float Utility::fast_exp(float x) { float Utility::fast_exp(float x)
union { {
uint32_t i; union
float f; {
} v{}; uint32_t i;
v.i = (1 << 23) * (1.4426950409 * x + 126.93490512f); float f;
return v.f; } v{};
v.i = (1 << 23) * (1.4426950409 * x + 126.93490512f);
return v.f;
} }
std::vector<float> std::vector<float> Utility::activation_function_softmax(std::vector<float>& src)
Utility::activation_function_softmax(std::vector<float> &src) { {
int length = src.size(); int length = src.size();
std::vector<float> dst; std::vector<float> dst;
dst.resize(length); dst.resize(length);
const float alpha = float(*std::max_element(&src[0], &src[0 + length])); const float alpha = float(*std::max_element(&src[0], &src[0 + length]));
float denominator{0}; float denominator{0};
for (int i = 0; i < length; ++i) { for(int i = 0; i < length; ++i)
dst[i] = fast_exp(src[i] - alpha); {
denominator += dst[i]; dst[i] = fast_exp(src[i] - alpha);
} denominator += dst[i];
}
for (int i = 0; i < length; ++i) {
dst[i] /= denominator; for(int i = 0; i < length; ++i)
} {
return dst; dst[i] /= denominator;
}
return dst;
} }
float Utility::iou(std::vector<int> &box1, std::vector<int> &box2) { float Utility::iou(std::vector<int>& box1, std::vector<int>& box2)
int area1 = std::max(0, box1[2] - box1[0]) * std::max(0, box1[3] - box1[1]); {
int area2 = std::max(0, box2[2] - box2[0]) * std::max(0, box2[3] - box2[1]); int area1 = std::max(0, box1[2] - box1[0]) * std::max(0, box1[3] - box1[1]);
int area2 = std::max(0, box2[2] - box2[0]) * std::max(0, box2[3] - box2[1]);
// computing the sum_area
int sum_area = area1 + area2; // computing the sum_area
int sum_area = area1 + area2;
// find the each point of intersect rectangle
int x1 = std::max(box1[0], box2[0]); // find the each point of intersect rectangle
int y1 = std::max(box1[1], box2[1]); int x1 = std::max(box1[0], box2[0]);
int x2 = std::min(box1[2], box2[2]); int y1 = std::max(box1[1], box2[1]);
int y2 = std::min(box1[3], box2[3]); int x2 = std::min(box1[2], box2[2]);
int y2 = std::min(box1[3], box2[3]);
// judge if there is an intersect
if (y1 >= y2 || x1 >= x2) { // judge if there is an intersect
return 0.0; if(y1 >= y2 || x1 >= x2)
} else { {
int intersect = (x2 - x1) * (y2 - y1); return 0.0;
return intersect / (sum_area - intersect + 0.00000001); }
} else
{
int intersect = (x2 - x1) * (y2 - y1);
return intersect / (sum_area - intersect + 0.00000001);
}
} }
float Utility::iou(std::vector<float> &box1, std::vector<float> &box2) { float Utility::iou(std::vector<float>& box1, std::vector<float>& box2)
float area1 = std::max((float)0.0, box1[2] - box1[0]) * {
std::max((float)0.0, box1[3] - box1[1]); float area1 = std::max((float)0.0, box1[2] - box1[0]) * std::max((float)0.0, box1[3] - box1[1]);
float area2 = std::max((float)0.0, box2[2] - box2[0]) * float area2 = std::max((float)0.0, box2[2] - box2[0]) * std::max((float)0.0, box2[3] - box2[1]);
std::max((float)0.0, box2[3] - box2[1]);
// computing the sum_area
// computing the sum_area float sum_area = area1 + area2;
float sum_area = area1 + area2;
// find the each point of intersect rectangle
// find the each point of intersect rectangle float x1 = std::max(box1[0], box2[0]);
float x1 = std::max(box1[0], box2[0]); float y1 = std::max(box1[1], box2[1]);
float y1 = std::max(box1[1], box2[1]); float x2 = std::min(box1[2], box2[2]);
float x2 = std::min(box1[2], box2[2]); float y2 = std::min(box1[3], box2[3]);
float y2 = std::min(box1[3], box2[3]);
// judge if there is an intersect
// judge if there is an intersect if(y1 >= y2 || x1 >= x2)
if (y1 >= y2 || x1 >= x2) { {
return 0.0; return 0.0;
} else { }
float intersect = (x2 - x1) * (y2 - y1); else
return intersect / (sum_area - intersect + 0.00000001); {
} float intersect = (x2 - x1) * (y2 - y1);
return intersect / (sum_area - intersect + 0.00000001);
}
} }
} // namespace migraphxSamples } // namespace migraphxSamples
\ No newline at end of file
...@@ -30,84 +30,91 @@ ...@@ -30,84 +30,91 @@
#include "opencv2/imgcodecs.hpp" #include "opencv2/imgcodecs.hpp"
#include "opencv2/imgproc.hpp" #include "opencv2/imgproc.hpp"
namespace migraphxSamples { namespace migraphxSamples
{
struct OCRPredictResult {
std::vector<std::vector<int>> box; struct OCRPredictResult
std::string text; {
float score = -1.0; std::vector<std::vector<int>> box;
float cls_score; std::string text;
int cls_label = -1; float score = -1.0;
float cls_score;
int cls_label = -1;
}; };
struct StructurePredictResult { struct StructurePredictResult
std::vector<float> box; {
std::vector<std::vector<int>> cell_box; std::vector<float> box;
std::string type; std::vector<std::vector<int>> cell_box;
std::vector<OCRPredictResult> text_res; std::string type;
std::string html; std::vector<OCRPredictResult> text_res;
float html_score = -1; std::string html;
float confidence; float html_score = -1;
float confidence;
}; };
class Utility { class Utility
public: {
static std::vector<std::string> ReadDict(const std::string &path); public:
static std::vector<std::string> ReadDict(const std::string& path);
static void VisualizeBboxes(const cv::Mat &srcimg, static void VisualizeBboxes(const cv::Mat& srcimg,
const std::vector<OCRPredictResult> &ocr_result, const std::vector<OCRPredictResult>& ocr_result,
const std::string &save_path); const std::string& save_path);
static void VisualizeBboxes(const cv::Mat &srcimg, static void VisualizeBboxes(const cv::Mat& srcimg,
const StructurePredictResult &structure_result, const StructurePredictResult& structure_result,
const std::string &save_path); const std::string& save_path);
template <class ForwardIterator> template <class ForwardIterator>
inline static size_t argmax(ForwardIterator first, ForwardIterator last) { inline static size_t argmax(ForwardIterator first, ForwardIterator last)
return std::distance(first, std::max_element(first, last)); {
} return std::distance(first, std::max_element(first, last));
}
static void GetAllFiles(const char *dir_name, static void GetAllFiles(const char* dir_name, std::vector<std::string>& all_inputs);
std::vector<std::string> &all_inputs);
static cv::Mat GetRotateCropImage(const cv::Mat &srcimage, static cv::Mat GetRotateCropImage(const cv::Mat& srcimage, std::vector<std::vector<int>> box);
std::vector<std::vector<int>> box);
static std::vector<int> argsort(const std::vector<float> &array); static std::vector<int> argsort(const std::vector<float>& array);
static std::string basename(const std::string &filename); static std::string basename(const std::string& filename);
static bool PathExists(const std::string &path); static bool PathExists(const std::string& path);
static void CreateDir(const std::string &path); static void CreateDir(const std::string& path);
static void print_result(const std::vector<OCRPredictResult> &ocr_result); static void print_result(const std::vector<OCRPredictResult>& ocr_result);
static cv::Mat crop_image(cv::Mat &img, const std::vector<int> &area); static cv::Mat crop_image(cv::Mat& img, const std::vector<int>& area);
static cv::Mat crop_image(cv::Mat &img, const std::vector<float> &area); static cv::Mat crop_image(cv::Mat& img, const std::vector<float>& area);
static void sorted_boxes(std::vector<OCRPredictResult> &ocr_result); static void sorted_boxes(std::vector<OCRPredictResult>& ocr_result);
static std::vector<int> xyxyxyxy2xyxy(std::vector<std::vector<int>> &box); static std::vector<int> xyxyxyxy2xyxy(std::vector<std::vector<int>>& box);
static std::vector<int> xyxyxyxy2xyxy(std::vector<int> &box); static std::vector<int> xyxyxyxy2xyxy(std::vector<int>& box);
static float fast_exp(float x); static float fast_exp(float x);
static std::vector<float> static std::vector<float> activation_function_softmax(std::vector<float>& src);
activation_function_softmax(std::vector<float> &src); static float iou(std::vector<int>& box1, std::vector<int>& box2);
static float iou(std::vector<int> &box1, std::vector<int> &box2); static float iou(std::vector<float>& box1, std::vector<float>& box2);
static float iou(std::vector<float> &box1, std::vector<float> &box2);
private: private:
static bool comparison_box(const OCRPredictResult &result1, static bool comparison_box(const OCRPredictResult& result1, const OCRPredictResult& result2)
const OCRPredictResult &result2) { {
if (result1.box[0][1] < result2.box[0][1]) { if(result1.box[0][1] < result2.box[0][1])
return true; {
} else if (result1.box[0][1] == result2.box[0][1]) { return true;
return result1.box[0][0] < result2.box[0][0]; }
} else { else if(result1.box[0][1] == result2.box[0][1])
return false; {
return result1.box[0][0] < result2.box[0][0];
}
else
{
return false;
}
} }
}
}; };
} // namespace migraphxSamples } // namespace migraphxSamples
\ No newline at end of file
...@@ -7,33 +7,33 @@ ...@@ -7,33 +7,33 @@
namespace migraphxSamples namespace migraphxSamples
{ {
// 路径分隔符(Linux:‘/’,Windows:’\\’) // 路径分隔符(Linux:‘/’,Windows:’\\’)
#ifdef _WIN32 #ifdef _WIN32
#define PATH_SEPARATOR '\\' #define PATH_SEPARATOR '\\'
#else #else
#define PATH_SEPARATOR '/' #define PATH_SEPARATOR '/'
#endif #endif
#define CONFIG_FILE "../Resource/Configuration.xml" #define CONFIG_FILE "../Resource/Configuration.xml"
typedef enum _ErrorCode typedef enum _ErrorCode
{ {
SUCCESS=0, // 0 SUCCESS = 0, // 0
MODEL_NOT_EXIST, // 模型不存在 MODEL_NOT_EXIST, // 模型不存在
CONFIG_FILE_NOT_EXIST, // 配置文件不存在 CONFIG_FILE_NOT_EXIST, // 配置文件不存在
FAIL_TO_LOAD_MODEL, // 加载模型失败 FAIL_TO_LOAD_MODEL, // 加载模型失败
FAIL_TO_OPEN_CONFIG_FILE, // 加载配置文件失败 FAIL_TO_OPEN_CONFIG_FILE, // 加载配置文件失败
IMAGE_ERROR, // 图像错误 IMAGE_ERROR, // 图像错误
}ErrorCode; } ErrorCode;
typedef struct _ResultOfPrediction typedef struct _ResultOfPrediction
{ {
float confidence; float confidence;
int label; int label;
_ResultOfPrediction():confidence(0.0f),label(0){} _ResultOfPrediction() : confidence(0.0f), label(0) {}
}ResultOfPrediction; } ResultOfPrediction;
typedef struct _ResultOfDetection typedef struct _ResultOfDetection
{ {
...@@ -43,15 +43,15 @@ typedef struct _ResultOfDetection ...@@ -43,15 +43,15 @@ typedef struct _ResultOfDetection
std::string className; std::string className;
bool exist; bool exist;
_ResultOfDetection():confidence(0.0f),classID(0),exist(true){} _ResultOfDetection() : confidence(0.0f), classID(0), exist(true) {}
}ResultOfDetection; } ResultOfDetection;
typedef struct _InitializationParameterOfDetector typedef struct _InitializationParameterOfDetector
{ {
std::string parentPath; std::string parentPath;
std::string configFilePath; std::string configFilePath;
}InitializationParameterOfDetector; } InitializationParameterOfDetector;
typedef struct _InitializationParameterOfDetector InitializationParameterOfClassifier; typedef struct _InitializationParameterOfDetector InitializationParameterOfClassifier;
typedef struct _InitializationParameterOfDetector InitializationParameterOfSuperresolution; typedef struct _InitializationParameterOfDetector InitializationParameterOfSuperresolution;
...@@ -61,7 +61,6 @@ typedef struct _InitializationParameterOfDetector InitializationParameterOfOcr; ...@@ -61,7 +61,6 @@ typedef struct _InitializationParameterOfDetector InitializationParameterOfOcr;
typedef struct _InitializationParameterOfDetector InitializationParameterOfDB; typedef struct _InitializationParameterOfDetector InitializationParameterOfDB;
typedef struct _InitializationParameterOfDetector InitializationParameterOfSVTR; typedef struct _InitializationParameterOfDetector InitializationParameterOfSVTR;
} } // namespace migraphxSamples
#endif #endif
...@@ -3,34 +3,37 @@ ...@@ -3,34 +3,37 @@
namespace migraphxSamples namespace migraphxSamples
{ {
bool CompareConfidence(const ResultOfDetection &L,const ResultOfDetection &R) bool CompareConfidence(const ResultOfDetection& L, const ResultOfDetection& R)
{ {
return L.confidence > R.confidence; return L.confidence > R.confidence;
} }
bool CompareArea(const ResultOfDetection &L,const ResultOfDetection &R) bool CompareArea(const ResultOfDetection& L, const ResultOfDetection& R)
{ {
return L.boundingBox.area() > R.boundingBox.area(); return L.boundingBox.area() > R.boundingBox.area();
} }
void NMS(std::vector<ResultOfDetection> &detections, float IOUThreshold) void NMS(std::vector<ResultOfDetection>& detections, float IOUThreshold)
{ {
// sort // sort
std::sort(detections.begin(), detections.end(), CompareConfidence); std::sort(detections.begin(), detections.end(), CompareConfidence);
for (int i = 0; i<detections.size(); ++i) for(int i = 0; i < detections.size(); ++i)
{ {
if (detections[i].exist) if(detections[i].exist)
{ {
for (int j = i + 1; j<detections.size(); ++j) for(int j = i + 1; j < detections.size(); ++j)
{ {
if (detections[j].exist) if(detections[j].exist)
{ {
// compute IOU // compute IOU
float intersectionArea = (detections[i].boundingBox & detections[j].boundingBox).area(); float intersectionArea =
float intersectionRate = intersectionArea / (detections[i].boundingBox.area() + detections[j].boundingBox.area() - intersectionArea); (detections[i].boundingBox & detections[j].boundingBox).area();
float intersectionRate =
intersectionArea / (detections[i].boundingBox.area() +
detections[j].boundingBox.area() - intersectionArea);
if (intersectionRate>IOUThreshold) if(intersectionRate > IOUThreshold)
{ {
detections[j].exist = false; detections[j].exist = false;
} }
...@@ -38,7 +41,6 @@ void NMS(std::vector<ResultOfDetection> &detections, float IOUThreshold) ...@@ -38,7 +41,6 @@ void NMS(std::vector<ResultOfDetection> &detections, float IOUThreshold)
} }
} }
} }
} }
} } // namespace migraphxSamples
...@@ -9,12 +9,12 @@ namespace migraphxSamples ...@@ -9,12 +9,12 @@ namespace migraphxSamples
{ {
// 排序规则: 按照置信度或者按照面积排序 // 排序规则: 按照置信度或者按照面积排序
bool CompareConfidence(const ResultOfDetection &L,const ResultOfDetection &R); bool CompareConfidence(const ResultOfDetection& L, const ResultOfDetection& R);
bool CompareArea(const ResultOfDetection &L,const ResultOfDetection &R); bool CompareArea(const ResultOfDetection& L, const ResultOfDetection& R);
// 非极大抑制 // 非极大抑制
void NMS(std::vector<ResultOfDetection> &detections, float IOUThreshold); void NMS(std::vector<ResultOfDetection>& detections, float IOUThreshold);
} } // namespace migraphxSamples
#endif #endif
...@@ -14,9 +14,9 @@ ...@@ -14,9 +14,9 @@
// 路径分隔符(Linux:‘/’,Windows:’\\’) // 路径分隔符(Linux:‘/’,Windows:’\\’)
#ifdef _WIN32 #ifdef _WIN32
#define PATH_SEPARATOR '\\' #define PATH_SEPARATOR '\\'
#else #else
#define PATH_SEPARATOR '/' #define PATH_SEPARATOR '/'
#endif #endif
using namespace std; using namespace std;
...@@ -28,666 +28,672 @@ static std::vector<std::string> SplitString(std::string str, std::string separat ...@@ -28,666 +28,672 @@ static std::vector<std::string> SplitString(std::string str, std::string separat
{ {
std::string::size_type pos; std::string::size_type pos;
std::vector<std::string> result; std::vector<std::string> result;
str+=separator;//扩展字符串以方便操作 str += separator; // 扩展字符串以方便操作
int size=str.size(); int size = str.size();
for(int i=0; i<size; i++) for(int i = 0; i < size; i++)
{ {
pos=str.find(separator,i); pos = str.find(separator, i);
if(pos<size) if(pos < size)
{ {
std::string s=str.substr(i,pos-i); std::string s = str.substr(i, pos - i);
result.push_back(s); result.push_back(s);
i=pos+separator.size()-1; i = pos + separator.size() - 1;
} }
} }
return result; return result;
} }
#if defined _WIN32 || defined WINCE #if defined _WIN32 || defined WINCE
const char dir_separators[] = "/\\"; const char dir_separators[] = "/\\";
struct dirent struct dirent
{ {
const char* d_name; const char* d_name;
}; };
struct DIR struct DIR
{ {
#ifdef WINRT #ifdef WINRT
WIN32_FIND_DATAW data; WIN32_FIND_DATAW data;
#else #else
WIN32_FIND_DATAA data; WIN32_FIND_DATAA data;
#endif #endif
HANDLE handle; HANDLE handle;
dirent ent; dirent ent;
#ifdef WINRT #ifdef WINRT
DIR() { } DIR() {}
~DIR() ~DIR()
{ {
if (ent.d_name) if(ent.d_name)
delete[] ent.d_name; delete[] ent.d_name;
} }
#endif #endif
}; };
DIR* opendir(const char* path) DIR* opendir(const char* path)
{ {
DIR* dir = new DIR; DIR* dir = new DIR;
dir->ent.d_name = 0; dir->ent.d_name = 0;
#ifdef WINRT #ifdef WINRT
string full_path = string(path) + "\\*"; string full_path = string(path) + "\\*";
wchar_t wfull_path[MAX_PATH]; wchar_t wfull_path[MAX_PATH];
size_t copied = mbstowcs(wfull_path, full_path.c_str(), MAX_PATH); size_t copied = mbstowcs(wfull_path, full_path.c_str(), MAX_PATH);
CV_Assert((copied != MAX_PATH) && (copied != (size_t)-1)); CV_Assert((copied != MAX_PATH) && (copied != (size_t)-1));
dir->handle = ::FindFirstFileExW(wfull_path, FindExInfoStandard, dir->handle = ::FindFirstFileExW(
&dir->data, FindExSearchNameMatch, NULL, 0); wfull_path, FindExInfoStandard, &dir->data, FindExSearchNameMatch, NULL, 0);
#else #else
dir->handle = ::FindFirstFileExA((string(path) + "\\*").c_str(), dir->handle = ::FindFirstFileExA((string(path) + "\\*").c_str(),
FindExInfoStandard, &dir->data, FindExSearchNameMatch, NULL, 0); FindExInfoStandard,
&dir->data,
FindExSearchNameMatch,
NULL,
0);
#endif #endif
if (dir->handle == INVALID_HANDLE_VALUE) if(dir->handle == INVALID_HANDLE_VALUE)
{ {
/*closedir will do all cleanup*/ /*closedir will do all cleanup*/
delete dir; delete dir;
return 0; return 0;
} }
return dir; return dir;
} }
dirent* readdir(DIR* dir) dirent* readdir(DIR* dir)
{ {
#ifdef WINRT #ifdef WINRT
if (dir->ent.d_name != 0) if(dir->ent.d_name != 0)
{ {
if (::FindNextFileW(dir->handle, &dir->data) != TRUE) if(::FindNextFileW(dir->handle, &dir->data) != TRUE)
return 0; return 0;
} }
size_t asize = wcstombs(NULL, dir->data.cFileName, 0); size_t asize = wcstombs(NULL, dir->data.cFileName, 0);
CV_Assert((asize != 0) && (asize != (size_t)-1)); CV_Assert((asize != 0) && (asize != (size_t)-1));
char* aname = new char[asize + 1]; char* aname = new char[asize + 1];
aname[asize] = 0; aname[asize] = 0;
wcstombs(aname, dir->data.cFileName, asize); wcstombs(aname, dir->data.cFileName, asize);
dir->ent.d_name = aname; dir->ent.d_name = aname;
#else #else
if (dir->ent.d_name != 0) if(dir->ent.d_name != 0)
{ {
if (::FindNextFileA(dir->handle, &dir->data) != TRUE) if(::FindNextFileA(dir->handle, &dir->data) != TRUE)
return 0; return 0;
} }
dir->ent.d_name = dir->data.cFileName; dir->ent.d_name = dir->data.cFileName;
#endif #endif
return &dir->ent; return &dir->ent;
} }
void closedir(DIR* dir) void closedir(DIR* dir)
{ {
::FindClose(dir->handle); ::FindClose(dir->handle);
delete dir; delete dir;
} }
#else #else
# include <dirent.h> #include <dirent.h>
# include <sys/stat.h> #include <sys/stat.h>
const char dir_separators[] = "/"; const char dir_separators[] = "/";
#endif #endif
static bool isDir(const string &path, DIR* dir) static bool isDir(const string& path, DIR* dir)
{ {
#if defined _WIN32 || defined WINCE #if defined _WIN32 || defined WINCE
DWORD attributes; DWORD attributes;
BOOL status = TRUE; BOOL status = TRUE;
if (dir) if(dir)
attributes = dir->data.dwFileAttributes; attributes = dir->data.dwFileAttributes;
else else
{ {
WIN32_FILE_ATTRIBUTE_DATA all_attrs; WIN32_FILE_ATTRIBUTE_DATA all_attrs;
#ifdef WINRT #ifdef WINRT
wchar_t wpath[MAX_PATH]; wchar_t wpath[MAX_PATH];
size_t copied = mbstowcs(wpath, path.c_str(), MAX_PATH); size_t copied = mbstowcs(wpath, path.c_str(), MAX_PATH);
CV_Assert((copied != MAX_PATH) && (copied != (size_t)-1)); CV_Assert((copied != MAX_PATH) && (copied != (size_t)-1));
status = ::GetFileAttributesExW(wpath, GetFileExInfoStandard, &all_attrs); status = ::GetFileAttributesExW(wpath, GetFileExInfoStandard, &all_attrs);
#else #else
status = ::GetFileAttributesExA(path.c_str(), GetFileExInfoStandard, &all_attrs); status = ::GetFileAttributesExA(path.c_str(), GetFileExInfoStandard, &all_attrs);
#endif #endif
attributes = all_attrs.dwFileAttributes; attributes = all_attrs.dwFileAttributes;
} }
return status && ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0); return status && ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0);
#else #else
(void)dir; (void)dir;
struct stat stat_buf; struct stat stat_buf;
if (0 != stat(path.c_str(), &stat_buf)) if(0 != stat(path.c_str(), &stat_buf))
return false; return false;
int is_dir = S_ISDIR(stat_buf.st_mode); int is_dir = S_ISDIR(stat_buf.st_mode);
return is_dir != 0; return is_dir != 0;
#endif #endif
} }
bool IsDirectory(const string &path) bool IsDirectory(const string& path) { return isDir(path, NULL); }
{
return isDir(path, NULL);
}
bool Exists(const string& path) bool Exists(const string& path)
{ {
#if defined _WIN32 || defined WINCE #if defined _WIN32 || defined WINCE
BOOL status = TRUE; BOOL status = TRUE;
{ {
WIN32_FILE_ATTRIBUTE_DATA all_attrs; WIN32_FILE_ATTRIBUTE_DATA all_attrs;
#ifdef WINRT #ifdef WINRT
wchar_t wpath[MAX_PATH]; wchar_t wpath[MAX_PATH];
size_t copied = mbstowcs(wpath, path.c_str(), MAX_PATH); size_t copied = mbstowcs(wpath, path.c_str(), MAX_PATH);
CV_Assert((copied != MAX_PATH) && (copied != (size_t)-1)); CV_Assert((copied != MAX_PATH) && (copied != (size_t)-1));
status = ::GetFileAttributesExW(wpath, GetFileExInfoStandard, &all_attrs); status = ::GetFileAttributesExW(wpath, GetFileExInfoStandard, &all_attrs);
#else #else
status = ::GetFileAttributesExA(path.c_str(), GetFileExInfoStandard, &all_attrs); status = ::GetFileAttributesExA(path.c_str(), GetFileExInfoStandard, &all_attrs);
#endif #endif
} }
return !!status; return !!status;
#else #else
struct stat stat_buf; struct stat stat_buf;
return (0 == stat(path.c_str(), &stat_buf)); return (0 == stat(path.c_str(), &stat_buf));
#endif #endif
} }
bool IsPathSeparator(char c) bool IsPathSeparator(char c) { return c == '/' || c == '\\'; }
{
return c == '/' || c == '\\'; string JoinPath(const string& base, const string& path)
} {
if(base.empty())
string JoinPath(const string& base, const string& path) return path;
{ if(path.empty())
if (base.empty()) return base;
return path;
if (path.empty()) bool baseSep = IsPathSeparator(base[base.size() - 1]);
return base; bool pathSep = IsPathSeparator(path[0]);
string result;
bool baseSep = IsPathSeparator(base[base.size() - 1]); if(baseSep && pathSep)
bool pathSep = IsPathSeparator(path[0]); {
string result; result = base + path.substr(1);
if (baseSep && pathSep) }
{ else if(!baseSep && !pathSep)
result = base + path.substr(1); {
} result = base + PATH_SEPARATOR + path;
else if (!baseSep && !pathSep) }
{ else
result = base + PATH_SEPARATOR + path; {
} result = base + path;
else }
{ return result;
result = base + path; }
}
return result; static bool wildcmp(const char* string, const char* wild)
} {
const char *cp = 0, *mp = 0;
static bool wildcmp(const char *string, const char *wild)
{ while((*string) && (*wild != '*'))
const char *cp = 0, *mp = 0; {
if((*wild != *string) && (*wild != '?'))
while ((*string) && (*wild != '*'))
{
if ((*wild != *string) && (*wild != '?'))
{
return false;
}
wild++;
string++;
}
while (*string)
{
if (*wild == '*')
{
if (!*++wild)
{
return true;
}
mp = wild;
cp = string + 1;
}
else if ((*wild == *string) || (*wild == '?'))
{
wild++;
string++;
}
else
{
wild = mp;
string = cp++;
}
}
while (*wild == '*')
{
wild++;
}
return *wild == 0;
}
static void glob_rec(const string &directory, const string& wildchart, std::vector<string>& result,
bool recursive, bool includeDirectories, const string& pathPrefix)
{
DIR *dir;
if ((dir = opendir(directory.c_str())) != 0)
{
/* find all the files and directories within directory */
try
{
struct dirent *ent;
while ((ent = readdir(dir)) != 0)
{
const char* name = ent->d_name;
if ((name[0] == 0) || (name[0] == '.' && name[1] == 0) || (name[0] == '.' && name[1] == '.' && name[2] == 0))
continue;
string path = JoinPath(directory, name);
string entry = JoinPath(pathPrefix, name);
if (isDir(path, dir))
{
if (recursive)
glob_rec(path, wildchart, result, recursive, includeDirectories, entry);
if (!includeDirectories)
continue;
}
if (wildchart.empty() || wildcmp(name, wildchart.c_str()))
result.push_back(entry);
}
}
catch (...)
{
closedir(dir);
throw;
}
closedir(dir);
}
else
{
printf("could not open directory: %s", directory.c_str());
}
}
void GetFileNameList(const string &directory, const string &pattern, std::vector<string>& result, bool recursive, bool addPath)
{
// split pattern
vector<string> patterns=SplitString(pattern,",");
result.clear();
for(int i=0;i<patterns.size();++i)
{ {
string eachPattern=patterns[i]; return false;
std::vector<string> eachResult; }
glob_rec(directory, eachPattern, eachResult, recursive, true, directory);
for(int j=0;j<eachResult.size();++j) wild++;
string++;
}
while(*string)
{
if(*wild == '*')
{
if(!*++wild)
{ {
if (IsDirectory(eachResult[j])) return true;
continue; }
if(addPath)
mp = wild;
cp = string + 1;
}
else if((*wild == *string) || (*wild == '?'))
{
wild++;
string++;
}
else
{
wild = mp;
string = cp++;
}
}
while(*wild == '*')
{
wild++;
}
return *wild == 0;
}
static void glob_rec(const string& directory,
const string& wildchart,
std::vector<string>& result,
bool recursive,
bool includeDirectories,
const string& pathPrefix)
{
DIR* dir;
if((dir = opendir(directory.c_str())) != 0)
{
/* find all the files and directories within directory */
try
{
struct dirent* ent;
while((ent = readdir(dir)) != 0)
{
const char* name = ent->d_name;
if((name[0] == 0) || (name[0] == '.' && name[1] == 0) ||
(name[0] == '.' && name[1] == '.' && name[2] == 0))
continue;
string path = JoinPath(directory, name);
string entry = JoinPath(pathPrefix, name);
if(isDir(path, dir))
{
if(recursive)
glob_rec(path, wildchart, result, recursive, includeDirectories, entry);
if(!includeDirectories)
continue;
}
if(wildchart.empty() || wildcmp(name, wildchart.c_str()))
result.push_back(entry);
}
}
catch(...)
{
closedir(dir);
throw;
}
closedir(dir);
}
else
{
printf("could not open directory: %s", directory.c_str());
}
}
void GetFileNameList(const string& directory,
const string& pattern,
std::vector<string>& result,
bool recursive,
bool addPath)
{
// split pattern
vector<string> patterns = SplitString(pattern, ",");
result.clear();
for(int i = 0; i < patterns.size(); ++i)
{
string eachPattern = patterns[i];
std::vector<string> eachResult;
glob_rec(directory, eachPattern, eachResult, recursive, true, directory);
for(int j = 0; j < eachResult.size(); ++j)
{
if(IsDirectory(eachResult[j]))
continue;
if(addPath)
{
result.push_back(eachResult[j]);
}
else
{
result.push_back(GetFileName(eachResult[j]));
}
}
}
std::sort(result.begin(), result.end());
}
void GetFileNameList2(const string& directory,
const string& pattern,
std::vector<string>& result,
bool recursive,
bool addPath)
{
// split pattern
vector<string> patterns = SplitString(pattern, ",");
result.clear();
for(int i = 0; i < patterns.size(); ++i)
{
string eachPattern = patterns[i];
std::vector<string> eachResult;
glob_rec(directory, eachPattern, eachResult, recursive, true, directory);
for(int j = 0; j < eachResult.size(); ++j)
{
string filePath = eachResult[j];
if(IsDirectory(filePath))
{
filePath = filePath + "/";
for(int k = 0; k < filePath.size(); ++k)
{ {
result.push_back(eachResult[j]); if(IsPathSeparator(filePath[k]))
{
filePath[k] = '/';
}
} }
else }
if(addPath)
{
result.push_back(filePath);
}
else
{
if(!IsDirectory(filePath))
{ {
result.push_back(GetFileName(eachResult[j])); result.push_back(GetFileName(filePath));
} }
} }
} }
std::sort(result.begin(), result.end()); }
} std::sort(result.begin(), result.end());
}
void GetFileNameList2(const string &directory, const string &pattern, std::vector<string>& result, bool recursive, bool addPath)
{ void RemoveAll(const string& path)
// split pattern {
vector<string> patterns = SplitString(pattern, ",");
if(!Exists(path))
result.clear(); return;
for (int i = 0; i<patterns.size(); ++i) if(IsDirectory(path))
{ {
string eachPattern = patterns[i]; std::vector<string> entries;
std::vector<string> eachResult; GetFileNameList2(path, string(), entries, false, true);
glob_rec(directory, eachPattern, eachResult, recursive, true, directory); for(size_t i = 0; i < entries.size(); i++)
for (int j = 0; j<eachResult.size(); ++j) {
{ const string& e = entries[i];
string filePath = eachResult[j]; RemoveAll(e);
if (IsDirectory(filePath)) }
{
filePath = filePath + "/";
for (int k = 0; k < filePath.size(); ++k)
{
if (IsPathSeparator(filePath[k]))
{
filePath[k] = '/';
}
}
}
if (addPath)
{
result.push_back(filePath);
}
else
{
if (!IsDirectory(filePath))
{
result.push_back(GetFileName(filePath));
}
}
}
}
std::sort(result.begin(), result.end());
}
void RemoveAll(const string& path)
{
if (!Exists(path))
return;
if (IsDirectory(path))
{
std::vector<string> entries;
GetFileNameList2(path, string(), entries, false, true);
for (size_t i = 0; i < entries.size(); i++)
{
const string& e = entries[i];
RemoveAll(e);
}
#ifdef _MSC_VER #ifdef _MSC_VER
bool result = _rmdir(path.c_str()) == 0; bool result = _rmdir(path.c_str()) == 0;
#else #else
bool result = rmdir(path.c_str()) == 0; bool result = rmdir(path.c_str()) == 0;
#endif #endif
if (!result) if(!result)
{ {
printf("can't remove directory: %s\n", path.c_str()); printf("can't remove directory: %s\n", path.c_str());
} }
} }
else else
{ {
#ifdef _MSC_VER #ifdef _MSC_VER
bool result = _unlink(path.c_str()) == 0; bool result = _unlink(path.c_str()) == 0;
#else #else
bool result = unlink(path.c_str()) == 0; bool result = unlink(path.c_str()) == 0;
#endif #endif
if (!result) if(!result)
{
printf("can't remove file: %s\n", path.c_str());
}
}
}
void Remove(const string &directory, const string &extension)
{
DIR *dir;
static int numberOfFiles = 0;
if ((dir = opendir(directory.c_str())) != 0)
{
/* find all the files and directories within directory */
try
{
struct dirent *ent;
while ((ent = readdir(dir)) != 0)
{
const char* name = ent->d_name;
if ((name[0] == 0) || (name[0] == '.' && name[1] == 0) || (name[0] == '.' && name[1] == '.' && name[2] == 0))
continue;
string path = JoinPath(directory, name);
if (isDir(path, dir))
{
Remove(path, extension);
}
// �ж���չ��
if (extension.empty() || wildcmp(name, extension.c_str()))
{
RemoveAll(path);
++numberOfFiles;
printf("%s deleted! number of deleted files:%d\n", path.c_str(), numberOfFiles);
}
}
}
catch (...)
{
closedir(dir);
throw;
}
closedir(dir);
}
else
{
printf("could not open directory: %s", directory.c_str());
}
// ����RemoveAllɾ��Ŀ¼
RemoveAll(directory);
}
string GetFileName(const string &path)
{
string fileName;
int indexOfPathSeparator = -1;
for (int i = path.size() - 1; i >= 0; --i)
{
if (IsPathSeparator(path[i]))
{
fileName = path.substr(i + 1, path.size() - i - 1);
indexOfPathSeparator = i;
break;
}
}
if (indexOfPathSeparator == -1)
{ {
fileName = path; printf("can't remove file: %s\n", path.c_str());
} }
}
}
void Remove(const string& directory, const string& extension)
{
return fileName; DIR* dir;
}
string GetFileName_NoExtension(const string &path) static int numberOfFiles = 0;
if((dir = opendir(directory.c_str())) != 0)
{ {
string fileName=GetFileName(path); /* find all the files and directories within directory */
string fileName_NoExtension; try
for(int i=fileName.size()-1;i>0;--i)
{ {
if(fileName[i]=='.') struct dirent* ent;
while((ent = readdir(dir)) != 0)
{ {
fileName_NoExtension=fileName.substr(0,i); const char* name = ent->d_name;
break; if((name[0] == 0) || (name[0] == '.' && name[1] == 0) ||
} (name[0] == '.' && name[1] == '.' && name[2] == 0))
} continue;
return fileName_NoExtension; string path = JoinPath(directory, name);
}
if(isDir(path, dir))
string GetExtension(const string &path) {
{ Remove(path, extension);
string fileName; }
for (int i = path.size() - 1; i >= 0; --i)
{ // �ж���չ��
if (path[i]=='.') if(extension.empty() || wildcmp(name, extension.c_str()))
{ {
fileName = path.substr(i, path.size() - i); RemoveAll(path);
break; ++numberOfFiles;
} printf("%s deleted! number of deleted files:%d\n", path.c_str(), numberOfFiles);
} }
return fileName;
}
string GetParentPath(const string &path)
{
string fileName;
for (int i = path.size() - 1; i >= 0; --i)
{
if (IsPathSeparator(path[i]))
{
fileName = path.substr(0, i+1);
break;
}
}
return fileName;
}
static bool CreateDirectory(const string &path)
{
#if defined WIN32 || defined _WIN32 || defined WINCE
#ifdef WINRT
wchar_t wpath[MAX_PATH];
size_t copied = mbstowcs(wpath, path.c_str(), MAX_PATH);
CV_Assert((copied != MAX_PATH) && (copied != (size_t)-1));
int result = CreateDirectoryA(wpath, NULL) ? 0 : -1;
#else
int result = _mkdir(path.c_str());
#endif
#elif defined __linux__ || defined __APPLE__
int result = mkdir(path.c_str(), 0777);
#else
int result = -1;
#endif
if (result == -1)
{
return IsDirectory(path);
} }
return true; }
} catch(...)
bool CreateDirectories(const string &directoryPath)
{
string path = directoryPath;
for (;;)
{
char last_char = path.empty() ? 0 : path[path.length() - 1];
if (IsPathSeparator(last_char))
{
path = path.substr(0, path.length() - 1);
continue;
}
break;
}
if (path.empty() || path == "./" || path == ".\\" || path == ".")
return true;
if (IsDirectory(path))
return true;
size_t pos = path.rfind('/');
if (pos == string::npos)
pos = path.rfind('\\');
if (pos != string::npos)
{
string parent_directory = path.substr(0, pos);
if (!parent_directory.empty())
{
if (!CreateDirectories(parent_directory))
return false;
}
}
return CreateDirectory(path);
}
bool CopyFile(const string srcPath, const string dstPath)
{
std::ifstream srcFile(srcPath,ios::binary);
std::ofstream dstFile(dstPath,ios::binary);
if(!srcFile.is_open())
{ {
printf("can not open %s\n",srcPath.c_str()); closedir(dir);
return false; throw;
} }
if(!dstFile.is_open()) closedir(dir);
}
else
{
printf("could not open directory: %s", directory.c_str());
}
// ����RemoveAllɾ��Ŀ¼
RemoveAll(directory);
}
string GetFileName(const string& path)
{
string fileName;
int indexOfPathSeparator = -1;
for(int i = path.size() - 1; i >= 0; --i)
{
if(IsPathSeparator(path[i]))
{ {
printf("can not open %s\n", dstPath.c_str()); fileName = path.substr(i + 1, path.size() - i - 1);
return false; indexOfPathSeparator = i;
break;
} }
if(srcPath==dstPath) }
if(indexOfPathSeparator == -1)
{
fileName = path;
}
return fileName;
}
string GetFileName_NoExtension(const string& path)
{
string fileName = GetFileName(path);
string fileName_NoExtension;
for(int i = fileName.size() - 1; i > 0; --i)
{
if(fileName[i] == '.')
{ {
printf("src can not be same with dst\n"); fileName_NoExtension = fileName.substr(0, i);
return false; break;
} }
char buffer[2048]; }
unsigned int numberOfBytes=0;
while(srcFile) return fileName_NoExtension;
}
string GetExtension(const string& path)
{
string fileName;
for(int i = path.size() - 1; i >= 0; --i)
{
if(path[i] == '.')
{ {
srcFile.read(buffer,2048); fileName = path.substr(i, path.size() - i);
dstFile.write(buffer,srcFile.gcount()); break;
numberOfBytes+=srcFile.gcount();
} }
srcFile.close();
dstFile.close();
return true;
} }
bool CopyDirectories(string srcPath, const string dstPath) return fileName;
}
string GetParentPath(const string& path)
{
string fileName;
for(int i = path.size() - 1; i >= 0; --i)
{ {
if(srcPath==dstPath) if(IsPathSeparator(path[i]))
{ {
printf("src can not be same with dst\n"); fileName = path.substr(0, i + 1);
return false; break;
} }
}
// ȥ������·���ָ��� return fileName;
srcPath = srcPath.substr(0, srcPath.size() - 1); }
vector<string> fileNameList; static bool CreateDirectory(const string& path)
GetFileNameList2(srcPath, "", fileNameList, true, true); {
#if defined WIN32 || defined _WIN32 || defined WINCE
#ifdef WINRT
wchar_t wpath[MAX_PATH];
size_t copied = mbstowcs(wpath, path.c_str(), MAX_PATH);
CV_Assert((copied != MAX_PATH) && (copied != (size_t)-1));
int result = CreateDirectoryA(wpath, NULL) ? 0 : -1;
#else
int result = _mkdir(path.c_str());
#endif
#elif defined __linux__ || defined __APPLE__
int result = mkdir(path.c_str(), 0777);
#else
int result = -1;
#endif
string parentPathOfSrc=GetParentPath(srcPath); if(result == -1)
int length=parentPathOfSrc.size(); {
return IsDirectory(path);
}
return true;
}
// create all directories bool CreateDirectories(const string& directoryPath)
for(int i=0;i<fileNameList.size();++i) {
string path = directoryPath;
for(;;)
{
char last_char = path.empty() ? 0 : path[path.length() - 1];
if(IsPathSeparator(last_char))
{ {
// create directory path = path.substr(0, path.length() - 1);
string srcFilePath=fileNameList[i]; continue;
string subStr=srcFilePath.substr(length,srcFilePath.size()-length);
string dstFilePath=dstPath+subStr;
string parentPathOfDst=GetParentPath(dstFilePath);
CreateDirectories(parentPathOfDst);
} }
break;
}
// copy file if(path.empty() || path == "./" || path == ".\\" || path == ".")
for(int i=0;i<fileNameList.size();++i) return true;
if(IsDirectory(path))
return true;
size_t pos = path.rfind('/');
if(pos == string::npos)
pos = path.rfind('\\');
if(pos != string::npos)
{
string parent_directory = path.substr(0, pos);
if(!parent_directory.empty())
{ {
string srcFilePath=fileNameList[i]; if(!CreateDirectories(parent_directory))
if (IsDirectory(srcFilePath)) return false;
{
continue;
}
string subStr=srcFilePath.substr(length,srcFilePath.size()-length);
string dstFilePath=dstPath+subStr;
// copy file
CopyFile(srcFilePath,dstFilePath);
// process
double process = (1.0*(i + 1) / fileNameList.size()) * 100;
printf("%s done! %f% \n", GetFileName(fileNameList[i]).c_str(), process);
} }
printf("all done!(the number of files:%d)\n", fileNameList.size()); }
return true; return CreateDirectory(path);
}
bool CopyFile(const string srcPath, const string dstPath)
{
std::ifstream srcFile(srcPath, ios::binary);
std::ofstream dstFile(dstPath, ios::binary);
if(!srcFile.is_open())
{
printf("can not open %s\n", srcPath.c_str());
return false;
}
if(!dstFile.is_open())
{
printf("can not open %s\n", dstPath.c_str());
return false;
}
if(srcPath == dstPath)
{
printf("src can not be same with dst\n");
return false;
}
char buffer[2048];
unsigned int numberOfBytes = 0;
while(srcFile)
{
srcFile.read(buffer, 2048);
dstFile.write(buffer, srcFile.gcount());
numberOfBytes += srcFile.gcount();
}
srcFile.close();
dstFile.close();
return true;
}
bool CopyDirectories(string srcPath, const string dstPath)
{
if(srcPath == dstPath)
{
printf("src can not be same with dst\n");
return false;
} }
} // ȥ������·���ָ���
srcPath = srcPath.substr(0, srcPath.size() - 1);
vector<string> fileNameList;
GetFileNameList2(srcPath, "", fileNameList, true, true);
string parentPathOfSrc = GetParentPath(srcPath);
int length = parentPathOfSrc.size();
// create all directories
for(int i = 0; i < fileNameList.size(); ++i)
{
// create directory
string srcFilePath = fileNameList[i];
string subStr = srcFilePath.substr(length, srcFilePath.size() - length);
string dstFilePath = dstPath + subStr;
string parentPathOfDst = GetParentPath(dstFilePath);
CreateDirectories(parentPathOfDst);
}
// copy file
for(int i = 0; i < fileNameList.size(); ++i)
{
string srcFilePath = fileNameList[i];
if(IsDirectory(srcFilePath))
{
continue;
}
string subStr = srcFilePath.substr(length, srcFilePath.size() - length);
string dstFilePath = dstPath + subStr;
// copy file
CopyFile(srcFilePath, dstFilePath);
// process
double process = (1.0 * (i + 1) / fileNameList.size()) * 100;
printf("%s done! %f% \n", GetFileName(fileNameList[i]).c_str(), process);
}
printf("all done!(the number of files:%d)\n", fileNameList.size());
return true;
}
} // namespace migraphxSamples
...@@ -5,27 +5,27 @@ ...@@ -5,27 +5,27 @@
#include <string> #include <string>
#include <vector> #include <vector>
namespace migraphxSamples namespace migraphxSamples
{ {
// 路径是否存在 // 路径是否存在
bool Exists(const std::string &path); bool Exists(const std::string& path);
// 路径是否为目录 // 路径是否为目录
bool IsDirectory(const std::string &path); bool IsDirectory(const std::string& path);
// 是否是路径分隔符(Linux:‘/’,Windows:’\\’) // 是否是路径分隔符(Linux:‘/’,Windows:’\\’)
bool IsPathSeparator(char c); bool IsPathSeparator(char c);
// 路径拼接 // 路径拼接
std::string JoinPath(const std::string &base, const std::string &path); std::string JoinPath(const std::string& base, const std::string& path);
// 创建多级目录,注意:创建多级目录的时候,目标目录是不能有文件存在的 // 创建多级目录,注意:创建多级目录的时候,目标目录是不能有文件存在的
bool CreateDirectories(const std::string &directoryPath); bool CreateDirectories(const std::string& directoryPath);
/** 生成符合指定模式的文件名列表(支持递归遍历) /** 生成符合指定模式的文件名列表(支持递归遍历)
* *
* pattern: 模式,比如"*.jpg","*.png","*.jpg,*.png" * pattern: 模式,比如"*.jpg","*.png","*.jpg,*.png"
* addPath:是否包含父路径 * addPath:是否包含父路径
* 注意: * 注意:
...@@ -36,35 +36,43 @@ bool CreateDirectories(const std::string &directoryPath); ...@@ -36,35 +36,43 @@ bool CreateDirectories(const std::string &directoryPath);
5. 不能返回子目录名 5. 不能返回子目录名
* *
*/ */
void GetFileNameList(const std::string &directory, const std::string &pattern, std::vector<std::string> &result, bool recursive, bool addPath); void GetFileNameList(const std::string& directory,
const std::string& pattern,
std::vector<std::string>& result,
bool recursive,
bool addPath);
// 与GetFileNameList的区别在于如果有子目录,在addPath为true的时候会返回子目录路径(目录名最后有"/") // 与GetFileNameList的区别在于如果有子目录,在addPath为true的时候会返回子目录路径(目录名最后有"/")
void GetFileNameList2(const std::string &directory, const std::string &pattern, std::vector<std::string> &result, bool recursive, bool addPath); void GetFileNameList2(const std::string& directory,
const std::string& pattern,
std::vector<std::string>& result,
bool recursive,
bool addPath);
// 删除文件或者目录,支持递归删除 // 删除文件或者目录,支持递归删除
void Remove(const std::string &directory, const std::string &extension=""); void Remove(const std::string& directory, const std::string& extension = "");
/** 获取路径的文件名和扩展名 /** 获取路径的文件名和扩展名
* *
* 示例:path为D:/1/1.txt,则GetFileName()为1.txt,GetFileName_NoExtension()为1,GetExtension()为.txt,GetParentPath()为D:/1/ * 示例:path为D:/1/1.txt,则GetFileName()为1.txt,GetFileName_NoExtension()为1,GetExtension()为.txt,GetParentPath()为D:/1/
*/ */
std::string GetFileName(const std::string &path); std::string GetFileName(const std::string& path);
std::string GetFileName_NoExtension(const std::string &path); std::string GetFileName_NoExtension(const std::string& path);
std::string GetExtension(const std::string &path); std::string GetExtension(const std::string& path);
std::string GetParentPath(const std::string &path); std::string GetParentPath(const std::string& path);
// 拷贝文件 // 拷贝文件
bool CopyFile(const std::string srcPath,const std::string dstPath); bool CopyFile(const std::string srcPath, const std::string dstPath);
/** 拷贝目录 /** 拷贝目录
* *
* 示例:CopyDirectories("D:/0/1/2/","E:/3/");实现把D:/0/1/2/目录拷贝到E:/3/目录中(即拷贝完成后的目录结构为E:/3/2/) * 示例:CopyDirectories("D:/0/1/2/","E:/3/");实现把D:/0/1/2/目录拷贝到E:/3/目录中(即拷贝完成后的目录结构为E:/3/2/)
* 注意: * 注意:
1.第一个参数的最后不能加”/” 1.第一个参数的最后不能加”/”
2.不能拷贝隐藏文件 2.不能拷贝隐藏文件
*/ */
bool CopyDirectories(std::string srcPath,const std::string dstPath); bool CopyDirectories(std::string srcPath, const std::string dstPath);
} } // namespace migraphxSamples
#endif #endif
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
#include <map> #include <map>
#include <thread> #include <thread>
#include <mutex> #include <mutex>
#if (defined WIN32 || defined _WIN32) #if(defined WIN32 || defined _WIN32)
#include <Windows.h> #include <Windows.h>
#else #else
#include <sys/time.h> #include <sys/time.h>
...@@ -16,13 +16,13 @@ ...@@ -16,13 +16,13 @@
using namespace std; using namespace std;
/** 简易日志 /** 简易日志
* *
* 不依赖于其他第三方库,只需要包含一个头文件就可以使用。提供了4种日志级别,包括INFO,DEBUG,WARN和ERROR。 * 不依赖于其他第三方库,只需要包含一个头文件就可以使用。提供了4种日志级别,包括INFO,DEBUG,WARN和ERROR。
* *
* 示例1: * 示例1:
// 初始化日志,在./Log/目录下创建两个日志文件log1.log和log2.log(注意:目录./Log/需要存在,否则日志创建失败) //
初始化日志,在./Log/目录下创建两个日志文件log1.log和log2.log(注意:目录./Log/需要存在,否则日志创建失败)
LogManager::GetInstance()->Initialize("./Log/","log1"); LogManager::GetInstance()->Initialize("./Log/","log1");
LogManager::GetInstance()->Initialize("./Log/","log2"); LogManager::GetInstance()->Initialize("./Log/","log2");
...@@ -34,11 +34,11 @@ using namespace std; ...@@ -34,11 +34,11 @@ using namespace std;
// 关闭日志 // 关闭日志
LogManager::GetInstance()->Close("log1"); LogManager::GetInstance()->Close("log1");
LogManager::GetInstance()->Close("log2"); LogManager::GetInstance()->Close("log2");
* 示例2: * 示例2:
// 将日志输出到控制台 // 将日志输出到控制台
string log = "Hello World"; string log = "Hello World";
LOG_INFO(stdout, "%s\n", log.c_str()); LOG_INFO(stdout, "%s\n", log.c_str());
* 注意: * 注意:
1. 需要C++11 1. 需要C++11
...@@ -50,44 +50,43 @@ using namespace std; ...@@ -50,44 +50,43 @@ using namespace std;
class LogManager class LogManager
{ {
private: private:
LogManager(){} LogManager() {}
public: public:
~LogManager(){} ~LogManager() {}
inline void Initialize(const string &parentPath,const string &logName) inline void Initialize(const string& parentPath, const string& logName)
{ {
// 日志名为空表示输出到控制台 // 日志名为空表示输出到控制台
if(logName.size()==0) if(logName.size() == 0)
return; return;
// 查找该日志文件,如果没有则创建 // 查找该日志文件,如果没有则创建
std::map<string, FILE*>::const_iterator iter = logMap.find(logName); std::map<string, FILE*>::const_iterator iter = logMap.find(logName);
if (iter == logMap.end()) if(iter == logMap.end())
{ {
string pathOfLog = parentPath+ logName + ".log"; string pathOfLog = parentPath + logName + ".log";
FILE *logFile = fopen(pathOfLog.c_str(), "a"); // w:覆盖原有文件,a:追加 FILE* logFile = fopen(pathOfLog.c_str(), "a"); // w:覆盖原有文件,a:追加
if(logFile!=NULL) if(logFile != NULL)
{ {
logMap.insert(std::make_pair(logName, logFile)); logMap.insert(std::make_pair(logName, logFile));
} }
} }
} }
inline FILE* GetLogFile(const string &logName) inline FILE* GetLogFile(const string& logName)
{ {
std::map<string, FILE*>::const_iterator iter=logMap.find(logName); std::map<string, FILE*>::const_iterator iter = logMap.find(logName);
if(iter==logMap.end()) if(iter == logMap.end())
{ {
return NULL; return NULL;
} }
return (*iter).second; return (*iter).second;
} }
inline void Close(const string &logName) inline void Close(const string& logName)
{ {
std::map<string, FILE*>::const_iterator iter=logMap.find(logName); std::map<string, FILE*>::const_iterator iter = logMap.find(logName);
if(iter==logMap.end()) if(iter == logMap.end())
{ {
return; return;
} }
...@@ -95,10 +94,7 @@ public: ...@@ -95,10 +94,7 @@ public:
fclose((*iter).second); fclose((*iter).second);
logMap.erase(iter); logMap.erase(iter);
} }
inline std::mutex &GetLogMutex() inline std::mutex& GetLogMutex() { return logMutex; }
{
return logMutex;
}
// Singleton // Singleton
static LogManager* GetInstance() static LogManager* GetInstance()
...@@ -106,21 +102,22 @@ public: ...@@ -106,21 +102,22 @@ public:
static LogManager logManager; static LogManager logManager;
return &logManager; return &logManager;
} }
private:
private:
std::map<string, FILE*> logMap; std::map<string, FILE*> logMap;
std::mutex logMutex; std::mutex logMutex;
}; };
#ifdef LOG_MUTEX #ifdef LOG_MUTEX
#define LOCK LogManager::GetInstance()->GetLogMutex().lock() #define LOCK LogManager::GetInstance()->GetLogMutex().lock()
#define UNLOCK LogManager::GetInstance()->GetLogMutex().unlock() #define UNLOCK LogManager::GetInstance()->GetLogMutex().unlock()
#else #else
#define LOCK #define LOCK
#define UNLOCK #define UNLOCK
#endif #endif
// log time // log time
typedef struct _LogTime typedef struct _LogTime
{ {
string year; string year;
string month; string month;
...@@ -131,53 +128,53 @@ typedef struct _LogTime ...@@ -131,53 +128,53 @@ typedef struct _LogTime
string millisecond; // ms string millisecond; // ms
string microsecond; // us string microsecond; // us
string weekDay; string weekDay;
}LogTime; } LogTime;
inline LogTime GetTime() inline LogTime GetTime()
{ {
LogTime currentTime; LogTime currentTime;
#if (defined WIN32 || defined _WIN32) #if(defined WIN32 || defined _WIN32)
SYSTEMTIME systemTime; SYSTEMTIME systemTime;
GetLocalTime(&systemTime); GetLocalTime(&systemTime);
char temp[8] = { 0 }; char temp[8] = {0};
sprintf(temp, "%04d", systemTime.wYear); sprintf(temp, "%04d", systemTime.wYear);
currentTime.year=string(temp); currentTime.year = string(temp);
sprintf(temp, "%02d", systemTime.wMonth); sprintf(temp, "%02d", systemTime.wMonth);
currentTime.month=string(temp); currentTime.month = string(temp);
sprintf(temp, "%02d", systemTime.wDay); sprintf(temp, "%02d", systemTime.wDay);
currentTime.day=string(temp); currentTime.day = string(temp);
sprintf(temp, "%02d", systemTime.wHour); sprintf(temp, "%02d", systemTime.wHour);
currentTime.hour=string(temp); currentTime.hour = string(temp);
sprintf(temp, "%02d", systemTime.wMinute); sprintf(temp, "%02d", systemTime.wMinute);
currentTime.minute=string(temp); currentTime.minute = string(temp);
sprintf(temp, "%02d", systemTime.wSecond); sprintf(temp, "%02d", systemTime.wSecond);
currentTime.second=string(temp); currentTime.second = string(temp);
sprintf(temp, "%03d", systemTime.wMilliseconds); sprintf(temp, "%03d", systemTime.wMilliseconds);
currentTime.millisecond=string(temp); currentTime.millisecond = string(temp);
sprintf(temp, "%d", systemTime.wDayOfWeek); sprintf(temp, "%d", systemTime.wDayOfWeek);
currentTime.weekDay=string(temp); currentTime.weekDay = string(temp);
#else #else
struct timeval tv; struct timeval tv;
struct tm *p; struct tm* p;
gettimeofday(&tv, NULL); gettimeofday(&tv, NULL);
p = localtime(&tv.tv_sec); p = localtime(&tv.tv_sec);
char temp[8]={0}; char temp[8] = {0};
sprintf(temp,"%04d",1900+p->tm_year); sprintf(temp, "%04d", 1900 + p->tm_year);
currentTime.year=string(temp); currentTime.year = string(temp);
sprintf(temp,"%02d",1+p->tm_mon); sprintf(temp, "%02d", 1 + p->tm_mon);
currentTime.month=string(temp); currentTime.month = string(temp);
sprintf(temp,"%02d",p->tm_mday); sprintf(temp, "%02d", p->tm_mday);
currentTime.day=string(temp); currentTime.day = string(temp);
sprintf(temp,"%02d",p->tm_hour); sprintf(temp, "%02d", p->tm_hour);
currentTime.hour=string(temp); currentTime.hour = string(temp);
sprintf(temp,"%02d",p->tm_min); sprintf(temp, "%02d", p->tm_min);
currentTime.minute=string(temp); currentTime.minute = string(temp);
sprintf(temp,"%02d",p->tm_sec); sprintf(temp, "%02d", p->tm_sec);
currentTime.second=string(temp); currentTime.second = string(temp);
sprintf(temp,"%03d",(int)(tv.tv_usec/1000)); sprintf(temp, "%03d", (int)(tv.tv_usec / 1000));
currentTime.millisecond = string(temp); currentTime.millisecond = string(temp);
sprintf(temp, "%03d", (int)(tv.tv_usec % 1000)); sprintf(temp, "%03d", (int)(tv.tv_usec % 1000));
currentTime.microsecond = string(temp); currentTime.microsecond = string(temp);
...@@ -187,61 +184,83 @@ inline LogTime GetTime() ...@@ -187,61 +184,83 @@ inline LogTime GetTime()
return currentTime; return currentTime;
} }
#define LOG_TIME(logFile) \ #define LOG_TIME(logFile) \
do\ do \
{\ { \
LogTime currentTime=GetTime(); \ LogTime currentTime = GetTime(); \
fprintf(((logFile == NULL) ? stdout : logFile), "%s-%s-%s %s:%s:%s.%s\t",currentTime.year.c_str(),currentTime.month.c_str(),currentTime.day.c_str(),currentTime.hour.c_str(),currentTime.minute.c_str(),currentTime.second.c_str(),currentTime.millisecond.c_str()); \ fprintf(((logFile == NULL) ? stdout : logFile), \
}while (0) "%s-%s-%s %s:%s:%s.%s\t", \
currentTime.year.c_str(), \
currentTime.month.c_str(), \
#define LOG_INFO(logFile,logInfo, ...) \ currentTime.day.c_str(), \
do\ currentTime.hour.c_str(), \
{\ currentTime.minute.c_str(), \
LOCK; \ currentTime.second.c_str(), \
LOG_TIME(logFile); \ currentTime.millisecond.c_str()); \
fprintf(((logFile == NULL) ? stdout : logFile), "INFO\t"); \ } while(0)
fprintf(((logFile == NULL) ? stdout : logFile), "[%s:%d (%s) ]: ", __FILE__, __LINE__, __FUNCTION__); \
fprintf(((logFile == NULL) ? stdout : logFile), logInfo, ## __VA_ARGS__); \
fflush(logFile); \
UNLOCK; \
} while (0)
#define LOG_DEBUG(logFile,logInfo, ...) \
do\
{\
LOCK; \
LOG_TIME(logFile);\
fprintf(((logFile==NULL)?stdout:logFile), "DEBUG\t"); \
fprintf(((logFile==NULL)?stdout:logFile), "[%s:%d (%s) ]: ", __FILE__, __LINE__, __FUNCTION__); \
fprintf(((logFile==NULL)?stdout:logFile),logInfo, ## __VA_ARGS__); \
fflush(logFile); \
UNLOCK; \
} while (0)
#define LOG_ERROR(logFile,logInfo, ...) \
do\
{\
LOCK; \
LOG_TIME(logFile);\
fprintf(((logFile==NULL)?stdout:logFile), "ERROR\t"); \
fprintf(((logFile==NULL)?stdout:logFile), "[%s:%d (%s) ]: ", __FILE__, __LINE__, __FUNCTION__); \
fprintf(((logFile==NULL)?stdout:logFile),logInfo, ## __VA_ARGS__); \
fflush(logFile); \
UNLOCK; \
} while (0)
#define LOG_WARN(logFile,logInfo, ...) \
do\
{\
LOCK; \
LOG_TIME(logFile);\
fprintf(((logFile==NULL)?stdout:logFile), "WARN\t"); \
fprintf(((logFile==NULL)?stdout:logFile), "[%s:%d (%s) ]: ", __FILE__, __LINE__, __FUNCTION__); \
fprintf(((logFile==NULL)?stdout:logFile),logInfo, ## __VA_ARGS__); \
fflush(logFile); \
UNLOCK; \
} while (0)
#endif // __SIMPLE_LOG_H__ #define LOG_INFO(logFile, logInfo, ...) \
do \
{ \
LOCK; \
LOG_TIME(logFile); \
fprintf(((logFile == NULL) ? stdout : logFile), "INFO\t"); \
fprintf(((logFile == NULL) ? stdout : logFile), \
"[%s:%d (%s) ]: ", \
__FILE__, \
__LINE__, \
__FUNCTION__); \
fprintf(((logFile == NULL) ? stdout : logFile), logInfo, ##__VA_ARGS__); \
fflush(logFile); \
UNLOCK; \
} while(0)
#define LOG_DEBUG(logFile, logInfo, ...) \
do \
{ \
LOCK; \
LOG_TIME(logFile); \
fprintf(((logFile == NULL) ? stdout : logFile), "DEBUG\t"); \
fprintf(((logFile == NULL) ? stdout : logFile), \
"[%s:%d (%s) ]: ", \
__FILE__, \
__LINE__, \
__FUNCTION__); \
fprintf(((logFile == NULL) ? stdout : logFile), logInfo, ##__VA_ARGS__); \
fflush(logFile); \
UNLOCK; \
} while(0)
#define LOG_ERROR(logFile, logInfo, ...) \
do \
{ \
LOCK; \
LOG_TIME(logFile); \
fprintf(((logFile == NULL) ? stdout : logFile), "ERROR\t"); \
fprintf(((logFile == NULL) ? stdout : logFile), \
"[%s:%d (%s) ]: ", \
__FILE__, \
__LINE__, \
__FUNCTION__); \
fprintf(((logFile == NULL) ? stdout : logFile), logInfo, ##__VA_ARGS__); \
fflush(logFile); \
UNLOCK; \
} while(0)
#define LOG_WARN(logFile, logInfo, ...) \
do \
{ \
LOCK; \
LOG_TIME(logFile); \
fprintf(((logFile == NULL) ? stdout : logFile), "WARN\t"); \
fprintf(((logFile == NULL) ? stdout : logFile), \
"[%s:%d (%s) ]: ", \
__FILE__, \
__LINE__, \
__FUNCTION__); \
fprintf(((logFile == NULL) ? stdout : logFile), logInfo, ##__VA_ARGS__); \
fflush(logFile); \
UNLOCK; \
} while(0)
#endif // __SIMPLE_LOG_H__
...@@ -10,20 +10,20 @@ int main() ...@@ -10,20 +10,20 @@ int main()
{ {
// 创建PaddleOCR车牌识别 // 创建PaddleOCR车牌识别
migraphxSamples::VLPR vlpr; migraphxSamples::VLPR vlpr;
migraphxSamples::InitializationParameterOfDB initParamOfDB; migraphxSamples::InitializationParameterOfDB initParamOfDB;
migraphxSamples::InitializationParameterOfSVTR initParamOfSVTR; migraphxSamples::InitializationParameterOfSVTR initParamOfSVTR;
vlpr.Initialize(initParamOfDB, initParamOfSVTR); vlpr.Initialize(initParamOfDB, initParamOfSVTR);
// 读取测试图片 // 读取测试图片
cv:: Mat Image=cv::imread("../Resource/Images/vlpr.jpg", 1); cv::Mat Image = cv::imread("../Resource/Images/vlpr.jpg", 1);
// 推理 // 推理
std::vector<std::string> recTexts; std::vector<std::string> recTexts;
std::vector<float> recTextScores; std::vector<float> recTextScores;
vlpr.Infer(Image, recTexts, recTextScores); vlpr.Infer(Image, recTexts, recTextScores);
// 打印结果 // 打印结果
for (int i = 0; i < recTexts.size(); i++) for(int i = 0; i < recTexts.size(); i++)
{ {
printf("VLPR Result:%s\n", recTexts[i].c_str()); printf("VLPR Result:%s\n", recTexts[i].c_str());
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment