Reverted back to the previous method where a public method groupRectangles was added to HOGDescriptor to take care of ROI and weight grouping

This commit is contained in:
Bahram Dahi
2013-05-24 18:25:23 -04:00
parent 8c25f9f28a
commit dcad6ce65a
3 changed files with 115 additions and 39 deletions

View File

@@ -1060,9 +1060,7 @@ void HOGDescriptor::detectMultiScale(
}
else
{
vector<int> dummy;
dummy.resize(foundLocations.size(), INT_MAX);
groupRectangles(foundLocations, (int)finalThreshold, 0.2, &dummy, &foundWeights);
groupRectangles(foundLocations, foundWeights, (int)finalThreshold, 0.2);
}
}
@@ -2636,4 +2634,82 @@ void HOGDescriptor::readALTModel(std::string modelfile)
fclose(modelfl);
}
void HOGDescriptor::groupRectangles(vector<cv::Rect>& rectList, vector<double>& weights, int groupThreshold, double eps) const
{
if( groupThreshold <= 0 || rectList.empty() )
{
return;
}
CV_Assert(rectList.size() == weights.size());
vector<int> labels;
int nclasses = partition(rectList, labels, SimilarRects(eps));
vector<cv::Rect_<double>> rrects(nclasses);
vector<int> numInClass(nclasses, 0);
vector<double> foundWeights(nclasses, DBL_MIN);
vector<double> totalFactorsPerClass(nclasses, 1);
int i, j, nlabels = (int)labels.size();
for( i = 0; i < nlabels; i++ )
{
int cls = labels[i];
rrects[cls].x += rectList[i].x;
rrects[cls].y += rectList[i].y;
rrects[cls].width += rectList[i].width;
rrects[cls].height += rectList[i].height;
foundWeights[cls] = max(foundWeights[cls], weights[i]);
numInClass[cls]++;
}
for( i = 0; i < nclasses; i++ )
{
// find the average of all ROI in the cluster
cv::Rect_<double> r = rrects[i];
float s = 1.f/numInClass[i];
rrects[i] = cv::Rect_<double>(cv::saturate_cast<double>(r.x*s),
cv::saturate_cast<double>(r.y*s),
cv::saturate_cast<double>(r.width*s),
cv::saturate_cast<double>(r.height*s));
}
rectList.clear();
weights.clear();
for( i = 0; i < nclasses; i++ )
{
cv::Rect r1 = rrects[i];
int n1 = numInClass[i];
double w1 = foundWeights[i];
if( n1 <= groupThreshold )
continue;
// filter out small rectangles inside large rectangles
for( j = 0; j < nclasses; j++ )
{
int n2 = numInClass[j];
if( j == i || n2 <= groupThreshold )
continue;
cv::Rect r2 = rrects[j];
int dx = cv::saturate_cast<int>( r2.width * eps );
int dy = cv::saturate_cast<int>( r2.height * eps );
if( r1.x >= r2.x - dx &&
r1.y >= r2.y - dy &&
r1.x + r1.width <= r2.x + r2.width + dx &&
r1.y + r1.height <= r2.y + r2.height + dy &&
(n2 > std::max(3, n1) || n1 < 3) )
break;
}
if( j == nclasses )
{
rectList.push_back(r1);
weights.push_back(w1);
}
}
}
}