1. 前言
yolov5-7.0版本繼續(xù)更新了實例分割的代碼,其分割的精度與速度令人驚訝,本文將yolov5-seg進行tensorrt加速,并利用矩陣的方法對進行部分后處理.
實例分割原理:yolact
yolov5seg-cpp實現(xiàn)代碼:Yolov5-instance-seg-tensorrt
cpp矩陣實現(xiàn):algorithm-cpp
本文測試代碼:https://github.com/Rex-LK/tensorrt_learning/tree/main/trt_cpp/src/trt/demo-infer/yolov5seg
歡迎正在學習或者想學的CV的同學進群一起討論與學習,v:Rex1586662742,q群:468713665
2. 實例分割結果
yolov5-seg的結果分為兩部分,一個是檢測的結果,維度為25200*177,前85列為每個檢測框結果,后32列為每個檢測框的mask系數(shù),另外一個是分割結果:原型mask,維度為32 * 160 * 160,實例分割的后處理就是將目標框里面的mask系數(shù)與原型mask進行加權求和,從而獲得實例分割的效果。
2.1 檢測結果后處理
通過置信度以及NMS可以挑選出最終的目標框,這個過程就不在過多的贅述了。
2.2 實例分割分割結果后處理
實例分割的后處理過程其實是一個矩陣相乘的過程,因此基于。。。實現(xiàn)cpp矩陣,在這里實現(xiàn)了后處理,原作者的代碼是用過利用opencv里面的Mat來表示一個矩陣,然后進行一些矩陣的操作,而本文實現(xiàn)在在自定義Matrix上進行矩陣操作。
// 原型mask 32 * 160 * 160
float *seg_det = seg_out->cpu<float>();
vector<float> mask(seg_det, seg_det + segChannels * segWidth * segHeight);
// 矩陣表示
Matrix seg_proto(segChannels, segWidth * segHeight, mask);
for (int i = 0; i < box_result.size(); ++i) {
// 可以將所有的mask系數(shù)放在一起,然后利用cuda進行加速計算
// 每個目標框的mask系數(shù) 乘以原型mask 并取sigmod
Matrix resSeg = (mygemm(box_result[i].mask_cofs,seg_proto).exp(-1) + 1.0).power(-1);
Mat resMat(resSeg.data_);
resMat = resMat.reshape(0,{segHeight,segWidth});
// 如果圖片預處理為直接resize,那么計算出來的resMat可以直接縮放回原圖,
// 如果是填充黑邊的resize,可以參考原代碼將原型mask恢復到原圖大小
resize(resMat, resMat, Size(INPUT_H,INPUT_W), INTER_NEAREST);
// 獲取原型mask里面目標框的區(qū)域
Rect temp_rect = box_result[i].box;
// 將目標框區(qū)域 大于0.5的值變?yōu)?55
cv::Mat binaryMat;
inRange(resMat(temp_rect), 0.5, 1, binaryMat);
box_result[i].boxMask = binaryMat;
// cv::imwrite(to_string(i) + "_.jpg", b);
}
下面為利用cpp實現(xiàn)的矩陣,可以實現(xiàn)一些簡單的矩陣運算。
class Matrix{
public:
Matrix();
Matrix(int rows, int cols, const std::initializer_list<float>& pdata={});
Matrix(int rows, int cols, const std::vector<float>&v);
const float& operator()(int irow, int icol)const {return data_[irow * cols_ + icol];}
float& operator()(int irow, int icol){return data_[irow * cols_ + icol];}
Matrix element_wise(const std::function<float(float)> &func) const;
Matrix operator*(const Matrix &value) const;
Matrix operator*(float value) const;
Matrix operator+(float value) const;
Matrix operator-(float value) const;
Matrix operator/(float value) const;
int rows() const{return rows_;}
int cols() const{return cols_;}
Matrix view(int rows, int cols) const;
Matrix power(float y) const;
float reduce_sum() const;
float* ptr() const{return (float*)data_.data();}
Matrix exp(float value);
public:
int rows_ = 0;
int cols_ = 0;
std::vector<float> data_;
};
3. 測試
下載本代碼
修改CMakeLists.txt 里面的cuda、tensorrt、protobuf路徑
修改main.cpp里面的路徑,修改yolov5seg.cu里面的模型路徑以及圖片路徑。
cd trt_cpp
mkdir build && cd biild
cmake … && make -j
./…/workspace/demo_infer
測試結果如下:文章來源:http://www.zghlxwxcb.cn/news/detail-431313.html
4. 總結
本次學習了yolov5實例分割的原理以及代碼,通過對比原理以及代碼的步驟,弄清楚了yolov5是如何實現(xiàn)實例的分割任務的,如果本文對各位有用,麻煩到github點個小star。文章來源地址http://www.zghlxwxcb.cn/news/detail-431313.html
到了這里,關于[CV學習筆記]tensorrt加速篇之yolov5seg 實例分割的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!