私のコンピュータの構成についてまず話、ubuntu16.04; opencv3.4.3は、アナコンダによりv1.0.1デベロッパーよりも、新しいAPIを使用する必要がある場合(C ++のコードを使用してトーチの異なるバージョンが、異なる内部torch1.3.1をインストールそうでない場合、あなたは)古いを使用する必要があります。cuda10.0; cudnn7.6.5。
ネットワークのセマンティックセグメンテーションは、ここで使用されます:DSPNet V2 ; pytorchベースの開発、私ができるPyTorch 1.0、1.3をサポートしています。リアルタイムセマンティックセグメンテーションを実現することができ、非常に高速、私のコンピュータの実行segnetすることができ、私のコンピュータは、唯一15msの1つのニーズを取り扱う、384 * 384のサイズに画像のサイズを変更します(このネットワークは、同じ目標物体の検出と分類を達成することができます)これは、60ミリ秒/フレーム、および2つの同様の精度を必要とします。マイコンピュータグラフィックスGTX1650です。
次に、モデルにC ++環境でのセマンティックセグメンテーションを使用する方法について事前に訓練を受けたかについて話しています。
ファイルに1 .pth .ptファイル
必要なときに、元のネットワーク定義のソースコード生成モデルの内側を見、segmentation_demo.pyが付属していますgithubの上のコードを、ダウンロードした後、このデモの写真は、セマンティックセグメンテーションをカタログsample_imagesで完了することができsegmentation_resultsディレクトリに保存され、また、パラメータの引数を渡す必要があり、いくつかのネットワークは、ソースコードを参照するには、特定の必要性を達成するためにパラメータを渡す必要はありません。
まず、Tieshanglaiコード(完全ここからダウンロードすることができますの掲載部分のみ):
model = ESPNetv2Segmentation(args).to(device='cuda')#将模型加载到相应的设备中。有的可能不需要传递参数
#model = espnetv2_seg(args)
model.load_state_dict(torch.load('./model/segmentation/model_zoo/espnetv2/espnetv2_s_2.0_pascal_384x384.pth', map_location='cuda'))
model.eval()
example = torch.Tensor(1, 3, 384, 384).cuda()
out = model(example)
print_info_message(out.size())
traced_script_module = torch.jit.trace(model, example)#这句话执行时会有warning,没有事
traced_script_module.save("espnetv2_s_2.0_pascal_384x384.pt")
print_info_message('Done')
あなたは上記のプログラムを実行すると長すぎない、完全なコードの内部のTieshanglaiを意味し、特定の上記の引数は、次の警告が表示されることがあります。
長い時間のための警告Googleは私が解決する方法を知りませんでしたが、彼は.ptファイル生成された結果に影響を与えませんでした。このモデルは、GPU上で訓練されているため、着信テンソルは.cuda()、加えて、得られたモデルは、GPUに置かれるべきであるGPU上に配置するように。他のネットワークが接近し、実装し、元のネットワーク、または着信パラメータを見てみましょうする必要性が、その後、事前研修モデルがでてくるというコードを見つけるランダムテンソルを与え、その後、.ptファイルを生成する以上は何も類似してはなりません。
2.C ++(libtorch)搭載モデル、完全なセマンティックセグメンテーション
我々は最初のpythonセマンティックセグメンテーション内のデモを使用する方法を理解しなければならないので、誰もが同じネットワーク、インターネット上の多くではない情報はないので、私は、長い間研究してきたこの1は、実装は、多少異なる場合があります。
一般的な手順は以下のとおりです。まず、リード・パラメータに基づいてモデルを作成します
model = espnetv2_seg(args)#将各种参数传入
そして、事前研修のパラメータをロードします。
weight_dict = torch.load(args.weights_test, map_location=torch.device('cuda'))
model.load_state_dict(weight_dict)
その後、読み取られた画像、及び画像処理の一連含む、リサイズサイズ、BGRは、RGBから、画像は、テンソルに変換する正規化、及び、出力テンソルを得るためにモデルを通過し、numpyのに変換しました、写真、応答サイズ、画像の色に変換RGB、保存に変換し、それゆえ、我々のC ++プログラムは、最初の標識cmakelistsを同様の手順に従わなければなりませんで
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
project(example-app)
SET(CMAKE_BUILD_TYPE Release)
MESSAGE("Build type: " ${CMAKE_BUILD_TYPE})
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -O3 -march=native ")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -O3 -march=native")
#set( CMAKE_CXX_FLAGS "-std=c++11 -O3" )
#Check C++11 or C++0x support
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
if(COMPILER_SUPPORTS_CXX11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
add_definitions(-DCOMPILEDWITHC11)
message(STATUS "Using flag -std=c++11.")
elseif(COMPILER_SUPPORTS_CXX0X)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
add_definitions(-DCOMPILEDWITHC0X)
message(STATUS "Using flag -std=c++0x.")
else()
message(FATAL_ERROR "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
endif()
if( TORCH_PATH )
message("TORCH_PATH set to: ${TORCH_PATH}")
set(Torch_DIR ${TORCH_PATH})
else()
message(FATAL_ERROR "Need to specify Torch path, e.g., pytorch/torch/share/cmake/Torch ")
endif()
find_package(OpenCV 3.4.3 REQUIRED)
find_package(Torch REQUIRED)
message(STATUS "Torch version is: ${Torch_VERSION}")
if(Torch_VERSION GREATER 1.0.1)
message(STATUS "Torch version is newer than v1.0.1, will use new api")
add_definitions(-DTORCH_NEW_API) #TORCH_NEW_API这个变量在代码中被检测是否定义,因为不同版本的一些功能的使用方法不一样
endif()
add_executable(example-app example-app.cpp)
target_link_libraries(example-app ${TORCH_LIBRARIES} ${OpenCV_LIBS})
set_property(TARGET example-app PROPERTY CXX_STANDARD 11)
add_executable(example-c example-c.cpp)
target_link_libraries(example-c ${TORCH_LIBRARIES} ${OpenCV_LIBS})
set_property(TARGET example-c PROPERTY CXX_STANDARD 11)
build.sh
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DTORCH_PATH=/home/azs/anaconda3/lib/python3.6/site-packages/torch/share/cmake/Torch #使用anaconda里面的pytorch
make -j8
あなたが作成すると、環境変数の設定TORCH_PATHに応じてcmakeのファイルのトーチを見つけます。
ここで私は2つのプログラムが、画像データを読み取ることができる例-app.cppは、セマンティックセグメンテーションのために継続的に複数の画像を有効にする、フォルダ内TUMを設定書いた、例-c.cppは、単一の画像ですセマンティックセグメンテーション。一例として、単一のコードで:
#include <torch/torch.h>
#include <iostream>
#include "torch/script.h"
#include "torch/torch.h"
#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgcodecs.hpp"
#include <vector>
#include <chrono>
#include <string>
#include <vector>
using namespace std;
//上色
void Visualization(cv::Mat prediction_map, std::string LUT_file) {
cv::cvtColor(prediction_map.clone(), prediction_map, CV_GRAY2BGR);
cv::Mat label_colours = cv::imread(LUT_file,1);
cv::cvtColor(label_colours, label_colours, CV_RGB2BGR);
cv::Mat output_image;
LUT(prediction_map, label_colours, output_image);
cv::imshow( "Display window", output_image);
}
//对图片首先进行处理,返回张量
torch::Tensor process( cv::Mat& image,torch::Device device,int img_size)
{
cv::imshow("test1",image);
//首先对输入的图片进行处理
cv::cvtColor(image, image, CV_BGR2RGB);// bgr -> rgb
cv::Mat img_float;
// image.convertTo(img_float, CV_32F, 1.0 / 255);//归一化到[0,1]区间,
cv::resize(image, img_float, cv::Size(img_size, img_size));
std::vector<int64_t> dims = {1, img_size, img_size, 3};
#if defined(TORCH_NEW_API) //根据编译结果选择执行哪一段
torch::Tensor img_var = torch::from_blob(img_float.data, dims, torch::kByte).to(device);//将图像转化成张量
#else
//下面这两句只有使用老版本的时候才用
torch::Tensor img_tensor = torch::CPU(torch::kFloat32).tensorFromBlob(img_float.data, dims);
torch::Tensor img_var = torch::autograd::make_variable(img_tensor, false).to(device);//创建图像变量
#endif
img_var = img_var.permute({0,3,1,2});//将张量的参数顺序转化为 torch输入的格式 1,3,384,384
img_var = img_var.toType(torch::kFloat);
img_var = img_var.div(255);
return img_var;
}
int main() {
char path[] = "../h2.png";
int img_size = 384;
std::string LUT_file="../pascal.png";
//设置device类型
torch::DeviceType device_type;
device_type = torch::kCUDA;
torch::Device device(device_type);
std::cout<<"cudu support:"<< (torch::cuda::is_available()?"ture":"false")<<std::endl;
//读取模型
//新版本
torch::jit::script::Module module= torch::jit::load("../espnetv2_s_2.0_pascal_384x384.pt");
//老版本,老版本的module是指针,使用->,新版本是对象,使用.
//std::shared_ptr<torch::jit::script::Module> module = torch::jit::load("../espnetv2_s_2.0_pascal_384x384.pt");
module.to(device);
// 读取图片
cv::Mat image = cv::imread(path,cv::ImreadModes::IMREAD_COLOR);
//对图片进行处理,得到张量
torch::Tensor img_var=process(image,device,img_size);
std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now();
torch::Tensor result = module.forward({img_var}).toTensor(); //前向传播获取结果,还是tensor类型
std::chrono::steady_clock::time_point t2 = std::chrono::steady_clock::now();
std::cout << "Processing time = " << (std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count())/1000000.0 << " sec" <<std::endl;
result=result.argmax(1);//找出每个点概率最大的一个
result = result.squeeze();//删除一个维度
result = result.to(torch::kU8);//.mul(100)这里是为了让分割的区域更明显,但是不需要加,因为后面使用了lut的方法可以使不同的mask显示不同颜色
result=result.to(torch::kCPU);
cv::Mat pts_mat(cv::Size(384,384), CV_8U, result.data_ptr());//新建一个矩阵,用于保存数据,将tensor的数据转移到这里面
//cv::imshow("test",pts_mat);//这个图是灰度图
Visualization(pts_mat,LUT_file);//上色
cv::waitKey(0);
return 0;
}
ノートは内側に、最終的な業績に書き込まれます。
オリジナル:
結果:
あなたは例-app.cppこのプログラムを実行すると、以下のように、時間の結果は以下のとおりです。
あなたは、処理時間が14ms程度ほとんどで見ることができます。
私のコードをダウンロード
参考カタログ:
https://blog.csdn.net/pplxlee/article/details/90445316
https://blog.csdn.net/u010397980/article/details/89437628
https://blog.csdn.net/IAMoldpan/article/details/85057238
https://www.cnblogs.com/geoffreyone/p/10827010.html
https://www.jianshu.com/p/aee6a3d72014
https://www.jianshu.com/p/7cddc09ca7a4
编译遇到的一些问题参考:
https://www.jianshu.com/p/186bcdfe9492