2024-09-01
C/C++
00

目录

基本环境
Ubuntu安装Opencv
从源码安装opencv-4.x
从源码安装opencv-3.x
直接pkg包安装
freetype支持
CLion工程cmake文件写法
Opencv demo
MNN
mnn文档
在Ubuntu编译MNN
CLion中使用

基本环境

(1)安装WSL;

(2)安装cmake:

sh
wget https://github.com/Kitware/CMake/releases/download/v3.20.0/cmake-3.20.0-linux-x86_64.tar.gz tar -xzvf cmake-3.20.0-linux-x86_64.tar.gz sudo ln -sf $(pwd)/cmake-3.20.0-linux-x86_64/bin/* /usr/bin/

(3)安装gcc++:

sh
# 如果 Ubuntu 版本 < 18.04,需要加入仓库 sudo add-apt-repository ppa:ubuntu-toolchain-r/test sudo apt-get update sudo apt-get install gcc sudo apt-get install g++

(4)安装GDB:

sh
sudo apt install gdb

(5)clion建立空工程后选择toolchains如下:

在这里插入图片描述

Ubuntu安装Opencv

从源码安装opencv-4.x

依赖:

sh
sudo apt install build-essential cmake git pkg-config libgtk-3-dev \ libavcodec-dev libavformat-dev libswscale-dev libv4l-dev \ libxvidcore-dev libx264-dev libjpeg-dev libpng-dev libtiff-dev \ gfortran openexr libatlas-base-dev python3-dev python3-numpy \ libtbb2 libtbb-dev libdc1394-22-dev libopenexr-dev \ libgstreamer-plugins-base1.0-dev libgstreamer1.0-dev

去github下载最新包:https://github.com/opencv/opencv.git

或者去官网下载 一个版本:https://opencv.org/releases/

sh
cd opencv-4.x mkdir -p build && cd build cmake -D CMAKE_BUILD_TYPE=RELEASE .. make -j8 sudo make install

从源码安装opencv-3.x

方法同opencv-4.x,但安装路径有区别,得注意。

直接pkg包安装

不想编译也ok,直接:

sh
sudo apt-get install -y libopencv-dev

freetype支持

https://cloud.tencent.com/developer/article/1353734

CLion工程cmake文件写法

c
# 声明要求的 cmake 最低版本 cmake_minimum_required( VERSION 3.8 ) # 声明一个 cmake 工程 project( cpptest ) # 设置编译模式 set( CMAKE_BUILD_TYPE "Debug" ) #set(OpenCV_DIR "/usr/local/share/OpenCV") set(OpenCV_DIR "/usr/local/share/opencv4") # 给一个安装路径 find_package( OpenCV REQUIRED ) # 找包 #添加OpenCV头文件 include_directories(${OpenCV_INCLUDE_DIRS}) message(STATUS "OpenCV_INCLUDE_DIRS: ${OpenCV_INCLUDE_DIRS}") message(STATUS "OpenCV_LIBS: ${OpenCV_LIBS}") # 添加一个可执行程序 # 语法:add_executable( 程序名 源代码文件 ) add_executable( cpptest main.cpp) # 将库文件链接到可执行程序上 target_link_libraries( cpptest ${OpenCV_LIBS})

Opencv demo

c++
#include <iostream> #include<opencv2/opencv.hpp>//opencv简单程序标配头文件 using namespace cv;//使用cv命名空间 int main() { Mat src=imread("/mnt/c/Users/kevin/Desktop/img.png");//读取图片,要提前将图片放在程序路径下 imwrite("/mnt/c/Users/kevin/Desktop/img2.jpg",src);//保存结果图片 return 0; }

在这里插入图片描述

MNN

mnn文档

https://mnn-docs.readthedocs.io/en/latest/compile/engine.html

在Ubuntu编译MNN

sh
sudo apt install protobuf-compiler # 下载mnn源码后: cd schema && ./generate.sh mkdir -p build && cd build cmake -DMNN_BUILD_CONVERTER=ON -DCMAKE_BUILD_TYPE=Release .. make -j8 sudo make install

安装成功:

