首頁>技術>

出處:https://mp.weixin.qq.com/s?__biz=MzIyNjM2MzQyNg==&mid=2247545057&idx=1&sn=047d56cb0a01d87a1056dd437791247e

本文講解了目標檢測的基本概念, 分析了實現目標檢測的常用思路。下一篇將 介紹目標檢測經典資料集—VOC資料集的基本資訊,和對VOC資料集進行處理的方法。

一、目標檢測基本概念1. 什麼是目標檢測

目標檢測是計算機視覺中的一個重要任務,近年來傳統目標檢測方法已經難以滿足人們對目標檢測效果的要求,隨著深度學習在計算機視覺任務上取得的巨大進展,目前基於深度學習的目標檢測演算法已經成為主流。

相比較於基於深度學習的影象分類任務,目標檢測任務更具難度,具體區別如下圖所示。

影象分類:只需要判斷輸入的影象中是否包含感興趣物體。

目標檢測:需要在識別出圖片中目標類別的基礎上,還要精確定位到目標的具體位置,並用外接矩形框標出。

分類和目標檢測任務示意圖

2. 目標檢測常用思路

自2012年Alex Krizhevsky憑藉Alex在ImageNet影象分類挑戰賽中拿下冠軍之後,深度學習在影象識別尤其是影象分類領域開始大放異彩,大眾的視野也重新回到深度神經網路中。緊接著,不斷有更深更復雜的網路出現,一再重新整理ImageNet影象分類比賽的記錄。

大家發現,透過合理的構造,神經網路可以用來預測各種各樣的實際問題。於是人們開始了基於CNN的目標檢測研究, 但是隨著進一步的探索大家發現,似乎CNN並不善於直接預測座標資訊。並且一幅影象中可能出現的物體個數也是不定的,模型如何構建也比較棘手。

因此,人們就想,如果知道了圖中某個位置存在物體,再將對應的區域性區域送入到分類網路中去進行判別,那我不就可以知道影象中每個物體的位置和類別了嗎?

但是,怎麼樣才能知道每個物體的位置呢?顯然我們是沒辦法知道的,但是我們可以去猜啊!所謂猜,其實就是透過滑窗的方式,羅列圖中各種可能的區域,一個個去試,分別送入到分類網路進行分類得到其類別,同時我們會對當前的邊界框進行微調,這樣對於影象中每個區域都能得到(class,x1,y1,x2,y2)五個屬性,彙總後最終就得到了圖中物體的類別和座標資訊。

總結一下我們的這種方案思路:先確立眾多候選框,再對候選框進行分類和微調。

觀察下圖,更形象的理解下這種思想:

從分類角度去看目標檢測

3. 目標框定義方式

任何影象任務的訓練資料都要包括兩項,圖片和真實標籤資訊,通常叫做GT。

影象分類中,標籤資訊是類別。目標檢測的標籤資訊除了類別label以外,需要同時包含目標的位置資訊,也就是目標的外接矩形框bounding box。

用來表達bbox的格式通常有兩種,(x1, y1, x2, y2) 和 (c_x, c_y, w, h) ,如圖所示:

目標框定義方式

之所以使用兩種不同的目標框資訊表達格式,是因為兩種格式會分別在後續不同場景下更加便於計算。

兩種格式互相轉換的實現在utils.py中,程式碼也非常簡單:

