大佬教程收集整理的这篇文章主要介绍了使用从 PyTorch 转换的相同 ONNX 模型,OpenCV 两次崩溃一次,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我的配置:
我将 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,请注明来意。