fixed crashes in parallel HOG detector; avoid use of new POPCNT instruction in ORB (to make it compatible with older CPUs).
This commit is contained in:
parent
3bfd1aa58d
commit
d3d55f3234
@ -180,6 +180,7 @@ CV_INLINE IppiSize ippiSize(int width, int height)
|
|||||||
}
|
}
|
||||||
|
|
||||||
typedef tbb::concurrent_vector<Rect> ConcurrentRectVector;
|
typedef tbb::concurrent_vector<Rect> ConcurrentRectVector;
|
||||||
|
typedef tbb::concurrent_vector<double> ConcurrentDoubleVector;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
namespace cv
|
namespace cv
|
||||||
@ -201,11 +202,12 @@ CV_INLINE IppiSize ippiSize(int width, int height)
|
|||||||
#ifdef HAVE_THREADING_FRAMEWORK
|
#ifdef HAVE_THREADING_FRAMEWORK
|
||||||
#include "threading_framework.hpp"
|
#include "threading_framework.hpp"
|
||||||
|
|
||||||
template<typename Body>
|
template<typename Body>
|
||||||
static void parallel_for( const BlockedRange& range, const Body& body )
|
static void parallel_for( const BlockedRange& range, const Body& body )
|
||||||
{
|
{
|
||||||
tf::parallel_for<Body>(range, body);
|
tf::parallel_for<Body>(range, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef tf::ConcurrentVector<Rect> ConcurrentRectVector;
|
typedef tf::ConcurrentVector<Rect> ConcurrentRectVector;
|
||||||
#else
|
#else
|
||||||
template<typename Body> static inline
|
template<typename Body> static inline
|
||||||
@ -214,6 +216,7 @@ CV_INLINE IppiSize ippiSize(int width, int height)
|
|||||||
body(range);
|
body(range);
|
||||||
}
|
}
|
||||||
typedef std::vector<Rect> ConcurrentRectVector;
|
typedef std::vector<Rect> ConcurrentRectVector;
|
||||||
|
typedef std::vector<double> ConcurrentDoubleVector;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template<typename Iterator, typename Body> static inline
|
template<typename Iterator, typename Body> static inline
|
||||||
|
@ -108,11 +108,11 @@ HammingLUT::ResultType HammingLUT::operator()( const unsigned char* a, const uns
|
|||||||
|
|
||||||
Hamming::ResultType Hamming::operator()(const unsigned char* a, const unsigned char* b, int size) const
|
Hamming::ResultType Hamming::operator()(const unsigned char* a, const unsigned char* b, int size) const
|
||||||
{
|
{
|
||||||
#if __GNUC__
|
ResultType result;
|
||||||
ResultType result = 0;
|
#if defined __GNUC__ && CV_NEON
|
||||||
#if CV_NEON
|
|
||||||
if (CPU_HAS_NEON_FEATURE)
|
if (CPU_HAS_NEON_FEATURE)
|
||||||
{
|
{
|
||||||
|
result = 0;
|
||||||
for (size_t i = 0; i < size; i += 16)
|
for (size_t i = 0; i < size; i += 16)
|
||||||
{
|
{
|
||||||
uint8x16_t A_vec = vld1q_u8 (a + i);
|
uint8x16_t A_vec = vld1q_u8 (a + i);
|
||||||
@ -131,32 +131,9 @@ Hamming::ResultType Hamming::operator()(const unsigned char* a, const unsigned c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
|
||||||
{
|
|
||||||
//for portability just use unsigned long -- and use the __builtin_popcountll (see docs for __builtin_popcountll)
|
|
||||||
typedef unsigned long long pop_t;
|
|
||||||
const size_t modulo = size % sizeof(pop_t);
|
|
||||||
const pop_t * a2 = reinterpret_cast<const pop_t*> (a);
|
|
||||||
const pop_t * b2 = reinterpret_cast<const pop_t*> (b);
|
|
||||||
const pop_t * a2_end = a2 + (size/sizeof(pop_t));
|
|
||||||
|
|
||||||
for (; a2 != a2_end; ++a2, ++b2)
|
|
||||||
result += __builtin_popcountll((*a2) ^ (*b2));
|
|
||||||
|
|
||||||
if (modulo)
|
|
||||||
{
|
|
||||||
//in the case where size is not divisible by sizeof(size_t)
|
|
||||||
//need to mask off the bits at the end
|
|
||||||
pop_t a_final=0,b_final=0;
|
|
||||||
memcpy(&a_final,a2,modulo);
|
|
||||||
memcpy(&b_final,b2,modulo);
|
|
||||||
result += __builtin_popcountll(a_final ^ b_final);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
#else
|
|
||||||
return HammingLUT()(a,b,size);
|
|
||||||
#endif
|
#endif
|
||||||
|
result = HammingLUT()(a,b,size);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
BriefDescriptorExtractor::BriefDescriptorExtractor(int bytes) :
|
BriefDescriptorExtractor::BriefDescriptorExtractor(int bytes) :
|
||||||
|
@ -942,7 +942,7 @@ struct HOGInvoker
|
|||||||
HOGInvoker( const HOGDescriptor* _hog, const Mat& _img,
|
HOGInvoker( const HOGDescriptor* _hog, const Mat& _img,
|
||||||
double _hitThreshold, Size _winStride, Size _padding,
|
double _hitThreshold, Size _winStride, Size _padding,
|
||||||
const double* _levelScale, ConcurrentRectVector* _vec,
|
const double* _levelScale, ConcurrentRectVector* _vec,
|
||||||
vector<double>* _weights=0, vector<double>* _scales=0 )
|
ConcurrentDoubleVector* _weights=0, ConcurrentDoubleVector* _scales=0 )
|
||||||
{
|
{
|
||||||
hog = _hog;
|
hog = _hog;
|
||||||
img = _img;
|
img = _img;
|
||||||
@ -1002,8 +1002,8 @@ struct HOGInvoker
|
|||||||
Size padding;
|
Size padding;
|
||||||
const double* levelScale;
|
const double* levelScale;
|
||||||
ConcurrentRectVector* vec;
|
ConcurrentRectVector* vec;
|
||||||
vector<double>* weights;
|
ConcurrentDoubleVector* weights;
|
||||||
vector<double>* scales;
|
ConcurrentDoubleVector* scales;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -1029,14 +1029,18 @@ void HOGDescriptor::detectMultiScale(
|
|||||||
levelScale.resize(levels);
|
levelScale.resize(levels);
|
||||||
|
|
||||||
ConcurrentRectVector allCandidates;
|
ConcurrentRectVector allCandidates;
|
||||||
|
ConcurrentDoubleVector tempScales;
|
||||||
|
ConcurrentDoubleVector tempWeights;
|
||||||
vector<double> foundScales;
|
vector<double> foundScales;
|
||||||
|
|
||||||
parallel_for(BlockedRange(0, (int)levelScale.size()),
|
parallel_for(BlockedRange(0, (int)levelScale.size()),
|
||||||
HOGInvoker(this, img, hitThreshold, winStride, padding, &levelScale[0], &allCandidates, &foundWeights, &foundScales));
|
HOGInvoker(this, img, hitThreshold, winStride, padding, &levelScale[0], &allCandidates, &tempWeights, &tempScales));
|
||||||
|
|
||||||
foundLocations.resize(allCandidates.size());
|
std::copy(tempScales.begin(), tempScales.end(), back_inserter(foundScales));
|
||||||
std::copy(allCandidates.begin(), allCandidates.end(), foundLocations.begin());
|
foundLocations.clear();
|
||||||
|
std::copy(allCandidates.begin(), allCandidates.end(), back_inserter(foundLocations));
|
||||||
|
foundWeights.clear();
|
||||||
|
std::copy(tempWeights.begin(), tempWeights.end(), back_inserter(foundWeights));
|
||||||
|
|
||||||
if ( useMeanshiftGrouping )
|
if ( useMeanshiftGrouping )
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user