integrated patch: HOG confidence calculation. Thanks, Wongun.
This commit is contained in:
@@ -491,6 +491,17 @@ protected:
|
||||
|
||||
//////////////// HOG (Histogram-of-Oriented-Gradients) Descriptor and Object Detector //////////////
|
||||
|
||||
// struct for detection region of interest (ROI)
|
||||
struct DetectionROI
|
||||
{
|
||||
// scale(size) of the bounding box
|
||||
double scale;
|
||||
// set of requrested locations to be evaluated
|
||||
vector<cv::Point> locations;
|
||||
// vector that will contain confidence values for each location
|
||||
vector<double> confidences;
|
||||
};
|
||||
|
||||
struct CV_EXPORTS_W HOGDescriptor
|
||||
{
|
||||
public:
|
||||
@@ -583,6 +594,23 @@ public:
|
||||
CV_PROP bool gammaCorrection;
|
||||
CV_PROP vector<float> svmDetector;
|
||||
CV_PROP int nlevels;
|
||||
|
||||
|
||||
// evaluate specified ROI and return confidence value for each location
|
||||
virtual void detectROI(const cv::Mat& img, const vector<cv::Point> &locations,
|
||||
CV_OUT std::vector<cv::Point>& foundLocations, CV_OUT std::vector<double>& confidences,
|
||||
double hitThreshold = 0, cv::Size winStride = Size(),
|
||||
cv::Size padding = Size()) const;
|
||||
|
||||
// evaluate specified ROI and return confidence value for each location in multiple scales
|
||||
virtual void detectMultiScaleROI(const cv::Mat& img,
|
||||
CV_OUT std::vector<cv::Rect>& foundLocations,
|
||||
std::vector<DetectionROI>& locations,
|
||||
double hitThreshold = 0,
|
||||
int groupThreshold = 0) const;
|
||||
|
||||
// read/parse Dalal's alt model file
|
||||
void readALTModel(std::string modelfile);
|
||||
};
|
||||
|
||||
|
||||
|
@@ -39,7 +39,7 @@
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "precomp.hpp"
|
||||
#include <iterator>
|
||||
#ifdef HAVE_IPP
|
||||
@@ -2382,4 +2382,238 @@ vector<float> HOGDescriptor::getDaimlerPeopleDetector()
|
||||
return vector<float>(detector, detector + sizeof(detector)/sizeof(detector[0]));
|
||||
}
|
||||
|
||||
struct HOGConfInvoker
|
||||
{
|
||||
HOGConfInvoker( const HOGDescriptor* _hog, const Mat& _img,
|
||||
double _hitThreshold, Size _padding,
|
||||
std::vector<DetectionROI>* locs,
|
||||
ConcurrentRectVector* _vec )
|
||||
{
|
||||
hog = _hog;
|
||||
img = _img;
|
||||
hitThreshold = _hitThreshold;
|
||||
padding = _padding;
|
||||
locations = locs;
|
||||
vec = _vec;
|
||||
}
|
||||
|
||||
void operator()( const BlockedRange& range ) const
|
||||
{
|
||||
int i, i1 = range.begin(), i2 = range.end();
|
||||
|
||||
Size maxSz(cvCeil(img.cols/(*locations)[0].scale), cvCeil(img.rows/(*locations)[0].scale));
|
||||
Mat smallerImgBuf(maxSz, img.type());
|
||||
vector<Point> dets;
|
||||
|
||||
for( i = i1; i < i2; i++ )
|
||||
{
|
||||
double scale = (*locations)[i].scale;
|
||||
|
||||
Size sz(cvRound(img.cols / scale), cvRound(img.rows / scale));
|
||||
Mat smallerImg(sz, img.type(), smallerImgBuf.data);
|
||||
|
||||
if( sz == img.size() )
|
||||
smallerImg = Mat(sz, img.type(), img.data, img.step);
|
||||
else
|
||||
resize(img, smallerImg, sz);
|
||||
|
||||
hog->detectROI(smallerImg, (*locations)[i].locations, dets, (*locations)[i].confidences, hitThreshold, Size(), padding);
|
||||
Size scaledWinSize = Size(cvRound(hog->winSize.width*scale), cvRound(hog->winSize.height*scale));
|
||||
for( size_t j = 0; j < dets.size(); j++ )
|
||||
vec->push_back(Rect(cvRound(dets[j].x*scale),
|
||||
cvRound(dets[j].y*scale),
|
||||
scaledWinSize.width, scaledWinSize.height));
|
||||
}
|
||||
}
|
||||
|
||||
const HOGDescriptor* hog;
|
||||
Mat img;
|
||||
double hitThreshold;
|
||||
std::vector<DetectionROI>* locations;
|
||||
Size padding;
|
||||
ConcurrentRectVector* vec;
|
||||
};
|
||||
|
||||
void HOGDescriptor::detectROI(const cv::Mat& img, const vector<cv::Point> &locations,
|
||||
CV_OUT std::vector<cv::Point>& foundLocations, CV_OUT std::vector<double>& confidences,
|
||||
double hitThreshold, cv::Size winStride,
|
||||
cv::Size padding) const
|
||||
{
|
||||
foundLocations.clear();
|
||||
|
||||
confidences.clear();
|
||||
|
||||
if( svmDetector.empty() )
|
||||
return;
|
||||
|
||||
if( locations.empty() )
|
||||
return;
|
||||
|
||||
if( winStride == Size() )
|
||||
winStride = cellSize;
|
||||
|
||||
Size cacheStride(gcd(winStride.width, blockStride.width),
|
||||
gcd(winStride.height, blockStride.height));
|
||||
|
||||
size_t nwindows = locations.size();
|
||||
padding.width = (int)alignSize(std::max(padding.width, 0), cacheStride.width);
|
||||
padding.height = (int)alignSize(std::max(padding.height, 0), cacheStride.height);
|
||||
Size paddedImgSize(img.cols + padding.width*2, img.rows + padding.height*2);
|
||||
|
||||
// HOGCache cache(this, img, padding, padding, nwindows == 0, cacheStride);
|
||||
HOGCache cache(this, img, padding, padding, true, cacheStride);
|
||||
if( !nwindows )
|
||||
nwindows = cache.windowsInImage(paddedImgSize, winStride).area();
|
||||
|
||||
const HOGCache::BlockData* blockData = &cache.blockData[0];
|
||||
|
||||
int nblocks = cache.nblocks.area();
|
||||
int blockHistogramSize = cache.blockHistogramSize;
|
||||
size_t dsize = getDescriptorSize();
|
||||
|
||||
double rho = svmDetector.size() > dsize ? svmDetector[dsize] : 0;
|
||||
vector<float> blockHist(blockHistogramSize);
|
||||
|
||||
for( size_t i = 0; i < nwindows; i++ )
|
||||
{
|
||||
Point pt0;
|
||||
pt0 = locations[i];
|
||||
if( pt0.x < -padding.width || pt0.x > img.cols + padding.width - winSize.width ||
|
||||
pt0.y < -padding.height || pt0.y > img.rows + padding.height - winSize.height )
|
||||
{
|
||||
// out of image
|
||||
confidences.push_back(-10.0);
|
||||
continue;
|
||||
}
|
||||
|
||||
double s = rho;
|
||||
const float* svmVec = &svmDetector[0];
|
||||
int j, k;
|
||||
|
||||
for( j = 0; j < nblocks; j++, svmVec += blockHistogramSize )
|
||||
{
|
||||
const HOGCache::BlockData& bj = blockData[j];
|
||||
Point pt = pt0 + bj.imgOffset;
|
||||
// need to devide this into 4 parts!
|
||||
const float* vec = cache.getBlock(pt, &blockHist[0]);
|
||||
for( k = 0; k <= blockHistogramSize - 4; k += 4 )
|
||||
s += vec[k]*svmVec[k] + vec[k+1]*svmVec[k+1] +
|
||||
vec[k+2]*svmVec[k+2] + vec[k+3]*svmVec[k+3];
|
||||
for( ; k < blockHistogramSize; k++ )
|
||||
s += vec[k]*svmVec[k];
|
||||
}
|
||||
// cv::waitKey();
|
||||
confidences.push_back(s);
|
||||
|
||||
if( s >= hitThreshold )
|
||||
foundLocations.push_back(pt0);
|
||||
}
|
||||
}
|
||||
|
||||
void HOGDescriptor::detectMultiScaleROI(const cv::Mat& img,
|
||||
CV_OUT std::vector<cv::Rect>& foundLocations,
|
||||
std::vector<DetectionROI>& locations,
|
||||
double hitThreshold,
|
||||
int groupThreshold) const
|
||||
{
|
||||
ConcurrentRectVector allCandidates;
|
||||
|
||||
parallel_for(BlockedRange(0, (int)locations.size()),
|
||||
HOGConfInvoker(this, img, hitThreshold, Size(8, 8), &locations, &allCandidates));
|
||||
|
||||
foundLocations.resize(allCandidates.size());
|
||||
std::copy(allCandidates.begin(), allCandidates.end(), foundLocations.begin());
|
||||
cv::groupRectangles(foundLocations, groupThreshold, 0.2);
|
||||
}
|
||||
|
||||
void HOGDescriptor::readALTModel(std::string modelfile)
|
||||
{
|
||||
// read model from SVMlight format..
|
||||
FILE *modelfl;
|
||||
if ((modelfl = fopen(modelfile.c_str(), "rb")) == NULL)
|
||||
{
|
||||
std::string eerr("file not exist");
|
||||
std::string efile(__FILE__);
|
||||
std::string efunc(__FUNCTION__);
|
||||
throw Exception(CV_StsError, eerr, efile, efunc, __LINE__);
|
||||
}
|
||||
char version_buffer[10];
|
||||
if (!fread (&version_buffer,sizeof(char),10,modelfl))
|
||||
{
|
||||
std::string eerr("version?");
|
||||
std::string efile(__FILE__);
|
||||
std::string efunc(__FUNCTION__);
|
||||
throw Exception(CV_StsError, eerr, efile, efunc, __LINE__);
|
||||
}
|
||||
if(strcmp(version_buffer,"V6.01")) {
|
||||
std::string eerr("version doesnot match");
|
||||
std::string efile(__FILE__);
|
||||
std::string efunc(__FUNCTION__);
|
||||
throw Exception(CV_StsError, eerr, efile, efunc, __LINE__);
|
||||
}
|
||||
/* read version number */
|
||||
int version = 0;
|
||||
if (!fread (&version,sizeof(int),1,modelfl))
|
||||
{ throw Exception(); }
|
||||
if (version < 200)
|
||||
{
|
||||
std::string eerr("version doesnot match");
|
||||
std::string efile(__FILE__);
|
||||
std::string efunc(__FUNCTION__);
|
||||
throw Exception();
|
||||
}
|
||||
int kernel_type;
|
||||
int nread;
|
||||
nread=fread(&(kernel_type),sizeof(int),1,modelfl);
|
||||
|
||||
{// ignore these
|
||||
int poly_degree;
|
||||
nread=fread(&(poly_degree),sizeof(int),1,modelfl);
|
||||
|
||||
double rbf_gamma;
|
||||
nread=fread(&(rbf_gamma),sizeof(double), 1, modelfl);
|
||||
double coef_lin;
|
||||
nread=fread(&(coef_lin),sizeof(double),1,modelfl);
|
||||
double coef_const;
|
||||
nread=fread(&(coef_const),sizeof(double),1,modelfl);
|
||||
int l;
|
||||
nread=fread(&l,sizeof(int),1,modelfl);
|
||||
char* custom = new char[l];
|
||||
nread=fread(custom,sizeof(char),l,modelfl);
|
||||
delete[] custom;
|
||||
}
|
||||
int totwords;
|
||||
nread=fread(&(totwords),sizeof(int),1,modelfl);
|
||||
{// ignore these
|
||||
int totdoc;
|
||||
nread=fread(&(totdoc),sizeof(int),1,modelfl);
|
||||
int sv_num;
|
||||
nread=fread(&(sv_num), sizeof(int),1,modelfl);
|
||||
}
|
||||
|
||||
double linearbias;
|
||||
nread=fread(&linearbias, sizeof(double), 1, modelfl);
|
||||
|
||||
std::vector<float> detector;
|
||||
detector.clear();
|
||||
if(kernel_type == 0) { /* linear kernel */
|
||||
/* save linear wts also */
|
||||
double *linearwt = new double[totwords+1];
|
||||
int length = totwords;
|
||||
nread = fread(linearwt, sizeof(double), totwords + 1, modelfl);
|
||||
if(nread != length + 1)
|
||||
throw Exception();
|
||||
|
||||
for(int i = 0; i < length; i++)
|
||||
detector.push_back((float)linearwt[i]);
|
||||
|
||||
detector.push_back((float)-linearbias);
|
||||
setSVMDetector(detector);
|
||||
delete linearwt;
|
||||
} else {
|
||||
throw Exception();
|
||||
}
|
||||
fclose(modelfl);
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user