sh
[100%] Built target OnnxClip Install the project... -- Install configuration: "Release" -- Installing: /usr/local/include/MNN/MNNDefine.h -- Installing: /usr/local/include/MNN/Interpreter.hpp -- Installing: /usr/local/include/MNN/HalideRuntime.h -- Installing: /usr/local/include/MNN/Tensor.hpp -- Installing: /usr/local/include/MNN/ErrorCode.hpp -- Installing: /usr/local/include/MNN/ImageProcess.hpp -- Installing: /usr/local/include/MNN/Matrix.h -- Installing: /usr/local/include/MNN/Rect.h -- Installing: /usr/local/include/MNN/MNNForwardType.h -- Installing: /usr/local/include/MNN/AutoTime.hpp -- Installing: /usr/local/include/MNN/MNNSharedContext.h -- Installing: /usr/local/include/MNN/expr/Expr.hpp -- Installing: /usr/local/include/MNN/expr/ExprCreator.hpp -- Installing: /usr/local/include/MNN/expr/MathOp.hpp -- Installing: /usr/local/include/MNN/expr/NeuralNetWorkOp.hpp -- Installing: /usr/local/include/MNN/expr/Optimizer.hpp -- Installing: /usr/local/include/MNN/expr/Executor.hpp -- Installing: /usr/local/include/MNN/expr/Module.hpp -- Up-to-date: /usr/local/include/MNN/expr/NeuralNetWorkOp.hpp -- Installing: /usr/local/include/MNN/expr/ExecutorScope.hpp -- Installing: /usr/local/include/MNN/expr/Scope.hpp -- Installing: /usr/local/lib/libMNN.so -- Installing: /usr/local/lib/libMNN_Express.so -- Set runtime path of "/usr/local/lib/libMNN_Express.so" to ""

CLion中使用

CmakeList.txt:

c
# 声明要求的 cmake 最低版本 cmake_minimum_required( VERSION 3.8 ) # 声明一个 cmake 工程 project( cpptest ) # 设置编译模式 set( CMAKE_BUILD_TYPE "Debug" ) set(OpenCV_DIR "/usr/local/share/opencv4") # 给一个安装路径 find_package( OpenCV REQUIRED ) # 找包 if (OpenCV_FOUND) # If the package has been found, several variables will # be set, you can find the full list with descriptions # in the OpenCVConfig.cmake file. # Print some message showing some of them message(STATUS "OpenCV library status:") message(STATUS " version: ${OpenCV_VERSION}") message(STATUS " include path: ${OpenCV_INCLUDE_DIRS}") else () message(FATAL_ERROR "Could not locate OpenCV") endif() #添加OpenCV头文件 include_directories(${OpenCV_INCLUDE_DIRS}) set(lib_DIR /usr/local/lib) include_directories(/usr/local/include) add_library(MNN SHARED IMPORTED) set_target_properties( MNN PROPERTIES IMPORTED_LOCATION ${lib_DIR}/libMNN.so ) #include 是头文件 src是c代码 include_directories( ${CMAKE_SOURCE_DIR}/include ) message(STATUS "CMAKE_SOURCE_DIR : ${CMAKE_SOURCE_DIR}") aux_source_directory( ${CMAKE_SOURCE_DIR}/src DIR_SRCS) message(STATUS "DIR_SRCS: ${DIR_SRCS}") # 添加一个可执行程序 add_executable( cpptest main.cpp ${DIR_SRCS}) # 将库文件链接到可执行程序上 target_link_libraries( cpptest MNN ${OpenCV_LIBS} )

main.cpp:

