Repository: opencv/opencv
File: modules/dnn/src/onnx/onnx_importer.cpp (C++)

Code before:

    Mat limitMat = getBlob(node_proto, 1);
    limitMat.convertTo(limitMat, CV_32F);
    float limit = limitMat.at<float>(0);

    Mat deltaMat = getBlob(node_proto, 2);
    deltaMat.convertTo(deltaMat, CV_32F);
    float delta = deltaMat.at<float>(0);

    int number_of_elements = std::max(int(std::ceil((limit - start) / delta)), 0);
    Mat r(1, number_of_elements, CV_32FC1); // should be 1d tensor, but Mat doesn't support it
    for (int i = 0; i < number_of_elements; i++)
    {
        r.at<float>(i) = start + (i * delta);
    }
    addConstant(node_proto.output(0), r);
    constBlobsExtraInfo.insert(std::make_pair(node_proto.output(0), TensorInfo(1)));
}

void ONNXImporter::parseRandomNormalLike(LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto)
{
    CV_CheckEQ(node_proto.input_size(), 1, "RandomNormalLike: one input is required");

    if (layerParams.has("dtype"))
    {
        int onnx_dtype = layerParams.get<int>("dtype");
        int cvDepth = CV_32F;
        switch (onnx_dtype)
        {
        case opencv_onnx::TensorProto_DataType_FLOAT16: cvDepth = CV_16F; break;
        case opencv_onnx::TensorProto_DataType_FLOAT:   cvDepth = CV_32F; break;
        case opencv_onnx::TensorProto_DataType_DOUBLE:  cvDepth = CV_64F; break;
        case opencv_onnx::TensorProto_DataType_UINT8:   cvDepth = CV_8U;  break;
        case opencv_onnx::TensorProto_DataType_INT8:    cvDepth = CV_8S;  break;
        case opencv_onnx::TensorProto_DataType_UINT16:  cvDepth = CV_16U; break;
        case opencv_onnx::TensorProto_DataType_INT16:   cvDepth = CV_16S; break;
        case opencv_onnx::TensorProto_DataType_INT32:   cvDepth = CV_32S; break;
        case opencv_onnx::TensorProto_DataType_INT64:   cvDepth = CV_32S; break;
        default:
            cvDepth = CV_32F;
        }
        layerParams.set("depth", cvDepth);
    }

    layerParams.type = "RandomNormalLike";
    addLayer(layerParams, node_proto);
}

void ONNXImporter::parseScatter(LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto)
{
    CV_CheckEQ(node_proto.input_size(), 3, "Scatter: three inputs are required.");

Review comment (refactor):
can we move this code (conversion from onnx type to opencv type) into a dedicated function, because we may need this mapping in more than one layer?

Code after:

    Mat limitMat = getBlob(node_proto, 1);
    limitMat.convertTo(limitMat, CV_32F);
    float limit = limitMat.at<float>(0);

    Mat deltaMat = getBlob(node_proto, 2);
    deltaMat.convertTo(deltaMat, CV_32F);
    float delta = deltaMat.at<float>(0);

    int number_of_elements = std::max(int(std::ceil((limit - start) / delta)), 0);
    Mat r(1, number_of_elements, CV_32FC1); // should be 1d tensor, but Mat doesn't support it
    for (int i = 0; i < number_of_elements; i++)
    {
        r.at<float>(i) = start + (i * delta);
    }
    addConstant(node_proto.output(0), r);
    constBlobsExtraInfo.insert(std::make_pair(node_proto.output(0), TensorInfo(1)));
}

void ONNXImporter::parseRandomNormalLike(LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto)
{
    CV_CheckEQ(node_proto.input_size(), 1, "RandomNormalLike: one input is required");

    layerParams.type = "RandomNormalLike";
    addLayer(layerParams, node_proto);
}

void ONNXImporter::parseScatter(LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto)
{
    CV_CheckEQ(node_proto.input_size(), 3, "Scatter: three inputs are required.");
    layerParams.type = "Scatter";
    if (node_proto.op_type() == "ScatterND")
        layerParams.type = "ScatterND";

     size_t consts = 0;
    for (size_t i = 0; i < node_proto.input_size(); ++i)
        if (layer_id.find(node_proto.input(i)) == layer_id.end())
            ++consts;

    if (consts == node_proto.input_size())
    {
        std::vector<Mat> inputs, output;
        for (size_t i = 0; i < node_proto.input_size(); i++)
        {
            Mat blob = getBlob(node_proto, i);
            if (i == 1) // indices
                blob.convertTo(blob, CV_32F);
            inputs.push_back(blob);
        }
        runLayer(layerParams, inputs, output);
        CV_Assert(output.size() == 1);