2013-04-29 60 views
11

我收集了我的圖像檢測器算法的結果。所以基本上我所做的是,從一組圖像中(大小爲320 x 480),我將運行一個64x128的滑動窗口,並且還可以使用多個預定義的比例。如何對滑動窗口對象檢測中的真陰性進行分類?

我明白:

  • 真陽性=當我的檢測窗口重疊(定義交叉點尺寸/形心內)與地面實況(註釋邊界框)
  • 誤報=當算法給出我積極的窗口,這是在grond真相之外。
  • False Negatives =當我沒有給出肯定的窗口時,而地面真實註釋表明存在一個對象。

但是True Negatives?這些真正的消極因素是我的分類器給我的負面結果嗎?這聽起來很奇怪,因爲我每次滑動一個小窗口(64x128)4個像素,並且我有大約8個不同的尺度用於檢測。如果我這樣做,那麼每張圖片都會有很多真實的負面信息。

或者我準備一套純粹的負面圖像(根本沒有任何物體/人),我只是通過滑動,如果在這些圖像中有一個或多個正面檢測,我會把它算作False否定,反之亦然?

下面是一個例子圖像(綠色rects作爲地面實況)

Example image, not real result

+3

對象檢測使用條款TP,FP和命中率。負面消息並沒有那麼多。 – William 2013-04-29 08:26:09

回答

1

我始終認爲,這四個方面,如下:

  • 假陰性;結果應該是積極的,但是是消極的。
  • 誤報;結果應該是消極的,但是是積極的。
  • 真正的;結果應該是積極的,並且是積極的。
  • 確實否定;結果應該是負面的,是負面的。

在你的情況,如果我理解正確,你試圖檢測圖像中是否有對象。因此,假陰性意味着有一個對象(結果應該是正數),但算法沒有檢測到它(因此返回負數)。真正的負面因素只是算法正確地說明它檢查的區域確實是而不是包含對象。

您可以選擇忽略負值,但可以使用這些值來進一步訓練算法(例如,使用查找兩者的算法,而不是將未識別的所有內容設置爲false)。

+0

請在這個幀中糾正我,FP = 2,TP = 3,FN = 1,TN = 0?那應該如何計算? – 2016-09-22 18:10:11

+0

我不完全明白你的意思是將數字分配給術語。 – Nallath 2016-09-26 13:09:41

+0

你讓我感到困惑,如果我不分配,我如何計算FPR或TPR來繪製roc曲線?我不知道我的計算是否正確。如果你知道任何方法,請分享。 – 2016-09-26 14:59:19

0

有一個很好的解釋here。在Wiki和here中解釋的F1分數有助於衡量成功。

enter image description here

我試圖寫一個計算F1值的函數:

/// <param name="realClasses">Class names that exists on the image. A class name may exists more than once.</param> 
    /// <param name="foundClasses">Predicted class names. A class name may exists more than once.</param> 
    private static void findPosNeg(List<string> realClasses, List<string> foundClasses, out int truePositive, out int falsePositive, out int falseNegative) 
    {    
     Dictionary<string, int> dicReal = new Dictionary<string, int>(StringComparer.InvariantCultureIgnoreCase); 
     Dictionary<string, int> dicFound = new Dictionary<string, int>(StringComparer.InvariantCultureIgnoreCase); 
     #region fill dictionaries 
     foreach (string className in realClasses) 
     { 
      if (!dicReal.ContainsKey(className)) 
       dicReal[className] = 1; 
      else 
       dicReal[className]++; 
     } 
     foreach (string className in foundClasses) 
     { 
      if (!dicFound.ContainsKey(className)) 
       dicFound[className] = 1; 
      else 
       dicFound[className]++; 
     } 
     #endregion 

     truePositive = 0; 
     falsePositive = 0; 
     falseNegative = 0; 
     foreach (string className in dicFound.Keys) 
     { 
      if (!dicReal.ContainsKey(className)) 
       falsePositive += dicFound[className]; 
      else 
      { 
       int found = dicFound[className]; 
       int real = dicReal[className]; 
       truePositive += Math.Min(found, real); 
       if (real > found) 
        falseNegative += real - found; 
       else if (found > real) 
        falsePositive += found - real; 
      } 
     } 
     foreach (string className in dicReal.Keys) 
      if (!dicFound.ContainsKey(className)) 
       falseNegative += dicReal[className]; 

    } 
    /// <summary> 
    /// Calculates F1Score ref:https://en.wikipedia.org/wiki/Precision_and_recall 
    /// </summary> 
    private static double calc_F1Score(int truePositive, int falsePositive, int falseNegative, out double precision, out double recall) 
    { 
     precision = (double)truePositive/((double)truePositive + (double)falsePositive); 
     recall = (double)truePositive/((double)truePositive + (double)falseNegative); 
     double div = (precision + recall); 
     return (div != 0d) ? 2d * precision * recall/div : 0d; 
    }