2016-04-11 2 views
0

Я очень новичок в OpenCV, поэтому, я думаю, я делаю какую-то глупую ошибку.Сбой функции OpenCV с маской, созданной из пороговой функции OpenCV?

Сначала я создаю пустую матрицу cv::mat, mask, CV_8U и заполняю ее нулями. Затем я заполняю матрицу либо 0, либо 255, проверяя значения в CV_32FC1 типа cv::mat матрицы croppedDifferenceImage с использованием cv::threshold. Затем я использую mask в качестве параметра для функции cv::mean.

cv::Mat mask = cv::Mat(croppedDifferenceImage.rows, croppedDifferenceImage.cols, CV_8U, cv::Scalar(0)); 
cv::threshold(croppedDifferenceImage, mask, 3.2, 255, CV_THRESH_BINARY); 
double mean = cv::mean(croppedDifferenceImage, mask)[0]; 

Но я продолжаю имея аварию с сообщением:

/build/buildd/opencv-2.4.8+dfsg1/modules/core/src/stat.cpp:565: error: (-215) mask.empty() || mask.type() == CV_8U in function mean 

Что я делаю неправильно?

+0

Любая причина, по которой вы используете opencv 2.4.0, а не opencv 3? – PhotometricStereo

+0

Я не знаю, есть ли какие-то причины. Я только что присоединился к этому проекту и очень новичок в opencv. –

+0

Каков тип 'mask'? Согласно документации для 'threshold', пункт назначения имеет« тот же размер и тип, что и src ». Это означает, что вы передаете CV_32FC1 в качестве маски для 'mean', что недопустимо. –

ответ

2

В соответствии с документацией cv::threshold:

double threshold(InputArray src, OutputArray dst, double thresh, double maxval, int type) 

Параметры:

  • SRC - входной массив (одноканальное, 8-битные или 32-бит с плавающей точкой).
  • dst - массив вывода такого же размера и типа, что и src.

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

Далее передать эту маску cv::mean, который (согласно утверждают) требует маски:

  • Не быть пустым
  • Для типа CV_8U (что особенно проверка не касается себя количество каналов).

Итак, для того, чтобы решить эту проблему, необходимо преобразовать (используя Mat::convertTo) маску после пороговым:

cv::threshold(croppedDifferenceImage, mask, 3.2, 255, CV_THRESH_BINARY); 
mask.convertTo(mask, CV_8U) 
double mean = cv::mean(croppedDifferenceImage, mask)[0]; 

Также см Miki's answer по предложению об использовании только логические операции над cv::Mat вместо звонка на cv::threshold.

1

Как упоминалось в комментариях @Dan Mašek, результат threshold будет иметь тот же тип, что и вход. Таким образом, в вашем случае, поскольку вы проходите матрицу CV_32FC1, тип mask будет CV_32FC1, что не является то, что ожидает mean.

В принципе, вы должны обязательно пройти к mean маске типа CV_8UC1.

Вместо преобразование mask к нужному типу, так как вы используете простой порог, вы можете использовать Mat логические операции, которые дадут вам всегда есть CV_8UC1 результата:

Mat mask = croppedDifferenceImage > 3.2; 
double mean = cv::mean(croppedDifferenceImage, mask)[0]; 

В противном случае, вы можете преобразовать mask к нужному типу:

Mat mask; 
threshold(croppedDifferenceImage, mask, 3.2, 255, CV_THRESH_BINARY); 
mask.convertTo(mask, CV_8U); 

double mean = cv::mean(croppedDifferenceImage, mask)[0]; 

Помните также, что вам не нужно для предварительного выделения результата операций OpenCV (т. OutputArray).

+1

Хороший вопрос об использовании только логических операций на 'cv :: Mat'. –

Смежные вопросы