Что это значит, когда cv :: minMaxLoc возвращает точку (-1, -1) в качестве минимального и максимального местоположений? - PullRequest
2 голосов
/ 12 декабря 2011

Использование OpenCV 2.3.1. Я запускаю cv :: minMaxLoc (), и он возвращает точку (-1, -1) как для минимального, так и для максимального местоположения, с 0 в качестве значения для обоих. Что это значит?

Ответы [ 2 ]

1 голос
/ 12 декабря 2011

Ниже приведены соответствующие разделы кода для функции minMaxLoc :

static void ofs2idx(const Mat& a, size_t ofs, int* idx)
{
    int i, d = a.dims;
    if( ofs > 0 )
    {
        ofs--;
        for( i = d-1; i >= 0; i-- )
        {
            int sz = a.size[i];
            idx[i] = (int)(ofs % sz);
            ofs /= sz;
        }
    }
    else
    {
        for( i = d-1; i >= 0; i-- )
            idx[i] = -1;
    }
}

}

void cv::minMaxIdx(InputArray _src, double* minVal,
                   double* maxVal, int* minIdx, int* maxIdx,
                   InputArray _mask)
{
    Mat src = _src.getMat(), mask = _mask.getMat();
    int depth = src.depth(), cn = src.channels();

    CV_Assert( (cn == 1 && (mask.empty() || mask.type() == CV_8U)) ||
               (cn >= 1 && mask.empty() && !minIdx && !maxIdx) );
    MinMaxIdxFunc func = minmaxTab[depth];
    CV_Assert( func != 0 );

    const Mat* arrays[] = {&src, &mask, 0};
    uchar* ptrs[2];
    NAryMatIterator it(arrays, ptrs);

    size_t minidx = 0, maxidx = 0;
    int iminval = INT_MAX, imaxval = INT_MIN;
    float fminval = FLT_MAX, fmaxval = -FLT_MAX;
    double dminval = DBL_MAX, dmaxval = -DBL_MAX;
    size_t startidx = 1;
    int *minval = &iminval, *maxval = &imaxval;
    int planeSize = (int)it.size*cn;

    if( depth == CV_32F )
        minval = (int*)&fminval, maxval = (int*)&fmaxval;
    else if( depth == CV_64F )
        minval = (int*)&dminval, maxval = (int*)&dmaxval;

    for( size_t i = 0; i < it.nplanes; i++, ++it, startidx += planeSize )
        func( ptrs[0], ptrs[1], minval, maxval, &minidx, &maxidx, planeSize, startidx );

    if( minidx == 0 )
        dminval = dmaxval = 0;
    else if( depth == CV_32F )
        dminval = fminval, dmaxval = fmaxval;
    else if( depth <= CV_32S )
        dminval = iminval, dmaxval = imaxval;

    if( minVal )
        *minVal = dminval;
    if( maxVal )
        *maxVal = dmaxval;

    if( minIdx )
        ofs2idx(src, minidx, minIdx);
    if( maxIdx )
        ofs2idx(src, maxidx, maxIdx);
}    

void cv::minMaxLoc( InputArray _img, double* minVal, double* maxVal,
                Point* minLoc, Point* maxLoc, InputArray mask )
{
    Mat img = _img.getMat();
    CV_Assert(img.dims <= 2);

    minMaxIdx(_img, minVal, maxVal, (int*)minLoc, (int*)maxLoc, mask);
    if( minLoc )
        std::swap(minLoc->x, minLoc->y);
    if( maxLoc )
        std::swap(maxLoc->x, maxLoc->y);
}

Судя по потоку кода, у вас есть случай minidx, равный нулю, которыйзатем устанавливает dminval = dmaxval = 0.Кроме того, в функции ofs2idx, когда minidx (т. Е. Параметр ofs в ofs2idx) равен нулю, логика устанавливает минимальную и максимальную точки в (-1, -1) (т. Е. idx[i] = -1;).Это может произойти, если ваша матрица не имеет элементов.Какой размер матрицы вы пытаетесь использовать?

0 голосов
/ 03 февраля 2015

Это немного загадочный способ, когда minMaxLoc говорит вам, что понятия «минимум» и «максимум» плохо применимы к вашей матрице. Посмотрим, что это значит. По сути, minMaxLoc определяет местоположение минимума и максимума, просматривая все значения в матрице. В псевдокоде алгоритм выглядит примерно так:

# initialization
minimum_value = Infinity
maximum_value = -Infinity

minimum_position = Unknown
maximum position = Unknown

for every element in matrix
    # determine if we have a candidate for the minimum
    if element.value < minimum_value
        minimum_value = element.value
        minimum_position = elment.position

    # determine if we have a candidate for the maximum
    if element.value > maximum_value
        maximum_value = element.value
        maximum_position = element.position

Теперь обратите внимание, что в этом коде есть два пути, которые оставляют для minimum_location значение Unknown:

  1. содержимое предложения for никогда не выполняется вообще
  2. содержимое первого предложения if никогда не выполняется

Как это может произойти? Ну, первый случай происходит, если в матрице нет элементов (пустая матрица). Второе происходит, если для каждого элемента в матрице сравнение element.value < minimum_value неверно. Это может означать две вещи: либо все элементы Infinity, либо все NaN. Аналогичные рассуждения применимы в случае maximum_location.

Итак, проблема в том, что вы спрашиваете «минимум» и «максимум» в контексте, где эти два понятия - в лучшем случае - неоднозначны.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...