一、重复显示
1. 背景
- 首先使用openvino的模型转换命令得到模型
python3 /opt/intel/openvino/deployment_tools/model_optimizer/mo.py --input_model models/xxx.caffemodel
-
然后在super-resolution-demo里添加rgb转yuv的代码,使demo支持y通道输入,参考
-
然后将y通道输入结果显示出来,观察结果是否符合预期。
2. 问题描述
如下图所示,左侧为输入Y通道图片,经过openvino-super-resolution-demo跑出来的结果为右图,明显结果显示不正常
3. 分析思路
a. 输出原始数据与显示数据是否有差异
输出原始数据存放在outputData
里,由于计算是fp32,要显示出来需要转成CV_32FC1,再转成CV_8UC1,因此怀疑是否是转换的时候漏掉了参数。
cv::Mat output_y(h, w, CV_32FC1, &(outputData[i * nunOfPixels * numOfChannels]));
output_y.convertTo(output_y, CV_8UC1);
cv::imshow("yArImg", output_y);
b. 3通道正常,单通道异常
现象:
- 3通道输入输出的dbpn-caffe和官方给的模型,经过openvino可以将每个通道都正常显示
- ar两个版本的模型都无法正常显示,sr也不正常
猜测原因:
- openvino-demo对于单通道输出单通道输出的调用方式不对,或底层支持有问题
- 自研模型从cafe转换到openvino可能存在问题,要么是模型本身,要么是转换脚本本身
c. 模型转换有问题
- 用XXX的单通道模型+Official-demo,依然有问题,说明 模型转换本身应该没啥问题,应该是demo调用的方式不对。
- tf直接转成caffe模型,由于tf模型有两个输入,需要改demo里调用函数,过于麻烦,暂不考虑这一条路,且上一步基本证明不太可能是模型转换问题。
- 用caffe模型,控制输出节点,只转换一个conv,依然有问题,有可能是底层支持有问题,但底层调用opencv的前馈,出错概率很小
d. demo调用有问题
对比xxx的开源代码,排查demo的写法,发现xxx使用memmove进行内存拷贝,而非官方demo的matU8ToBlob,最后发现是内存拷贝的问题。
4. 结论
官方给的sample代码,提供的Mat内存拷贝到Blob的函数matU8ToBlob,对于三通道数据采用了Vec3b的方式去赋值,所以三通道会显示正常,给单通道后,就会出现1张图变三张的情况
二、一半黑色显示
1. 问题描述
2. 原因分析
上半部分黑色部分问题已解决,原因是我加的调试代码里,有一条语句:
memmove(input_data, yImg.data, (img.rows*img.cols)*sizeof(unsigned char));
跟demo里的内存拷贝matU8ToBlob<float_t>(yImg, lrInputBlob, i);
重复
完整语句是:
matU8ToBlob<float_t>(yImg, lrInputBlob, i);
memmove(input_data, yImg.data, (img.rows*img.cols)*sizeof(unsigned char));
相当于matU8ToBlob用yImg.data对input_data进行了一次赋值,调试代码memmove又进行了一次同样的操作。
3. 解决办法
删除memmove(input_data, yImg.data, (img.rows*img.cols)*sizeof(unsigned char));
三、 空白图片
1. 问题描述
输出图片一篇空白
2. 原因分析及结论
有些模型先对图片进行归一化,再送入网络,然后对输出采用img.convertTo(img, CV_8UC1, 255);
恢复到255的值域。
而自研模型本身不需要归一化,因此,将255改成1即可