SSD原始碼解讀 prior box layer

2021-08-26 12:30:42 字數 3203 閱讀 1335

一直不是很理解檢測結果是怎麼出來的,學習最快的方法就是看原始碼啦,今天先從prior box層開始。

這層的作用就是對不同位置的每個特徵點產生不同大小的default box,這些box的大小、形狀由prototxt的prior_box_param來控制。隨便拿出乙個模型的prior box層來舉例:

name: "base_11_priorbox"

type: "priorbox"

bottom: "convndbackward91"

bottom: "data"

top: "base_11_priorbox"

prior_box_param }

然後就來看一下原始碼(caffe_root/src/caffe/layers/prior_box_layer.cpp):

#include 

#include

#include

#include

#include "caffe/layers/prior_box_layer.hpp"

namespace caffe

aspect_ratios_.clear();

// 預設加入正方形框

aspect_ratios_.push_back(1.);

flip_ = prior_box_param.flip();

// 從prototxt中讀取長寬比

for (int i = 0; i < prior_box_param.aspect_ratio_size(); ++i)

}if (!already_exist)

}} // 每個畫素的default box的數量

num_priors_ = aspect_ratios_.size() * min_sizes_.size();

// 如果有設定max_size,則測試數值正確後計數,表示最大正方形邊長(sqrt(min_size*max_size))

if (prior_box_param.max_size_size() > 0)

} clip_ = prior_box_param.clip();

if (prior_box_param.variance_size() > 1)

} else

if (prior_box_param.variance_size() == 1) else

// 設定尺寸,一般在prototxt中都不指定,所以預設指定為0

if (prior_box_param.has_img_h() || prior_box_param.has_img_w()) else

if (prior_box_param.has_img_size()) else

// 指定x和y方向的步長,否則預設為0,下面用除法求出縮放比例

if (prior_box_param.has_step_h() || prior_box_param.has_step_w()) else

if (prior_box_param.has_step()) else

// 指定偏移量,一般為0.5,做四捨五入處理,可以看下面用法來理解

offset_ = prior_box_param.offset();

}// 統計一下top的尺寸

template

void priorboxlayer::reshape(const

vector

*>& bottom,

const

vector

*>& top)

template

void priorboxlayer::forward_cpu(const

vector

*>& bottom,

const

vector

*>& top) else

// 指feature map和原圖的比例關係

float step_w, step_h;

if (step_w_ == 0 || step_h_ == 0) else

dtype* top_data = top[0]->mutable_cpu_data();

int dim = layer_height * layer_width * num_priors_ * 4;

int idx = 0;

// 把feature map上的點對映到原圖

for (int h = 0; h < layer_height; ++h)

// 這裡就用到了aspect_ratio引數了,表示長方形的框,可以指定各種比例

// rest of priors

for (int r = 0; r < aspect_ratios_.size(); ++r)

box_width = min_size_ * sqrt(ar);

box_height = min_size_ / sqrt(ar);

// xmin

top_data[idx++] = (center_x - box_width / 2.) / img_width;

// ymin

top_data[idx++] = (center_y - box_height / 2.) / img_height;

// xmax

top_data[idx++] = (center_x + box_width / 2.) / img_width;

// ymax

top_data[idx++] = (center_y + box_height / 2.) / img_height;}}

}} // 對框進行剪裁,不能越影象邊界

// clip the prior's coordidate such that it is within [0, 1]

if (clip_)

} // 看了一些解釋還是不是很懂,先貼上個人感覺講的不錯的解釋

// set the variance.

// 這一句得到的是特徵圖的height*width

top_data += top[0]->offset(0, 1);

if (variance_.size() == 1) else }}

}}}

instantiate_class(priorboxlayer);

register_layer_class(priorbox);

} // namespace caffe

ssd原始碼解析

1 preprocess for eval image預處理 1 tf image whitend rgb通道分別減去影象集統計的畫素均值。2 tf image.resize image 影象縮放成 300,300,3 2 ssd net 1 ssdnet 初始化功能。定義引數 feat layer...

0 SSD演算法原始碼解讀 anchor是如何生成的

ssd演算法中預設框的好壞是非常重要的,好的anchor降低回歸的難度,更容易訓練出更好的模型,下面我們根據pytorch 講講預設框是怎麼生成的,非常簡單,我對 做出必要的說明,希望可以幫助大家理解anchor。注意,以下 所有引數針對 ssd 512 512,至於ssd 300 300等其他大小...

openTLD 原始碼解讀

首先是run tld 在其次就是tldexample 最後到了初始化函式tldinit 第乙個比較關鍵的函式 bb scan 將影象網格化,將首先 scale 1.2.10 10 21 個規格 在每個規格上打網格 這個函式有乙個比較重要的方法 ntuples 就是重複 因為網格上的點很多點有相同的x...