|
|
|
@ -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); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|