Crnn.cpp 7.01 KB
Newer Older
Your Name's avatar
Your Name committed
1
2
3
4
5
6
7
8
9
#include <Crnn.h>
#include <migraphx/onnx.hpp>
#include <migraphx/gpu/target.hpp>
#include <Filesystem.h>
#include <SimpleLog.h>

namespace migraphxSamples
{

liucong's avatar
liucong committed
10
Crnn::Crnn() {}
Your Name's avatar
Your Name committed
11

liucong's avatar
liucong committed
12
Crnn::~Crnn() { configurationFile.release(); }
Your Name's avatar
Your Name committed
13
14
15

ErrorCode Crnn::Initialize(InitializationParameterOfOcr initializationParameterOfOcr, bool dynamic)
{
liucong's avatar
liucong committed
16
    // 读取配置文件
liucong's avatar
liucong committed
17
    std::string configFilePath = initializationParameterOfOcr.configFilePath;
liucong's avatar
liucong committed
18
    if(!Exists(configFilePath))
Your Name's avatar
Your Name committed
19
    {
liucong's avatar
liucong committed
20
21
        LOG_ERROR(stdout, "no configuration file!\n");
        return CONFIG_FILE_NOT_EXIST;
Your Name's avatar
Your Name committed
22
    }
liucong's avatar
liucong committed
23
24
    if(!configurationFile.open(configFilePath, cv::FileStorage::READ))
    {
liucong's avatar
liucong committed
25
26
        LOG_ERROR(stdout, "fail to open configuration file\n");
        return FAIL_TO_OPEN_CONFIG_FILE;
liucong's avatar
liucong committed
27
28
    }
    LOG_INFO(stdout, "succeed to open configuration file\n");
Your Name's avatar
Your Name committed
29
30

    // 获取配置文件参数
liucong's avatar
liucong committed
31
32
    cv::FileNode netNode  = configurationFile["CrnnDynamic"];
    std::string modelPath = (std::string)netNode["ModelPath"];
Your Name's avatar
Your Name committed
33
34

    // 加载模型
liucong's avatar
liucong committed
35
    if(!Exists(modelPath))
Your Name's avatar
Your Name committed
36
    {
liucong's avatar
liucong committed
37
        LOG_ERROR(stdout, "%s not exist!\n", modelPath.c_str());
Your Name's avatar
Your Name committed
38
39
40
41
        return MODEL_NOT_EXIST;
    }

    if(dynamic)
shizhm's avatar
shizhm committed
42
    {
Your Name's avatar
Your Name committed
43
        migraphx::onnx_options onnx_options;
liucong's avatar
liucong committed
44
        onnx_options.map_input_dims["input"] = {1, 1, 32, 512};
Your Name's avatar
Your Name committed
45

shizhm's avatar
shizhm committed
46
        net = migraphx::parse_onnx(modelPath, onnx_options);
liucong's avatar
liucong committed
47
        LOG_INFO(stdout, "succeed to load model: %s\n", GetFileName(modelPath).c_str());
Your Name's avatar
Your Name committed
48

liucong's avatar
liucong committed
49
        // 获取模型输入/输出节点信息
liucong's avatar
liucong committed
50
51
52
53
54
55
56
57
58
        std::unordered_map<std::string, migraphx::shape> inputs  = net.get_inputs();
        std::unordered_map<std::string, migraphx::shape> outputs = net.get_outputs();
        inputName                                                = inputs.begin()->first;
        inputShape                                               = inputs.begin()->second;
        int N                                                    = inputShape.lens()[0];
        int C                                                    = inputShape.lens()[1];
        int H                                                    = inputShape.lens()[2];
        int W                                                    = inputShape.lens()[3];
        inputSize                                                = cv::Size(W, H);
Your Name's avatar
Your Name committed
59
60

        // log输出日志信息
liucong's avatar
liucong committed
61
62
        LOG_INFO(stdout, "InputMaxSize:%dx%d\n", inputSize.width, inputSize.height);
        LOG_INFO(stdout, "InputName:%s\n", inputName.c_str());
Your Name's avatar
Your Name committed
63
64
65
66
    }
    else
    {
        migraphx::onnx_options onnx_options;
liucong's avatar
liucong committed
67
        onnx_options.map_input_dims["input"] = {1, 1, 32, 100};
Your Name's avatar
Your Name committed
68

shizhm's avatar
shizhm committed
69
        net = migraphx::parse_onnx(modelPath, onnx_options);
liucong's avatar
liucong committed
70
        LOG_INFO(stdout, "succeed to load model: %s\n", GetFileName(modelPath).c_str());
Your Name's avatar
Your Name committed
71

liucong's avatar
liucong committed
72
        // 获取模型输入/输出节点信息
liucong's avatar
liucong committed
73
74
75
76
77
78
79
80
81
        std::unordered_map<std::string, migraphx::shape> inputs  = net.get_inputs();
        std::unordered_map<std::string, migraphx::shape> outputs = net.get_outputs();
        inputName                                                = inputs.begin()->first;
        inputShape                                               = inputs.begin()->second;
        int N                                                    = inputShape.lens()[0];
        int C                                                    = inputShape.lens()[1];
        int H                                                    = inputShape.lens()[2];
        int W                                                    = inputShape.lens()[3];
        inputSize                                                = cv::Size(W, H);
Your Name's avatar
Your Name committed
82
83

        // log输出日志信息
liucong's avatar
liucong committed
84
85
        LOG_INFO(stdout, "InputSize:%dx%d\n", inputSize.width, inputSize.height);
        LOG_INFO(stdout, "InputName:%s\n", inputName.c_str());
Your Name's avatar
Your Name committed
86
87
88
89
90
91
92
    }

    // 设置模型为GPU模式
    migraphx::target gpuTarget = migraphx::gpu::target{};

    // 编译模型
    migraphx::compile_options options;
liucong's avatar
liucong committed
93
94
95
96
    options.device_id    = 0; // 设置GPU设备,默认为0号设备
    options.offload_copy = true;
    net.compile(gpuTarget, options);
    LOG_INFO(stdout, "succeed to compile model: %s\n", GetFileName(modelPath).c_str());
Your Name's avatar
Your Name committed
97

liucong's avatar
liucong committed
98
99
    // warm up
    std::unordered_map<std::string, migraphx::argument> inputData;
liucong's avatar
liucong committed
100
    inputData[inputName] = migraphx::argument{inputShape};
shizhm's avatar
shizhm committed
101
    net.eval(inputData);
Your Name's avatar
Your Name committed
102
103
104
105

    return SUCCESS;
}

liucong's avatar
liucong committed
106
107
ErrorCode
Crnn::Infer(const cv::Mat& srcImage, std::vector<char>& resultsChar, bool raw, bool dynamic)
Your Name's avatar
Your Name committed
108
{
liucong's avatar
liucong committed
109
    if(srcImage.empty() || srcImage.type() != CV_8UC3)
Your Name's avatar
Your Name committed
110
    {
liucong's avatar
liucong committed
111
        LOG_ERROR(stdout, "image error!\n");
Your Name's avatar
Your Name committed
112
113
114
115
116
        return IMAGE_ERROR;
    }

    cv::Mat inputImage, inputBlob;
    cv::cvtColor(srcImage, inputImage, CV_BGR2GRAY);
shizhm's avatar
shizhm committed
117

Your Name's avatar
Your Name committed
118
119
120
121
122
123
124
125
126
127
128
129
130
    int height, width, widthRaw;
    widthRaw = inputImage.cols;
    if(dynamic)
    {
        cv::resize(inputImage, inputImage, cv::Size(widthRaw, 32));
        height = inputImage.rows, width = inputImage.cols;
    }
    else
    {
        cv::resize(inputImage, inputImage, cv::Size(100, 32));
        height = inputImage.rows, width = inputImage.cols;
    }
    inputBlob = cv::dnn::blobFromImage(inputImage);
shizhm's avatar
shizhm committed
131

liucong's avatar
liucong committed
132
    for(int i = 0; i < width * height; i++)
Your Name's avatar
Your Name committed
133
    {
liucong's avatar
liucong committed
134
        *((float*)inputBlob.data + i) = ((*((float*)inputBlob.data + i)) / 255.f - 0.5) / 0.5;
Your Name's avatar
Your Name committed
135
    }
shizhm's avatar
shizhm committed
136

liucong's avatar
liucong committed
137
138
    // 创建输入数据
    std::unordered_map<std::string, migraphx::argument> inputData;
Your Name's avatar
Your Name committed
139
140
141
    if(dynamic)
    {
        std::vector<std::size_t> dynamicShape = {1, 1, 32, width};
liucong's avatar
liucong committed
142
143
        inputData[inputName] = migraphx::argument{migraphx::shape(inputShape.type(), dynamicShape),
                                                  (float*)inputBlob.data};
Your Name's avatar
Your Name committed
144
145
146
    }
    else
    {
liucong's avatar
liucong committed
147
        inputData[inputName] = migraphx::argument{inputShape, (float*)inputBlob.data};
Your Name's avatar
Your Name committed
148
    }
shizhm's avatar
shizhm committed
149

Your Name's avatar
Your Name committed
150
151
    // 推理
    std::vector<migraphx::argument> inferenceResults = net.eval(inputData);
shizhm's avatar
shizhm committed
152

Your Name's avatar
Your Name committed
153
154
    // 获取推理结果
    std::vector<cv::Mat> outs;
shizhm's avatar
shizhm committed
155
    migraphx::argument result = inferenceResults[0];
Your Name's avatar
Your Name committed
156
157
158

    // 转换为cv::Mat
    migraphx::shape outputShape = result.get_shape();
liucong's avatar
liucong committed
159
160
161
    int shape[] = {outputShape.lens()[0], outputShape.lens()[1], outputShape.lens()[2]};
    cv::Mat out(3, shape, CV_32F);
    memcpy(out.data, result.data(), sizeof(float) * outputShape.elements());
Your Name's avatar
Your Name committed
162
163
    outs.push_back(out);

shizhm's avatar
shizhm committed
164
    std::vector<int> predChars;
Your Name's avatar
Your Name committed
165
166
    const std::string alphabet = "-0123456789abcdefghijklmnopqrstuvwxyz";

liucong's avatar
liucong committed
167
    // 获取字符索引序列
Your Name's avatar
Your Name committed
168
169
    for(uint i = 0; i < outs[0].size[0]; i++)
    {
liucong's avatar
liucong committed
170
        cv::Mat scores = cv::Mat(1, outs[0].size[2], CV_32F, outs[0].ptr<float>(i));
Your Name's avatar
Your Name committed
171
172
173
174
175
176
        cv::Point charIdPoint;
        double maxCharScore;
        cv::minMaxLoc(scores, 0, &maxCharScore, 0, &charIdPoint);
        int maxIdx = charIdPoint.x;
        predChars.push_back(maxIdx);
    }
shizhm's avatar
shizhm committed
177

liucong's avatar
liucong committed
178
179
    // 字符转录处理
    for(uint i = 0; i < predChars.size(); i++)
Your Name's avatar
Your Name committed
180
181
182
183
184
185
186
187
188
    {
        if(raw)
        {
            resultsChar.push_back(alphabet[predChars[i]]);
        }
        else
        {
            if(predChars[i] != 0)
            {
liucong's avatar
liucong committed
189
                if(!(i > 0 && predChars[i - 1] == predChars[i]))
Your Name's avatar
Your Name committed
190
191
192
193
194
195
196
197
198
                {
                    resultsChar.push_back(alphabet[predChars[i]]);
                }
            }
        }
    }

    return SUCCESS;
}
liucong's avatar
liucong committed
199
} // namespace migraphxSamples