Bootstrap

VS 2019配置QT和Opencv调用DNN模块进行图像分类

前言

最近学习了一点点C++知识,想巩固一下之前的知识。

一、开发环境

1.1 软件

  • Pycharm
  • Visual Studio 2019
  • QT 5.12
  • Opencv 4.6.0

1.2 Python所需库

  • Pytorch
  • torchvision

二、VS 2019 环境的配置

2.1 VS 2019 配置opencv 4.6.0

《VS2019中配置OpenCv4.5.5,保姆级教程》.

2.2 VS 2019配置QT 5.12

《vs2019配置Qt5开发环境》.

三、数据集的介绍

在这里插入图片描述

  • 数据来源

    • 数据集影像来源于美国国家地质调查局(USGS)国家地图城市地区影像集合(National Map Urban Area Imagery)中的大影像的手动提取,图像用于全国各地的城市地区。
  • 数据集介绍

    • 数据类别:共21类,包含农业区域、飞机、棒球场、海滩、建筑群、丛林、密集住宅、森林、高速公路、高尔夫球场、港口、交叉路口、中心住宅、移动住房公园、立交桥、停车场、河流、跑道、稀疏住宅、储油罐和网球场。
  • 图像尺寸

    • 256×256像元。
  • 像素分辨率

    • 1英尺。
  • 数据集规模

    • 每类100张影像样本,共2100张影像。
  • 下载地址

四、设计原理

设计流程如下:
在这里插入图片描述

  1. 训练网络:卷积网络的使用的是何凯明大神团队的的ResNet,框架使用的是FaceBook的Pytorch。
  2. 模型保存为便于部署的ONNX(开放神经网络交换格式,Open Neural Network Exchange)模型。
  3. 界面设计使用的QT。
  4. 模型载入使用的是Opencv中的DNN模块。

五、结果展示

六、核心代码

6.1 模型保存为ONNX文件

# 导出网络到ONNX
dummy_input = torch.randn(1, 3, 256, 256).to(device)
torch.onnx.export(net, dummy_input, "torch.onnx")

6.2 打开图片所在文件夹并获得路径

QString OpenFile, OpenFilePath;
QImage image;
//打开文件夹中的图片文件
OpenFile = QFileDialog::getOpenFileName(this,
	"Please choose an image file",
	"./val",
	"Image Files(*.jpg *.png *.tif *.pgm *.pbm);;All(*.*)");
if (OpenFile != "")
{
	if (image.load(OpenFile))
	{
		ui.label->setPixmap(QPixmap::fromImage(image));
	}
}

//显示所示图片的路径
QFileInfo OpenFileInfo;
OpenFileInfo = QFileInfo(OpenFile);
OpenFilePath = OpenFileInfo.filePath();//图片所在路径
ui.lineEdit_1->setText(OpenFilePath.split("/")[8]);//获得图片名称

6.3 模型的载入与图片初始化

String modelFile = "./torch.onnx";
String imageFile = OpenFilePath.toStdString();
dnn::Net net = cv::dnn::readNetFromONNX(modelFile); //读取网络和参数
Mat image1 = imread(imageFile); // 读取测试图片
cv::cvtColor(image1, image1, cv::COLOR_BGR2RGB);
Mat inputBolb = blobFromImage(image1, 0.00390625f, Size(256, 256), Scalar(), false, false); //将图像转化为正确输入格式
net.setInput(inputBolb); //输入图像
Mat result = net.forward().reshape(1, 1); //前向计算

6.4 标签的定义与结果的获取

map<int, string> dict{
        {0 , "agricultural"},
        {1 , "airplane"},
        {2 , "baseballdiamond"},
        {3 , "beach"},
        {4 , "buildings"},
        {5 , "chaparral"},
        {6 , "denseresidential"},
        {7 , "forest"},
        {8 , "freeway"},
        {9 , "golfcourse"},
        {10 , "harbor"},
        {11 , "intersection"},
        {12 , "mediumresidential"},
        {13 , "mobilehomepark"},
        {14 , "overpass"},
        {15 , "parkinglot"},
        {16 , "river"},
        {17 , "runway"},
        {18 , "sparseresidential"},
        {19 , "storagetanks"},
        {20 , "tenniscourt"} };  // 定义一个 map 类型数据 相当于Python中的字典
double minValue, maxValue;    // 最大值,最小值
Point  minIdx, maxIdx;    // 最小值坐标,最大值坐标 
minMaxLoc(result, &minValue, &maxValue, &minIdx, &maxIdx);
QString QS = QString::fromStdString(dict[maxIdx.x]);//将cv::String转为QString
ui.lineEdit->setText(QS);

七、总结与不足

  • 初步将VS 2019、Opencv、QT和深度学习联系在一起,对遥感图像进行分类。
  • 在VS 2019进行分类时,发现准确率并没有达到训练时准确率。怀疑是图像问题,遂上网查了查.tif图片文件共有24个通道,这波是大意了。因为只是做一个例子玩玩。今后可能会查阅相关知识进行修改测试。
;