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源码解析)

你可能感兴趣的:(CV)