在海思AI芯片(Hi3519A/3559A)方案学习(十四)JPEG图片转换成bgr文件 中,有提到如何将jpeg文件转换为bgr格式数据,然后再输入到NNIE模型进行目标识别。但是在jpeg图片转换中,是先将原始图像直接resize成模型网络size,如下红框所示。
加入说待识别的输入图片size是1200x800,而我们的模型网络size是600x600,那么如果长、宽按都按2:1比例缩小的话,图片应该resize成600x400。但事实上,高度缩小比是800/600=4/3 < 2。 这种不等比例的缩放会导致图像变形。就这个例子而言,因为高度方向缩小比小些,会使得图像上的目标被拉长了。 这里大家脑补一下吧,我就不画图了。
另外, 当输入图片size为800x1200,类似的,直接resize成600x600后,图像上目标会显得拉宽了。
以图像较大的边为基准,宽高方向上 等比例缩放到网络size,并对小边方向上进行适当填充,以保证方放缩后的图像size和网络size相等。代码实现如下。
Mat img = imread("D:/work/xxxx.jpg"); if (img.empty()) { printf("reading image file fails \n"); return 1; } int net_w, net_h; net_w = 416; net_h = 416; #if 0 Mat box; resize(img, box, Size(net_w, net_h)); #else //resize int new_w, new_h; if (((float)net_w / img.cols) < ((float)net_h / img.rows)) { new_w = net_w; new_h = (img.rows * new_w) / img.cols; } else { new_h = net_h; new_w = (img.cols * net_h) / img.rows; } Mat resized; cv::resize(img, resized, Size(new_w, new_h)); Mat box = Mat(Size(net_w, net_h), CV_MAKETYPE(CV_8U, img.channels()), Scalar::all(127)); Mat roi(box, Rect((net_w - new_w) >> 1, (net_h - new_h) >> 1, new_w, new_h)); resized.copyTo(roi);以两种放缩方式在3519A上进行仿真推理,其结果示意图如下。左图(仔细看,狗被拉长了)是直接resize的识别结果;右图是等比例缩放,由于小边高度缩的比较多,所以上下进行了填充。显然,右边的结果要好一些。