EnoxSoftware / OpenCVForUnity

OpenCV for Unity (Untiy Asset Plugin)
https://assetstore.unity.com/packages/tools/integration/opencv-for-unity-21088
550 stars 172 forks source link

setInput crashes on tensorflow model #143

Closed Tigran1983 closed 2 years ago

Tigran1983 commented 2 years ago

pb_model.zip

Hello dear team,

OpencvDnn setInput crashes on my tensorflow model.

Want to mention, that before tensorflow model loading I used ONNX model, reshape it's Mat to get channels_first format, and that is working good. Now I generated .pb and .pbtxt files and try to load with Net.readNet, readFromTensorflow, but in both cases setInput crashes. Model files attached. Please look through and let me know what is an issue?

Best Regards, Tigran

EnoxSoftware commented 2 years ago

I loaded your model file with the following test script and got this error in the console.

dnn::readNetFromTensorflow_10() : OpenCV(4.5.5-dev) C:\Users\satoo\Desktop\opencv\modules\dnn\src\tensorflow\tf_importer.cpp:2923: error: (-215:Assertion failed) const_layers.insert(std::make_pair(name, li)).second in function 'cv::dnn::dnn4_v20211220::`anonymous-namespace'::addConstNodes'

Unfortunately I cannot point to a solution to this problem, but I found a similar error posted in an OpenCV Issues. https://github.com/opencv/opencv/issues?q=addConstNodes

. Test Script:

using OpenCVForUnity.CoreModule;
using OpenCVForUnity.DnnModule;
using OpenCVForUnity.UnityUtils;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Issue143_TF_ModelTest : MonoBehaviour {

    protected string model_filepath;
    protected string config_filepath;

    protected List<string> outBlobNames;
    protected List<string> outBlobTypes;

    // Use this for initialization
    void Start () {

        //if true, The error log of the Native side OpenCV will be displayed on the Unity Editor Console.
        Utils.setDebugMode(true);

        model_filepath = Utils.getFilePath("dnn/test/" + "classify.pb");
        config_filepath = Utils.getFilePath("dnn/test/" + "classify.pbtxt");
        Net net = Dnn.readNetFromTensorflow(model_filepath, config_filepath);

        outBlobNames = getOutputsNames(net);
        for (int i = 0; i < outBlobNames.Count; i++)
        {
            Debug.Log("names [" + i + "] " + outBlobNames[i]);
        }

        outBlobTypes = getOutputsTypes(net);
        for (int i = 0; i < outBlobTypes.Count; i++)
        {
            Debug.Log("types [" + i + "] " + outBlobTypes[i]);
        }

        Utils.setDebugMode(false);
    }

    // Update is called once per frame
    void Update () {

    }

    /// <summary>
    /// Gets the outputs names.
    /// </summary>
    /// <returns>The outputs names.</returns>
    /// <param name="net">Net.</param>
    protected virtual List<string> getOutputsNames(Net net)
    {
        List<string> names = new List<string>();

        MatOfInt outLayers = net.getUnconnectedOutLayers();
        for (int i = 0; i < outLayers.total(); ++i)
        {
            names.Add(net.getLayer(new DictValue((int)outLayers.get(i, 0)[0])).get_name());
        }
        outLayers.Dispose();

        return names;
    }

    /// <summary>
    /// Gets the outputs types.
    /// </summary>
    /// <returns>The outputs types.</returns>
    /// <param name="net">Net.</param>
    protected virtual List<string> getOutputsTypes(Net net)
    {
        List<string> types = new List<string>();

        MatOfInt outLayers = net.getUnconnectedOutLayers();
        for (int i = 0; i < outLayers.total(); ++i)
        {
            types.Add(net.getLayer(new DictValue((int)outLayers.get(i, 0)[0])).get_type());
        }
        outLayers.Dispose();

        return types;
    }
}
Tigran1983 commented 2 years ago

Thank you for quick response. I couldn't find solution to this problem, I guess problem is in some layers, which couldn't be frozen and then couldn't be read by opencvforunity, or may be problem is in tensorflow supported versions.

I am closing an issue.

Regards, Tigran