def xy_to_cxcy(xy):    """    Convert bounding boxes from boundary coordinates (x_min, y_min, x_max, y_max) to center-size coordinates (c_x, c_y, w, h).    :param xy: bounding boxes in boundary coordinates, a tensor of size (n_boxes, 4)    :return: bounding boxes in center-size coordinates, a tensor of size (n_boxes, 4)    """    return torch.cat([(xy[:, 2:] + xy[:, :2]) / 2,  # c_x, c_y                      xy[:, 2:] - xy[:, :2]], 1)  # w, hdef cxcy_to_xy(cxcy):    """    Convert bounding boxes from center-size coordinates (c_x, c_y, w, h) to boundary coordinates (x_min, y_min, x_max, y_max).    :param cxcy: bounding boxes in center-size coordinates, a tensor of size (n_boxes, 4)    :return: bounding boxes in boundary coordinates, a tensor of size (n_boxes, 4)    """    return torch.cat([cxcy[:, :2] - (cxcy[:, 2:] / 2),  # x_min, y_min                      cxcy[:, :2] + (cxcy[:, 2:] / 2)], 1)  # x_max, y_max

用torch.cat()將兩個形狀為(n,2)的tensor在第一維度拼接成(n,4)。

4. 交併比(IoU)

在目標檢測任務中,關於IOU的計算貫穿整個模型的訓練測試和評價過程,是非常非常重要的一個概念,其目的是用來衡量兩個目標框的重疊程度。

IoU的全稱是交併比(Intersection over Union),表示兩個目標框的交集佔其並集的比例。下圖為IOU計算示意圖:

IOU計算示意圖

圖中可以看到,分子中黃色區域為紅bbox和綠bbox的交集,分母中黃+紅+綠區域為紅bbox和綠bbox的並集,兩者之比即為iou。

那麼具體怎麼去計算呢?這裡給出計算流程的簡述:

首先獲取兩個框的座標,紅框座標: 左上(red_x1, red_y1), 右下(red_x2, red_y2),綠框座標: 左上(green_x1, green_y1),右下(green_x2, green_y2)計算兩個框左上點的座標最大值:(max(red_x1, green_x1), max(red_y1, green_y1)), 和右下點座標最小值:(min(red_x2, green_x2), min(red_y2, green_y2))利用2算出的資訊計算黃框面積:yellow_area計算紅綠框的面積:red_area 和 green_areaiou = yellow_area / (red_area + green_area - yellow_area)

如果文字表述的不夠清晰,就再看下程式碼:

def find_intersection(set_1, set_2):    """     Find the intersection of every box combination between two sets of boxes that are in boundary coordinates.    :param set_1: set 1, a tensor of dimensions (n1, 4)                                                                                                               :param set_2: set 2, a tensor of dimensions (n2, 4)    :return: intersection of each of the boxes in set 1 with respect to each of the boxes in set 2, a tensor of dimensions (n1, n2)    """    # PyTorch auto-broadcasts singleton dimensions    lower_bounds = torch.max(set_1[:, :2].unsqueeze(1), set_2[:, :2].unsqueeze(0))  # (n1, n2, 2)    upper_bounds = torch.min(set_1[:, 2:].unsqueeze(1), set_2[:, 2:].unsqueeze(0))  # (n1, n2, 2)    intersection_dims = torch.clamp(upper_bounds - lower_bounds, min=0)  # (n1, n2, 2)    return intersection_dims[:, :, 0] * intersection_dims[:, :, 1]  # (n1, n2)def find_jaccard_overlap(set_1, set_2):    """     Find the Jaccard Overlap (IoU) of every box combination between two sets of boxes that are in boundary coordinates.    :param set_1: set 1, a tensor of dimensions (n1, 4)    :param set_2: set 2, a tensor of dimensions (n2, 4)    :return: Jaccard Overlap of each of the boxes in set 1 with respect to each of the boxes in set 2, a tensor of dimensions (n1, n2)    """    # Find intersections    intersection = find_intersection(set_1, set_2)  # (n1, n2)    # Find areas of each box in both sets    areas_set_1 = (set_1[:, 2] - set_1[:, 0]) * (set_1[:, 3] - set_1[:, 1])  # (n1)    areas_set_2 = (set_2[:, 2] - set_2[:, 0]) * (set_2[:, 3] - set_2[:, 1])  # (n2)    # Find the union    # PyTorch auto-broadcasts singleton dimensions    union = areas_set_1.unsqueeze(1) + areas_set_2.unsqueeze(0) - intersection  # (n1, n2)    return intersection / union  # (n1, n2)

以上程式碼位於utils.py指令碼的find_intersection和find_jaccard_overlap。

函式 find_intersection find_intersection(set_1, set_2) 是求形狀為 (n1,4) 和 (n2,4) 的boxes的交集的面積。 set_1[:, :2] 的形狀為(n1,2),後面加上 .unsqueeze(1) ,形狀變為(n1,1,2)。同理 set_2[:, :2].unsqueeze(0) ,形狀為(1,n2,2)。(n1,1,2)和(1,n2,2),作了torch.max,有廣播存在,(n1,1,2)變成(n1,n2,2) ,(1,n2,2)也變成(n1,n2,2)。因此得到了形狀為(n1,n2,2)的框的左上角座標 那個2 就是儲存了x1,y1。torch.clamp() 是將函式限制在最大值和最小值範圍內,如果超過就變成那個最大值或者最小值。這裡min=0,意思是如果面積小於0,那麼面積取0(排除異常)。函式 find_jaccard_overlap 計算iou,交集/並集,最後union計算, 升維 (n1)->(n1,1) 、 (n2)->(1,n2) 、 接下去相加,廣播成(n1,n2),減去一個(n1,n2)的交集面積,得到並集面積。5. 小結

本小節首先介紹了目標檢測的問題背景,隨後分析了一個實現目標檢測的解決思路,這也是眾多經典檢測網路所採用的思路(即先確立眾多候選框,再對候選框進行分類和微調)。最後介紹了bbox和IoU這兩個目標檢測相關的基本概念。

出處:https://mp.weixin.qq.com/s?__biz=MzIyNjM2MzQyNg==&mid=2247545057&idx=1&sn=047d56cb0a01d87a1056dd437791247e

18
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • “易語言”基礎知識——變數的有效範圍