faster R-CNN中anchors 的生成過程代碼

import numpy as np


def _whctrs(anchor):
    """
    將 anchor 四個座標的形式 轉化成 (寬,高,中心點橫座標,中心點縱座標)的形式
    Return width, height, x center, and y center for an anchor (window).
    """
    w = anchor[2] - anchor[0] + 1   # 寬   圖像座標 從 0開始;
    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):
    """
    針對 一個anchor
    將 (寬,高,中心點橫座標,中心點縱座標) 的形式 轉化成 四個座標值的形式
    :return:
    """
    left = x_ctr - (ws - 1) * 0.5
    top = y_ctr - (hs - 1) * 0.5

    right = x_ctr + (ws - 1) * 0.5
    bottom = y_ctr + (hs - 1) * 0.5

    return [left, top, right, bottom]  # 四個座標的形式


def _mkanchors_list(ws, hs, x_ctr, y_ctr):
    """
    :param ws: list
    :param hs: list
    :param x_ctr: float
    :param y_ctr: float
    :return:
    """
    anchors_list = []
    for i in range(len(ws)):
        anchors_list.append(_mkanchors(ws[i], hs[i], x_ctr, y_ctr))

    return np.array(anchors_list)


def _scale_enum(anchor, scales):
    """
    針對的 是 一個 anchor
    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_list(ws, hs, x_ctr, y_ctr)

    return anchors


def _ratio_enum(anchor=np.array([0, 0, 15, 15]), ratios=[0.5, 1, 2]):
    """
    :param anchor: base anchor 座標 左上角 座標, 右下角座標 形式;
    :param ratios:
    :return:
    """
    w = anchor[-2] - anchor[0] + 1
    h = anchor[-1] - anchor[1] + 1
    print(w, h)
    anchor_size = w * h  # 256    # anchor 長寬比(aspect ratio) 變換方法
    size_ratio = anchor_size / ratios   # [512. 256. 128.]
    # print(size_ratio)
    # size 開方 求的 三種比例的 寬度, 然後在按比例 求的 高度
    ws = np.round(np.sqrt(size_ratio))   # [23. 16. 11.]
    # print(ws)
    hs = np.round(ws * ratios)   # [12. 16. 22.]
    # print(hs)
    # 預測窗口(四個座標)
    # 返回窗口座標(左上角座標, 右下角座標)

    # 按比例變換之後, 上下角座標 就變了,要計算 原來的中心點座標, 再根據 原來中心座標計算 上下角座標;
    w, h, x_ctr, y_ctr = _whctrs(anchor)
    anchors = _mkanchors_list(ws, hs, x_ctr, y_ctr)  # 根據中心點座標,計算 左上角 和 右下角座標;
    print("_ratio_enum anchors")
    print(anchors)
    return anchors


def generate_anchors1(base_size=16, ratios=[0.5, 1, 2], scales=2 ** np.arange(3, 6)):
    base_anchor = np.array([1, 1, base_size, base_size]) - 1   # top left bottom right
    print(base_anchor)   # [ 0  0 15 15]     座標(0, 0), 長寬(16, 16)
    print(type(base_anchor))
    """
    aspect ratio 長寬比 變換 3個; base_anchor, ratios
    """

    ratio_anchors = _ratio_enum(base_anchor, ratios)  # 一個變換成 3個   數組(3, 4)
    print("anchors after ratio \n", ratio_anchors)

    anchors = np.vstack([_scale_enum(ratio_anchors[i, :], scales) for i in range(ratio_anchors.shape[0])])
    print("achors after ration and scale \n", anchors)
    return anchors


if __name__ == '__main__':
    import time
    t = time.time()
    a = generate_anchors1()
    print(time.time() - t)
    # print(a)

參考自:faster R-CNN中anchors 的生成過程(generate_anchors源碼解析)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章