cpp
#include <iostream> #include <string> #include <MNN/Interpreter.hpp> #include <opencv2/opencv.hpp> #include <iostream> #include "Yolo.h" using namespace MNN; int main() { const char *model_name = "/mnt/d/cpp_ptoject/cpptest/checkpoints/yolov7-tiny416.mnn"; std::shared_ptr<Interpreter> net(Interpreter::createFromFile(model_name)); ScheduleConfig config; config.type = MNN_FORWARD_AUTO; Session *pSession = net->createSession(config); Tensor *ptensorInput = net->getSessionInput(pSession, NULL); std::vector<int> vctInputDims = ptensorInput->shape(); printf("输入Tensor的维度为: "); for (size_t i = 0; i < vctInputDims.size(); ++i) { printf("%d ", vctInputDims[i]); } printf("\n"); // opencv 读取数据,resize操作,减均值, 除方差,并且转成nchw cv::Mat matImg = cv::imread("/mnt/d/cpp_ptoject/cpptest/doc/bus.jpg", cv::IMREAD_COLOR); assert(matImg.data != NULL); cv::Mat matFloatImage; int MODEL_INPUT_HEIGHT = 416; int MODEL_INPUT_WIDTH = 416; float r; int dw, dh; letterbox(matImg, matFloatImage, MODEL_INPUT_WIDTH, MODEL_INPUT_HEIGHT, cv::Scalar(114, 114, 114), false, true, 32, r, dw, dh); cv::cvtColor(matFloatImage, matFloatImage, cv::COLOR_BGR2RGB); matFloatImage.convertTo(matFloatImage, CV_32FC3); cv::Mat matStd(MODEL_INPUT_HEIGHT, MODEL_INPUT_WIDTH, CV_32FC3, cv::Scalar(255.0f, 255.0f, 255.0f)); cv::Mat matMean(MODEL_INPUT_HEIGHT, MODEL_INPUT_WIDTH, CV_32FC3, cv::Scalar(0.0f, 0.0f, 0.0f)); // 均值 cv::Mat matNormImage = (matFloatImage - matMean) / matStd; std::vector<std::vector<cv::Mat>> nChannels; std::vector<cv::Mat> rgbChannels(3); cv::split(matNormImage, rgbChannels); nChannels.push_back(rgbChannels); // NHWC 转NCHW void *pvData = malloc(1 * 3 * MODEL_INPUT_HEIGHT * MODEL_INPUT_WIDTH * sizeof(float)); int nPlaneSize = MODEL_INPUT_HEIGHT * MODEL_INPUT_WIDTH; for (int c = 0; c < 3; ++c) { cv::Mat matPlane = nChannels[0][c]; memcpy((float *) (pvData) + c * nPlaneSize, \ matPlane.data, nPlaneSize * sizeof(float)); } // 将数据拷贝到Tensor中 auto nchwTensor = new Tensor(ptensorInput, Tensor::CAFFE); ::memcpy(nchwTensor->host<float>(), pvData, nPlaneSize * 3 * sizeof(float)); ptensorInput->copyFromHostTensor(nchwTensor); delete nchwTensor; // 获取输出Tensor Tensor *pTensorOutput = net->getSessionOutput(pSession, NULL); // 执行推理 net->runSession(pSession); // 获取输出维度类型 auto dimType = pTensorOutput->getDimensionType(); if (pTensorOutput->getType().code != halide_type_float) { dimType = Tensor::CAFFE; } // 创建输出tensor std::shared_ptr<Tensor> outputUser(new Tensor(pTensorOutput, dimType)); MNN_PRINT("output size:%d\n", outputUser->elementSize()); // 拷贝出去 pTensorOutput->copyToHostTensor(outputUser.get()); auto type = outputUser->getType(); auto size = outputUser->elementSize(); //100行*7列 std::vector<std::vector<float>> tempValues; if (type.code == halide_type_float) { auto values = outputUser->host<float>(); for (int i = 0; i < size; i += 7) { std::vector<float> temp; if (values[i + 6] < 0.1) { break; } for (int j = 0; j < 7; j++) { temp.push_back(values[i + j]); } tempValues.push_back(temp); } } drawResultImage(matImg, tempValues, r, dw, dh); cv::imwrite("/mnt/d/cpp_ptoject/cpptest/doc/bus_out.jpg", matImg); // 释放我们创建的数据内存,这个不是tensor里的 if (NULL != pvData) { free(pvData); pvData = NULL; } std::cout << "finish " << std::endl; return 0; }

项目样子:

在这里插入图片描述

如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay

本文作者:Dong

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC。本作品采用《知识共享署名-非商业性使用 4.0 国际许可协议》进行许可。您可以在非商业用途下自由转载和修改,但必须注明出处并提供原作者链接。 许可协议。转载请注明出处!