detectron程式碼理解(四):generate_anchors
阿新 • • 發佈:2018-12-01
def generate_anchors( stride=16, sizes=(32, 64, 128, 256, 512), aspect_ratios=(0.5, 1, 2) ): """Generates a matrix of anchor boxes in (x1, y1, x2, y2) format. Anchors are centered on stride / 2, have (approximate) sqrt areas of the specified sizes, and aspect ratios as given. #這裡的stride可以理解為元anchor的邊長(base_size) 產生anchor的原理是: (1)先對元anchor生成不同aspect_ratios下的base_anchors (2)再根據該層實際設計的anchor的sizes,將base_anchors進行擴大,擴大的倍數就是下面的:np.array(sizes, dtype=np.float) / stride """ return _generate_anchors( stride, np.array(sizes, dtype=np.float) / stride, np.array(aspect_ratios, dtype=np.float) ) def _generate_anchors(base_size, scales, aspect_ratios): """Generate anchor (reference) windows by enumerating aspect ratios X scales wrt a reference (0, 0, base_size - 1, base_size - 1) window. """ anchor = np.array([1, 1, base_size, base_size], dtype=np.float) - 1 #這個就是元anchor anchors = _ratio_enum(anchor, aspect_ratios) #根據aspect_ratios,對元anchor生成不同ratio下的base_anchors #根據該層實際設計的anchor的邊長size,以及size與stride的關係(size/stride =scales),將base_anchors的邊長乘以scales anchors = np.vstack( [_scale_enum(anchors[i, :], scales) for i in range(anchors.shape[0])] ) return anchors def _whctrs(anchor): """Return width, height, x center, and y center for an anchor (window).""" w = anchor[2] - anchor[0] + 1 h = anchor[3] - anchor[1] + 1 x_ctr = anchor[0] + 0.5 * (w - 1) y_ctr = anchor[1] + 0.5 * (h - 1) return w, h, x_ctr, y_ctr def _mkanchors(ws, hs, x_ctr, y_ctr): """Given a vector of widths (ws) and heights (hs) around a center (x_ctr, y_ctr), output a set of anchors (windows). """ ws = ws[:, np.newaxis] #由(3,)變為(3,1) hs = hs[:, np.newaxis] anchors = np.hstack( #hstack橫向拼接,保證行不變,列合併,所以是anchors的大小是(3,4) ( x_ctr - 0.5 * (ws - 1), #anchor左上角的x,大小為(3,1) y_ctr - 0.5 * (hs - 1), #anchor左上角的y,大小為(3,1) x_ctr + 0.5 * (ws - 1), #anchor右上角的x,大小為(3,1) y_ctr + 0.5 * (hs - 1) #anchor右上角的y,大小為(3,1) ) ) return anchors def _ratio_enum(anchor, ratios): """Enumerate a set of anchors for each aspect ratio wrt an anchor.""" w, h, x_ctr, y_ctr = _whctrs(anchor)#返回高寬以及中心 size = w * h #面積 #下面這三個是計算在面積相同情況固定長寬比下的長hs與寬ws size_ratios = size / ratios ws = np.round(np.sqrt(size_ratios)) hs = np.round(ws * ratios) anchors = _mkanchors(ws, hs, x_ctr, y_ctr) #根據求取的長寬和中心seanchor return anchors def _scale_enum(anchor, scales): """Enumerate a set of anchors for each scale wrt an anchor.""" w, h, x_ctr, y_ctr = _whctrs(anchor) ws = w * scales hs = h * scales anchors = _mkanchors(ws, hs, x_ctr, y_ctr) return anchors