Я пытаюсь написать метод, который найдет правильные пороговые значения в пространстве HSV для объекта, расположенного в центре экрана. Эти значения используются для алгоритма отслеживания объектов. Я тестировал этот фрагмент кода с пороговыми значениями ручной кодировки, и он работает хорошо. Идея метода заключается в том, что он должен вычислять гистограммы для каждого из каналов, а затем возвращать 5-й и 95-й процентиль для каждого, которые будут использоваться в качестве пороговых значений. (Кредит: How to find RGB/HSV color parameters for color tracking?) Изображение передается картина объекта отслеживаться (который задается пользователем перед началом всего процесса Вот кодПоиск порогов HSV с помощью гистограмм с помощью OpenCV
std::vector<cv::Scalar> HSV_Threshold_Determiner::Get_Threshold_Values(const cv::Mat& image)
{
cv::Mat inputImage;
cv::cvtColor(image, inputImage, CV_BGR2HSV);
std::vector<cv::Mat> bgrPlanes;
cv::split(inputImage, bgrPlanes);
cv::Mat hHist, sHist, vHist;
int hMax = 180, svMax = 256;
float hRanges[] = { 0, (float)hMax };
const float* hRange = { hRanges };
float svRanges[] = { 0, (float)svMax };
const float* svRange = { svRanges };
//float sRanges[] = { 0, 256 };
cv::calcHist(&bgrPlanes[0], 1, 0, cv::Mat(), hHist, 1, &hMax, &hRange);
cv::calcHist(&bgrPlanes[1], 1, 0, cv::Mat(), sHist, 1, &svMax, &svRange);
cv::calcHist(&bgrPlanes[2], 1, 0, cv::Mat(), vHist, 1, &svMax, &svRange);
int totalEntries = image.cols * image.rows;
int fiveCutoff = (int)(totalEntries * .05);
int ninetyFiveCutoff = (int)(totalEntries * .95);
float hTotal = 0, sTotal = 0, vTotal = 0;
bool hMinFound = false, hMaxFound = false, sMinFound = false, sMaxFound = false,
vMinFound = false, vMaxFound = false;
cv::Scalar hThresholds;
cv::Scalar sThresholds;
cv::Scalar vThresholds;
for(int i = 0; i < vHist.rows; ++i)
{
if(i < hHist.rows)
{
hTotal += hHist.at<float>(i, 0);
if(hTotal >= fiveCutoff && !hMinFound)
{
hThresholds.val[0] = i;
hMinFound = true;
}
else if(hTotal>= ninetyFiveCutoff && !hMaxFound)
{
hThresholds.val[1] = i;
hMaxFound = true;
}
}
sTotal += sHist.at<float>(i, 0);
vTotal += vHist.at<float>(i, 0);
if(sTotal >= fiveCutoff && !sMinFound)
{
sThresholds.val[0] = i;
sMinFound = true;
}
else if(sTotal >= ninetyFiveCutoff && !sMaxFound)
{
sThresholds.val[1] = i;
sMaxFound = true;
}
if(vTotal >= fiveCutoff && !vMinFound)
{
vThresholds.val[0] = i;
vMinFound = true;
}
else if(vTotal >= ninetyFiveCutoff && !vMaxFound)
{
vThresholds.val[1] = i;
vMaxFound = true;
}
if(vMaxFound && sMaxFound && hMaxFound)
{
break;
}
}
std::vector<cv::Scalar> returnVect;
returnVect.push_back(hThresholds);
returnVect.push_back(sThresholds);
returnVect.push_back(vThresholds);
return returnVect;
}
То, что я пытаюсь сделать, это сумма. количество записей в каждом ведре до тех пор, пока я не получу число, которое больше или равно пяти процентам и девяносто пять процентов от общего числа. К сожалению, числа, которые я получаю, никогда не близки к тем, которые я получаю, если я делаю пороговое значение вручную
Как далеко ли я получить от фактически найти 5% и 95% от каждого канала? Если вы сделаете обрезание 0-100%, верните ли вы число, равное totalEntries? –
i довольно далеко, и я не понимаю вторую часть вопроса, делая отсечки, эти значения должны давать i's 0 и 255 или 179 – Pat