Crnn.cpp 6.13 KB
Newer Older
Your Name's avatar
Your Name committed
1
#include <Crnn.h>
liucong's avatar
liucong committed
2

Your Name's avatar
Your Name committed
3
4
#include <migraphx/onnx.hpp>
#include <migraphx/gpu/target.hpp>
liucong's avatar
liucong committed
5

Your Name's avatar
Your Name committed
6
7
8
9
10
11
12
#include <Filesystem.h>
#include <SimpleLog.h>


namespace migraphxSamples
{

liucong's avatar
liucong committed
13
Crnn::Crnn()
Your Name's avatar
Your Name committed
14
15
16
17
18
19
20
21
22
23
24
25
26
{

}

Crnn::~Crnn()
{

    configurationFile.release();
    
}

ErrorCode Crnn::Initialize(InitializationParameterOfOcr initializationParameterOfOcr, bool dynamic)
{
liucong's avatar
liucong committed
27
28
29
    // 读取配置文件
    std::string configFilePath=initializationParameterOfOcr.configFilePath;
    if(Exists(configFilePath)==false)
Your Name's avatar
Your Name committed
30
    {
liucong's avatar
liucong committed
31
32
        LOG_ERROR(stdout, "no configuration file!\n");
        return CONFIG_FILE_NOT_EXIST;
Your Name's avatar
Your Name committed
33
    }
liucong's avatar
liucong committed
34
35
36
37
38
39
    if(!configurationFile.open(configFilePath, cv::FileStorage::READ))
    {
       LOG_ERROR(stdout, "fail to open configuration file\n");
       return FAIL_TO_OPEN_CONFIG_FILE;
    }
    LOG_INFO(stdout, "succeed to open configuration file\n");
Your Name's avatar
Your Name committed
40
41

    // 获取配置文件参数
liucong's avatar
liucong committed
42
43
    cv::FileNode netNode = configurationFile["CrnnDynamic"];
    std::string modelPath=(std::string)netNode["ModelPath"];
Your Name's avatar
Your Name committed
44
45
46
47

    // 加载模型
    if(Exists(modelPath)==false)
    {
liucong's avatar
liucong committed
48
        LOG_ERROR(stdout,"%s not exist!\n",modelPath.c_str());
Your Name's avatar
Your Name committed
49
50
51
52
53
54
55
56
57
        return MODEL_NOT_EXIST;
    }

    if(dynamic)
    {   
        migraphx::onnx_options onnx_options;
        onnx_options.map_input_dims["input"]={1,1,32,512};

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

        // 获取模型输入属性
liucong's avatar
liucong committed
61
62
63
64
65
66
67
68
        std::unordered_map<std::string, migraphx::shape> inputMap=net.get_parameter_shapes();
        inputName=inputMap.begin()->first;
        inputShape=inputMap.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
69
70

        // log输出日志信息
liucong's avatar
liucong committed
71
72
        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
73
74
75
76
77
78
79
    }
    else
    {
        migraphx::onnx_options onnx_options;
        onnx_options.map_input_dims["input"]={1,1,32,100};

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

        // 获取模型输入属性
liucong's avatar
liucong committed
83
84
85
86
87
88
89
90
        std::unordered_map<std::string, migraphx::shape> inputMap=net.get_parameter_shapes();
        inputName=inputMap.begin()->first;
        inputShape=inputMap.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
91
92

        // log输出日志信息
liucong's avatar
liucong committed
93
94
        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
95
96
97
98
99
100
101
102
    }

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

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

liucong's avatar
liucong committed
107
108
109
110
    // warm up
    std::unordered_map<std::string, migraphx::argument> inputData;
    inputData[inputName]=migraphx::argument{inputShape};
    net.eval(inputData);                        
Your Name's avatar
Your Name committed
111
112
113
114
115
116
117
118

    return SUCCESS;
}

ErrorCode Crnn::Infer(const cv::Mat &srcImage, std::vector<char> &resultsChar, bool raw, bool dynamic)
{
    if(srcImage.empty() || srcImage.type()!=CV_8UC3)
    {
liucong's avatar
liucong committed
119
        LOG_ERROR(stdout, "image error!\n");
Your Name's avatar
Your Name committed
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
        return IMAGE_ERROR;
    }

    cv::Mat inputImage, inputBlob;
    cv::cvtColor(srcImage, inputImage, CV_BGR2GRAY);
    
    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);
    
    for(int i=0; i<width * height; i++)
    {
        *((float*)inputBlob.data+i) = ((*((float*)inputBlob.data+i))/255.f - 0.5)/0.5;
    }
    
liucong's avatar
liucong committed
145
146
    // 创建输入数据
    std::unordered_map<std::string, migraphx::argument> inputData;
Your Name's avatar
Your Name committed
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
    if(dynamic)
    {
        std::vector<std::size_t> dynamicShape = {1, 1, 32, width};
        inputData[inputName]= migraphx::argument{migraphx::shape(inputShape.type(),dynamicShape), (float*)inputBlob.data};
    }
    else
    {
        inputData[inputName]= migraphx::argument{inputShape, (float*)inputBlob.data};
    }
    
    // 推理
    std::vector<migraphx::argument> inferenceResults = net.eval(inputData);
     
    // 获取推理结果
    std::vector<cv::Mat> outs;
    migraphx::argument result = inferenceResults[0]; 

    // 转换为cv::Mat
    migraphx::shape outputShape = result.get_shape();
    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());
    outs.push_back(out);

    std::vector<int> predChars; 
    const std::string alphabet = "-0123456789abcdefghijklmnopqrstuvwxyz";

    //获取字符索引序列
    for(uint i = 0; i < outs[0].size[0]; i++)
    {
liucong's avatar
liucong committed
177
        cv::Mat scores = cv::Mat(1,outs[0].size[2],CV_32F,outs[0].ptr<float>(i));
Your Name's avatar
Your Name committed
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
        cv::Point charIdPoint;
        double maxCharScore;
        cv::minMaxLoc(scores, 0, &maxCharScore, 0, &charIdPoint);
        int maxIdx = charIdPoint.x;
        predChars.push_back(maxIdx);
    }
    
    //字符转录处理
    for(uint i=0; i<predChars.size(); i++)
    {
        if(raw)
        {
            resultsChar.push_back(alphabet[predChars[i]]);
        }
        else
        {
            if(predChars[i] != 0)
            {
                if(!(i > 0 && predChars[i-1]==predChars[i]))
                {
                    resultsChar.push_back(alphabet[predChars[i]]);
                }
            }
        }
    }

    return SUCCESS;
}
}