Выполнение такой операции, как установка пороговых значений пиксель за пикселем, обычно является неправильным способом достижения этого в OpenCV - существуют функции, которые работают с целыми массивами изображений, которые проще и уже оптимизированы для скорости.
В этом случае попробуйте сначала разделить изображение, чтобы отделить каналы H / S / V, затем Порог на канале Хюэ, чтобы получить маску (возможно, вам придется использовать пересечение двух масок, которые вы можете сделать с помощью умножения или «поразрядно и») - итоговая маска - это ваше черно-белое изображение.
(я понимаю, что я связан с документацией C ++, но я уверен, что вы можете найти эквивалентные функции в документах OpenCV старого стиля)
Обновление
Хорошо, я попытаюсь написать код, чтобы показать, что я имею в виду. Я также нашел функцию, которую искал, которая лучше, чем Threshold, это InRangeS . Это позволяет вам устанавливать верхнюю и нижнюю границы для всех каналов одновременно и применять их все в вашу маску.
void HSVImageToMask(IplImage * image, cvMat * mask)
/* mask should be the same size as image, and of type CV_8UC1 */
/* e.g. cvMat * mask = cvCreateMat(image->width, image->height, CV8UC1); */
{
double hMin = 6;
double hMax = 36;
double sMin = 10; /* not sure what value you need */
double sMax = 245; /* not sure what value you need */
double vMin = 0;
double vMax = 255;
CvScalar hsvMin = cvScalar(hMin, sMin, vMin);
CvScalar hsvMax = cvScalar(hMax, sMax, vMax);
cvInRangeS(image, hsvMin, hsvMax, mask);
}
PS. Я выяснил проблему с вашим исходным кодом - вы должны использовать 255 вместо 256 в качестве «белого» значения. Этот метод все еще лучше, хотя:)
PPS. Они нам не нужны, кроме как для дальнейшего использования:
"поразрядно" :
cvAnd(const CvArr* src1, const CvArr* src2, CvArr* dst)
Если у вас есть две черно-белые маски, это даст вам пересечение. Используйте cvOr, чтобы получить Союз.