程序问答   发布时间:2022-06-02  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了使用从 PyTorch 转换的相同 ONNX 模型,OpenCV 两次崩溃一次大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如何解决使用从 PyTorch 转换的相同 ONNX 模型,OpenCV 两次崩溃一次?

开发过程中遇到使用从 PyTorch 转换的相同 ONNX 模型,OpenCV 两次崩溃一次的问题如何解决?下面主要结合日常开发的经验,给出你关于使用从 PyTorch 转换的相同 ONNX 模型,OpenCV 两次崩溃一次的解决方法建议,希望对你解决使用从 PyTorch 转换的相同 ONNX 模型,OpenCV 两次崩溃一次有所启发或帮助;

我的配置:

  • windows 10
  • Python 3.9
  • Pytorch 1.8.1
  • 火炬视觉 0.9.1
  • Onnx 1.9.0
  • OpenCV 4.5.2 (C++)

我将 PyTorch 模型转换为 ONNX 并使用 OpenCV 加载它。

file_onnx = './r2p1d18.onnx'

my_model=torchvision.models.vIDeo.r2plus1d_18(preTrained=True,progress=falsE)
my_model.to(torch.device('cpu'))
my_model.eval()

dummy_input = torch.randn(1,3,16,112,requires_grad=falsE)

torch.onnx._export(my_model,dummy_input,file_onnx,Training=false,export_params=True,verbose=True
              )

导出似乎没问题(没有错误日志,用 Netron 目视检查模型)然后我将它与 OpenCV 一起使用:

voID test_so()
{
    std::string f_classes("../models/action_recognition.txt");
    std::string f_vIDeo("e:/divx/snowboard.mkv");
    
    //std::string f_onnx("../models/resnet-34_kinetics.onnx"); // OK
    //std::string f_onnx("../models/r3d18.onnx"); // NOT OK
    std::string f_onnx("../models/r2p1d18.onnx"); // NOT OK

    vector<String>v_classes;
    std::ifstream ifs(f_classes);
    std::string line;
    while (std::getline(ifs,linE))
    {
        v_classes.push_BACk(linE);
    }

    Net net = readNetFromONNX(std::string(f_onnX));
    //net.setPreferableTarget(DNN_TARGET_CUDA);
    //net.setPreferableBACkend(DNN_BACKEND_CUDA);
    net.setPreferableTarget(DNN_TARGET_cpu);
    net.setPreferableBACkend(DNN_BACKEND_OPENCV);

    VIDeoCapture cap(f_vIDeo);

    int sample_duration = 16;
    int sample_size = 112;

    vector<Mat>v_frames;
    
    // only the first sample used for the example
    for (int i = 0; i < sample_duration; i++)
    {
        Mat frame,frame_resized,frame_f;
        cap >> frame;
        resize(frame,Size(sample_size,sample_sizE));
        frame_resized.convertTo(frame_f,CV_32FC3);
        v_frames.push_BACk(frame_f);
    }
    
    //Mat blob = blobFromImages(v_frames,1.0/255.0,Size(112,112),(0.485,0.456,0.406),true,false,CV_32F);
    Mat blob = blobFromImages(v_frames,1.0,(114.7748,107.7354,99.4750),CV_32F);

    // rearrange matrix to fit in the model
    int sz[] = { 1,blob.size[1],blob.size[0],blob.size[2],blob.size[3] };
    Mat newblob = Mat(5,sz,CV_32F,blob.ptr<float>(0));

    net.seTinput(newblob);
    cout << "Fwd... " << endl;
    Mat score = net.forWARD();
    cout << "Done." << endl;

    Point pmin,pmax;
    double vmin,vmax;
    minMaxLoc(score,&vmin,&vmax,&pmin,&pmaX);
    cout << "Action : " << v_classes[pmax.x] << endl;
}

然后,我使用相同的 onnx 文件和相同的视频文件多次启动相同的 exe,我得到随机不同的结果:

Fwd...
OpenCV: terminate handler is called! The last OpenCV error is:
OpenCV(4.5.2) Error: Assertion Failed (srcMat.dims == 2 && srcMat.cols == weights.cols &&
dstMat.rows == srcMat.rows && dstMat.cols == weights.rows && srcMat.type() == weights.type() && 
weights.type() == dstMat.type() && srcMat.type() == CV_32F && (biasmat.empty() || (biasmat.type()
== srcMat.type() && biasmat.isConTinuous() && (int)biasmat.@R_50_10586@l() == dstMat.cols))) in 
cv::dnn::FullyConnectedLayerImpl::FullyConnected::run,file E:\Develop\opencv-4.5.2\modules
\dnn\src\layers\fully_connected_layer.cpp,line 180

或:

Fwd...
OpenCV: terminate handler is called! The last OpenCV error is:
OpenCV(4.5.2) Error: Assertion Failed (@R_50_10586@l(os[i]) > 0) in 
cv::dnn::dnn4_v20210301::Net::Impl::getLayerShapesRecursively,file E:\Develop\opencv-4.5.2\modules\dnn\src\dnn.cpp,line 3534

有时,一切都好(不管班级好不好):

Fwd...
Done
score : 1 lines,400 cols
Action : drawing

我已经用 ONNX 格式提供的另一个模型(resnet34-kinetics)测试了 OpenCV 代码,它运行良好,所以我怀疑是转换部分。

我还测试了转换更简单的模型(超分辨率)并将其与 openCV 一起使用(当然不是使用相同的代码),效果很好。

在转换为 ONNX 期间,我尝试了一些选项(requires_grad=True),并在 OpenCV 中尝试指定输入和输出层名称,但这不会改变任何行为。

我是这个领域的初学者,所以我忘记了什么,代码有什么问题,或者视频模型有什么特别之处吗? 最重要的是,我不明白的是:为什么它有时会起作用,而当它不起作用时,为什么错误并不总是相同的?

预先感谢您的帮助

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

大佬总结

以上是大佬教程为你收集整理的使用从 PyTorch 转换的相同 ONNX 模型,OpenCV 两次崩溃一次全部内容,希望文章能够帮你解决使用从 PyTorch 转换的相同 ONNX 模型,OpenCV 两次崩溃一次所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。