Faster R-CNN代码学习(二)——utils模块

Faster R-CNN代码学习(二)——utils模块

主要学习了lib文件夹下的utils模块,这部分模块的主要作用是提供一些工具类函数,包括NMS、图片预处理以及IoU计算函数等。

NMS(非极大抑制)

NMS的原理就是在同一类的框中,根据scores来进行去除冗余框的计算。

import numpy as np
def nms(dets, thresh):
    # 输入一系列具有相同类别的坐标和得分
    # dets (N, 5)
    x1 = dets[:, 0]
    y1 = dets[:, 1]
    x2 = dets[:, 2]
    y2 = dets[:, 3]
    
    scores = dets[:, 4]
    order = np.argsort(scores)[::-1]  # 从大到小排列的index
    
    keep = []  # 返回的index
    while order.size > 0:
        i = order[0] # order剩余的里面得分最高的index
        keep.append(i)
        # 下面的坐标计算跟IoU计算相同,x2、y2取min,x1、y1取max
        xx1 = np.maximum(x1[i], x1[order[1:]])
        yy1 = np.maximum(y1[i], y1[order[1:]])
        xx2 = np.minimum(x2[i], x2[order[1:]])
        yy2 = np.minimum(y2[i], y2[order[1:]])
        
        iw = np.maximum(0.0, xx2 - xx1)
        ih = np.maximum(0.0, yy2 - yy1)
        
        ovr = (iw * ih) / (areas[i] + areas[order[1:]] - iw * ih)
        inds = np.where(ovr <= thresh)[0] # IoU小于thresh的index保留
        order = order[inds + 1] # 由于ovr比order少1个元素,因此index + 1
    return keep

IoU计算

这部分用来计算两个box_list之间的IoU,如果维度分别为(M, D)和(N, D),则返回一个(M, N)的矩阵,矩阵内元素的值为IoU。

cimport cython  # 用cython来写的
import numpy as np
cimport numpy as np

DTYPE = np.float
ctypedef np.float_t DTYPE_t

def bbox_overlaps(
        np.ndarray[DTYPE_t, ndim=2] boxes
        np.ndarray[DTYPE_t, ndim=2] query_boxes):
        cdef unsigned int N = boxes.shape[0]
        cdef unsigned int K = query_boxes.shape[0]
        cdef np.ndarray[DTYPE_t, ndim=2] overlaps = np.zeros((N, K), dtype=DTYPE)
        cdef DTYPE_t iw, ih, box_area
        cdef DTYPE_t ua
        cdef unsigned int k, n
        for k in range(K):
            for n in range(N):
                iw = (
                    min(boxes[n, 2], query_boxes[0, 2] -
                    max(boxes[n, 0], query_boxes[n, 2] + 1
                )
                if iw > 0:
                    ih = (
                    min(boxes[n, 3], query_boxes[0, 3] -
                    max(boxes[n, 1], query_boxes[n, 1] + 1
                    )
                    if ih > 0:
                        query_box_area = (
                            (query_boxes[k, 2] - query_boxes[k, 0] + 1) *
                            (query_boxes[k, 3] - query_boxes[k, 1] + 1)
                        )
                        box_area = (
                            (boxes[k, 2] - boxes[k, 0] + 1) *
                            (boxes[k, 3] - boxes[k, 1] + 1)
                        )
                        ua = query_box_area + box_area - ih * iw  # 并面积
                        overlaps[n, k] = ih * iw / ua

        return overlaps

image预处理函数

image预处理的函数包含在blob.py文件中,主要包含了两个函数,第一个函数的功能是将一系列的image三维矩阵合并为一个(N, W, H, 3)的矩阵。

import cv2
import numpy as np
def im_list_to_blob(ims):
    num_image = len(ims)
    max_shape = np.array([im.shape for im in ims]).max(axis=0)  # 获取这些图片中最大的长和宽
    blob = np.zeros((num_image, max_shape[0], max_shape[1], 3), dtype=np.float32)
    
    for i in range(num_image):
        im = ims[i]
        blob[i, 0:im.shape[0], 0:im.shape[1], 3] = im
    return blob

第二个函数的功能是将图片进行均一化处理并缩放到目标尺寸,来为形成blob做准备。使用的函数是cv2.resize(args)

def pre_im_for_blob(im, pixel_means, target_size, max_size):
    im = im.astype(np.float32, copy=Fasle)
    im -= pixel_means
    im_shape = im.shape
    im_size_min = np.min(im_shape[0:2])
    im_size_max = np.max(im_shape[0:2])
    # 缩放是让其中一个边达到target_size,同时要保证长边不能超出max_size
    im_scale = float(target_size) / float(im_size_min)
    if np.round(im_scale * im_size_max) > max_size:
        im_scale = float(max_size) / float(im_size_max)
    im = cv2.resize(im, fx=im_scale, fy=im_scale, interpolation=cv2.INTER_LINEAR)
    return im, im_scale

有待理解

对于作者给出的boxes_grid.py,暂时没明白是干什么的,可能看了后面的代码能理解它的意义,这部分后面再补充。

猜你喜欢

转载自blog.csdn.net/LHaoRax/article/details/88845784