linux下QT工程调用opencv、libtorch,并用cmake编译:
文章目录
一、新建QT工程
新建QT工程,因为需要用cmake编译代码,因此本工程就吧.pro和usrpro文件去掉了。
工程目录下新建build的文件夹,并新建CMakelists.txt文件。
工程下的目录结构如下:
--build文件夹
--CMakeLists.txt
--CMakeLists.txt.user
--main.cpp
--mainwindow.cpp
--mainwindow.h
--mainwindow.ui
二、编写CMakeLists.txt文件
我的CMakeLists.txt文件内容如下:
cmake_minimum_required(VERSION 2.8.11 FATAL_ERROR)
project(helloworld)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
set(CMAKE_PREFIX_PATH /home/xxx/Qt5.9.5/5.9.5/gcc_64/lib/cmake/Qt5)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON)
find_package(Qt5 COMPONENTS Widgets Gui Core REQUIRED)
set(Torch_DIR /home/xxx/software/libtorch/share/cmake/Torch)
find_package(Torch REQUIRED)
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS} ${TORCH_INCLUDE_DIRS})
add_executable(helloworld main.cpp mainwindow.cpp mainwindow.h mainwindow.ui)
target_link_libraries(helloworld Qt5::Core)
target_link_libraries(helloworld Qt5::Widgets)
target_link_libraries(helloworld Qt5::Gui)
target_link_libraries(helloworld ${OpenCV_LIBS} ${TORCH_LIBRARIES})
set_property(TARGET helloworld PROPERTY CXX_STANDARD 14)
注意:请把以上涉及到绝对路径的设置,改为自己的文件路径。
三、各个文件的内容如下:
以下界面设计和代码实现,比较简单,只是为了测试 QT工程下调用opencv和libtorch,并用cmake编译。
1、mainwindow.ui的设置如下:
简单实现:输入R半径,点击count按钮,在eara处输出面积,并在viewLabel处一起显示图像。
界面简单设计。
2、mainwindow.cpp内容如下:
#include <torch/script.h>
#include <torch/torch.h>
#include "mainwindow.h"
#include "ui_mainwindow.h"
// #undef errno
#include <iostream>
// #include "torch/script.h"
// #include "torch/torch.h"
#include <complex>
#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgcodecs.hpp"
#include <opencv2/imgproc/types_c.h>
#include <vector>
#include <QImage>
const static double PI=3.1416;
//using namespace cv;
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_countButton_clicked()
{
bool ok;
QString tempStr;
QString valueStr=ui->radiusLineEdit->text();
int valueInt=valueStr.toInt(&ok);
double area=valueInt*valueInt*PI;
/* 配置参数 */
std::vector <float> mean_ = {0.485, 0.456, 0.406};
std::vector <float> std_ = {0.229, 0.224, 0.225};
char path[] = "1.jpg";
// 读取图片
cv::Mat image = cv::imread(path);
if (image.empty())
fprintf(stderr, "Can not load image\n");
转换通道,
cv::cvtColor(image, image, CV_BGR2RGB);
cv::Mat img_float;
image.convertTo(img_float, CV_32F, 1.0 / 255);
// resize, 测试一个点数据
cv::resize(img_float, img_float, cv::Size(256, 128));
std::cout << img_float.at<cv::Vec3f>(256, 128)[1] << std::endl;
// 转换成tensor
auto img_tensor = torch::from_blob(img_float.data, {1, 3, 256, 128}, torch::kFloat32);
//img_tensor = img_tensor.permute({0,3,1,2});
// tensor标准化
for (int i = 0; i < 3; i++) {
img_tensor[0][0] = img_tensor[0][0].sub_(mean_[i]).div_(std_[i]);
}
//cv::imshow("1", image);
// cv::waitKey(0);
cv::Mat temp;
QImage Qtemp;
cvtColor(image, temp, CV_BGR2RGB);//BGR convert to RGB
Qtemp = QImage((const unsigned char*)(temp.data), temp.cols, temp.rows, temp.step, QImage::Format_RGB888);
ui->viewLabel->setPixmap(QPixmap::fromImage(Qtemp));
ui->viewLabel->resize(Qtemp.size());
ui->viewLabel->show();
ui->areaLabel_2->setText(tempStr.setNum(area));
}
3、mainwindow.h内容如下:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_countButton_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
4、main.cpp内容如下:
#include "mainwindow.h"
#include <QApplication>
#include <QLabel>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
//QLabel label("hello world!");
// label.show();
MainWindow w;
w.show();
// Dialog w;
// w.show();
return a.exec();
}
5、用cmake编译,进入工程目录下执行命令:
cd build
cmake ..
make
./helloworld
如果正常的话会出现如下界面:
6、在执行make中出现一下问题:
问题一、
xxx@xxx-Precision-5820-Tower-X-Series:~/vsProjects/qtProjects/helloword/build$ make
Scanning dependencies of target helloworld_automoc
[ 20%] Automatic moc, uic and rcc for target helloworld
Generating ui_mainwindow.h
Generating moc_mainwindow.cpp
[ 20%] Built target helloworld_automoc
Scanning dependencies of target helloworld
[ 40%] Building CXX object CMakeFiles/helloworld.dir/main.cpp.o
[ 60%] Building CXX object CMakeFiles/helloworld.dir/mainwindow.cpp.o
In file included from /home/xxx/software/libtorch/include/ATen/core/ivalue.h:1138:0,
from /home/xxx/software/libtorch/include/ATen/record_function.h:3,
from /home/xxx/software/libtorch/include/ATen/Dispatch.h:5,
from /home/xxx/software/libtorch/include/ATen/ATen.h:13,
from /home/xxx/software/libtorch/include/torch/csrc/api/include/torch/types.h:3,
from /home/xxx/software/libtorch/include/torch/script.h:3,
from /home/xxx/vsProjects/qtProjects/helloword/mainwindow.cpp:20:
/home/xxx/software/libtorch/include/ATen/core/ivalue_inl.h:647:36: error: expected unqualified-id before ‘)’ token
const std::vector<IValue>& slots() const {
^
/home/xxx/software/libtorch/include/ATen/core/ivalue_inl.h:647:36: error: expected ‘;’ at end of member declaration
/home/xxx/software/libtorch/include/ATen/core/ivalue_inl.h:647:44: error: expected unqualified-id before ‘{’ token
const std::vector<IValue>& slots() const {
^
In file included from /home/xxx/software/libtorch/include/c10/core/DeviceType.h:8:0,
from /home/xxx/software/libtorch/include/c10/core/Device.h:3,
from /home/xxx/software/libtorch/include/c10/core/Allocator.h:6,
from /home/xxx/software/libtorch/include/ATen/ATen.h:7,
from /home/xxx/software/libtorch/include/torch/csrc/api/include/torch/types.h:3,
from /home/xxx/software/libtorch/include/torch/script.h:3,
from /home/xxx/vsProjects/qtProjects/helloword/mainwindow.cpp:20:
/home/xxx/software/libtorch/include/ATen/core/ivalue_inl.h: In member function ‘c10::intrusive_ptr<T> c10::IValue::toCustomClass() &&’:
/home/xxx/software/libtorch/include/ATen/core/ivalue_inl.h:834:3: error: expected unqualified-id before ‘(’ token
TORCH_CHECK(
^
/home/xxx/software/libtorch/include/ATen/core/ivalue_inl.h: In member function ‘c10::intrusive_ptr<T> c10::IValue::toCustomClass() const &’:
/home/xxx/software/libtorch/include/ATen/core/ivalue_inl.h:852:3: error: expected unqualified-id before ‘(’ token
TORCH_CHECK(
^
In file included from /home/xxx/software/libtorch/include/torch/csrc/jit/frontend/tracer.h:9:0,
from /home/xxx/software/libtorch/include/torch/csrc/autograd/generated/variable_factories.h:12,
from /home/xxx/software/libtorch/include/torch/csrc/api/include/torch/types.h:7,
from /home/xxx/software/libtorch/include/torch/script.h:3,
from /home/xxx/vsProjects/qtProjects/helloword/mainwindow.cpp:20:
/home/xxx/software/libtorch/include/torch/csrc/jit/api/object.h: In member function ‘size_t torch::jit::Object::num_slots() const’:
/home/xxx/software/libtorch/include/torch/csrc/jit/api/object.h:129:28: error: expected unqualified-id before ‘(’ token
return _ivalue()->slots().size();
^
CMakeFiles/helloworld.dir/build.make:86: recipe for target 'CMakeFiles/helloworld.dir/mainwindow.cpp.o' failed
make[2]: *** [CMakeFiles/helloworld.dir/mainwindow.cpp.o] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/helloworld.dir/all' failed
make[1]: *** [CMakeFiles/helloworld.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2
网上相关的一些方法都尝试了,始终不行。后来参考此文档里面:
https://blog.csdn.net/qq_45662588/article/details/120541586
应该是头文件使用出现问题后经过尝试发现头文件的顺序不正确也会报错。
因此我把mainwindow.cpp下包含的libtorch的两个头文件放在所有头文件的最前面,再重新编译,成功通过。
#include <torch/script.h>
#include <torch/torch.h>
#include "mainwindow.h"
#include "ui_mainwindow.h"
// #undef errno
#include <iostream>
// #include "torch/script.h"
// #include "torch/torch.h"
#include <complex>
#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgcodecs.hpp"
#include <opencv2/imgproc/types_c.h>
#include <vector>
#include <QImage>
我原来是将#include "torch/script.h"和 #include "torch/torch.h"放在了中间位置,会报上面的错误,我将两个头文件放在最前面就没有报错了。
问题二:
之前还出现过:
Failed to compute shorthash for libnvrtc.so
参考https://blog.csdn.net/xzq1207105685/article/details/117400187的方法,
在CMakeList.txt开头添加:
find_package(PythonInterp REQUIRED)
添加后,再执行cmake …和make,就没有报错这个错误了。
后来又去掉了这句话,也没有报错了。有些奇怪,反正没有错误就好了。
问题三:
是之前我写的文章里提到的:
/helloword/build$ ./helloworld
./helloworld: /lib/x86_64-linux-gnu/libz.so.1: version `ZLIB_1.2.9' not found (required by /home/cpe/anaconda3/lib/libpng16.so.16)
遇到的问题,已经在https://blog.csdn.net/shoukequ8359/article/details/121679024?spm=1001.2014.3001.5501给出了解决方法。即:下载 wget http://www.zlib.net/fossils/zlib-1.2.9.tar.gz,编译安装,并复制libz.so.1和libz.so.1.2.9到我的目录x86_64-linux-gnu下,即可解决问题。