2016-07-30 2 views
0

Есть ли функция OpenCV, которая может дать мне список всех локальных максимумов для гистограммы? Может быть, есть функция, которая позволяет мне указать минимальный пик/порог и рассказать мне булавки всех этих локальных максимумов выше этого порога.Функция определения всех локальных максимумов гистограммы

Если нет, есть функция, которая может сортировать бункеры с самого высокого (наиболее частого) до самого низкого (наименее частого). Затем я могу захватить все первые 20 или около того, и у меня есть 20 самых больших локальных максимумов.

ответ

0

AFAIK OpenCV не имеет такой функциональности, но возможно реализовать что-то подобное себе.

Для сортировки гистограмм вы можете использовать sortIdx, но в результате вы получите список самых больших ящиков, который отличается от локальных максимумов (они должны быть «окружены» меньшими значениями).

Для получения локальных максимумов вы можете сравнить каждый бин со своими соседями (2 в 1D корпусе). Бункер должен быть больше соседей с некоторым запасом, чтобы считаться локальным максимумом.

В зависимости от размера корзины вы можете фильтровать гистограмму до этого шага (например, сверните ее с гауссовым ядром), так как в противном случае вы получили бы слишком много этих максимумов, особенно для небольших размеров бункера. Если вы использовали гауссовское ядро ​​- это сигма будет относиться к размеру окрестности, в которой обнаруженные локальные максимумы являются «глобальными».

Как только вы обнаружите эти точки - вы можете выполнить немаксимальное подавление, чтобы заменить группы точек, которые находятся очень близко друг к другу вместе с одной точкой. Простой стратегией для этого было бы сортировать эти максимумы в соответствии с некоторыми критериями (например, разницу с соседями), затем взять один максимум и удалить все точки в его окрестности (его размер может быть связан с гауссовским сигмасом ядра), принять следующий оставшиеся максимумы и снова удаляйте точки в своей окрестности и так далее, пока не закончите очки или не опустите некоторые значащие значения разницы.

Наконец, вы можете отсортировать оставшиеся очки-кандидаты по их абсолютным значениям (получить «самые большие» локальные максимумы) или их разницу с соседями (получить «самые острые»).

Вы можете попробовать другой подход. Мы можем использовать определение локального максимума this для реализации более простого алгоритма: просто сдвиньте скользящее окно размера S вдоль гистограммы и выберите максимум в каждой позиции. Это будет иметь некоторые проблемы:

  • в местах с видными максимумом несколько позиций окна будет создавать точки, которые соответствуют одному и тому же максимуму (может быть исправлено с не максимальным подавлением),
  • в местах с отсутствием или малым изменением его по вернет полуслучайные максимумы (может быть установлен с пороговым значением по дисперсии в окне или разностью между максимумом и соседством),
  • в регионах с монотонной гистограммой он вернет наибольшее значение (что не обязательно является максимальным).

После того, как вы выполнили всю обработку «особого случая», эти два подхода были бы очень похожими, я считаю.

Еще одна вещь, которая может быть реализована, может быть «многомасштабным» подходом, который можно рассматривать как расширение, если они 2. В основном это сводится к обнаружению локальных максимумов для разных размеров соседства, а затем их хранение вместе с соответствующим размером окрестности , что может быть полезно для некоторых целей.

Как вы можете видеть, это довольно неопределенное руководство, и есть причина для этого: тип и количество локальных максим, которые вы хотите получить, скорее всего, будут зависеть от проблемы, о которой вы имеете в виду. Нет простого и легкого правила, чтобы решить, следует ли считать этот пункт локальным максимумом, поэтому вам следует начать с простого подхода, а затем уточнить его для вашего конкретного случая.

0

Opencv minMaxLoc можно использовать в этом контексте с раздвижным окном. Если местоположение максимумов находится на краю, то игнорируйте максимумы, в противном случае записывайте как максимумы. Вы можете использовать что-то вроде функции ниже (Примечание: этот код больше как psuedocode он не был проверен)

/** 
* Assumes a 1 channel histogram 
*/ 
vector<int> findMaxima(Mat histogram, int windowsize, int histbins){ 
    vector<int> maximas; 
    int lastmaxima; 
    for(int i = 0; i < histbins - windowsize; i++){ 
     //Just some Local variables, only maxloc and maxval are used. 
     int maxval,minval; 
     Point* maxloc, maxloc; 
     //Crop the windows 
     Rect window(i,0,windowsize,1); 
     //Get the maxima 
     minMaxLoc(histogram(window), minval,maxval,maxloc,minloc); 
     //Check if its not on the side 
     if(maxloc.x != 0&&maxloc.x != windowsize-1){ 
      //Translate from cropped window into real position 
      int originalposition = maxloc.x+i; 
      //Check that this is a new maxima and not already recorded 
      if(lastmaxima != originalposition){ 
       maximas.push(originalposition); 
       lastmaxima = originalposition; 
      } 
     } 
    } 
    return maximas; 
} 

Конечно, это очень упрощенно система. Возможно, вы захотите использовать многомасштабный подход с разными размерами раздвижных окон. Вам также может потребоваться применить гауссовское сглаживание в зависимости от ваших данных. Другим подходом может быть запуск этого для небольшого размера окна, такого как 3 или 4 (вам нужно минимум 3). Тогда вы можете использовать что-то еще для не-максимума-подавления.

Для вашего подхода, в котором вы предложили

Может быть, есть функция, которая позволяет мне определить минимальный пик/порог и сказать мне закрома всех этих локальных максимумов выше этого порога.

Вы можете просто выполнить пороговое значение, прежде чем находить максимумы с вышеуказанной функцией.

threshold(hist,res ...aditional parameters...); 
vector<int> maximas = findMaximas(hist, ...other parameters...); 
Смежные вопросы