1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-31 00:03:03 +04:00

completely new C++ persistence implementation (#13011)

* integrated the new C++ persistence; removed old persistence; most of OpenCV compiles fine! the tests have not been run yet

* fixed multiple bugs in the new C++ persistence

* fixed raw size of the parsed empty sequences

* [temporarily] excluded obsolete applications traincascade and createsamples from build

* fixed several compiler warnings and multiple test failures

* undo changes in cocoa window rendering (that was fixed in another PR)

* fixed more compile warnings and the remaining test failures (hopefully)

* trying to fix the last little warning
This commit is contained in:
Vadim Pisarevsky
2018-11-02 00:27:06 +03:00
committed by GitHub
parent ca55982669
commit 0f622206e4
51 changed files with 5662 additions and 8562 deletions
+14 -4
View File
@@ -913,13 +913,23 @@ bool CascadeClassifierImpl::load(const String& filename)
if( !fs.isOpened() )
return false;
if( read_(fs.getFirstTopLevelNode()) )
FileNode fs_root = fs.getFirstTopLevelNode();
if( read_(fs_root) )
return true;
fs.release();
// probably, it's the cascade in the old format;
// let's try to convert it to the new format
FileStorage newfs(".yml", FileStorage::WRITE+FileStorage::MEMORY);
haar_cvt::convert(fs_root, newfs);
std::string newfs_content = newfs.releaseAndGetString();
newfs.open(newfs_content, FileStorage::READ+FileStorage::MEMORY);
fs_root = newfs.getFirstTopLevelNode();
oldCascade.reset((CvHaarClassifierCascade*)cvLoad(filename.c_str(), 0, 0, 0));
return !oldCascade.empty();
if( read_(fs_root) )
return true;
return false;
}
void CascadeClassifierImpl::read(const FileNode& node)
+6
View File
@@ -647,4 +647,10 @@ inline int predictCategoricalStump( CascadeClassifierImpl& cascade,
sum = (double)tmp;
return 1;
}
namespace haar_cvt
{
bool convert(const FileNode& oldcascade_root, FileStorage& newfs);
}
}
+12 -14
View File
@@ -42,6 +42,7 @@
/* Haar features calculation */
#include "precomp.hpp"
#include "cascadedetect.hpp"
#include <stdio.h>
namespace cv
@@ -111,13 +112,8 @@ struct HaarStageClassifier
std::vector<HaarClassifier> weaks;
};
static bool convert(const String& oldcascade, const String& newcascade)
bool convert(const FileNode& oldroot, FileStorage& newfs)
{
FileStorage oldfs(oldcascade, FileStorage::READ);
if( !oldfs.isOpened() )
return false;
FileNode oldroot = oldfs.getFirstTopLevelNode();
FileNode sznode = oldroot[ICV_HAAR_SIZE_NAME];
if( sznode.empty() )
return false;
@@ -194,10 +190,6 @@ static bool convert(const String& oldcascade, const String& newcascade)
}
}
FileStorage newfs(newcascade, FileStorage::WRITE);
if( !newfs.isOpened() )
return false;
int maxWeakCount = 0, nfeatures = (int)features.size();
for( i = 0; i < nstages; i++ )
maxWeakCount = std::max(maxWeakCount, (int)stages[i].weaks.size());
@@ -225,12 +217,12 @@ static bool convert(const String& oldcascade, const String& newcascade)
for( j = 0; j < nweaks; j++ )
{
const HaarClassifier& c = stages[i].weaks[j];
newfs << "{" << "internalNodes" << "[";
newfs << "{" << "internalNodes" << "[:";
int nnodes = (int)c.nodes.size(), nleaves = (int)c.leaves.size();
for( k = 0; k < nnodes; k++ )
newfs << c.nodes[k].left << c.nodes[k].right
<< c.nodes[k].f << c.nodes[k].threshold;
newfs << "]" << "leafValues" << "[";
newfs << "]" << "leafValues" << "[:";
for( k = 0; k < nleaves; k++ )
newfs << c.leaves[k];
newfs << "]" << "}";
@@ -249,7 +241,7 @@ static bool convert(const String& oldcascade, const String& newcascade)
{
if( j >= 2 && fabs(f.rect[j].weight) < FLT_EPSILON )
break;
newfs << "[" << f.rect[j].r.x << f.rect[j].r.y <<
newfs << "[:" << f.rect[j].r.x << f.rect[j].r.y <<
f.rect[j].r.width << f.rect[j].r.height << f.rect[j].weight << "]";
}
newfs << "]";
@@ -266,7 +258,13 @@ static bool convert(const String& oldcascade, const String& newcascade)
bool CascadeClassifier::convert(const String& oldcascade, const String& newcascade)
{
bool ok = haar_cvt::convert(oldcascade, newcascade);
FileStorage oldfs(oldcascade, FileStorage::READ);
FileStorage newfs(newcascade, FileStorage::WRITE);
if( !oldfs.isOpened() || !newfs.isOpened() )
return false;
FileNode oldroot = oldfs.getFirstTopLevelNode();
bool ok = haar_cvt::convert(oldroot, newfs);
if( !ok && newcascade.size() > 0 )
remove(newcascade.c_str());
return ok;
+59 -53
View File
@@ -102,26 +102,6 @@ typedef struct CvHidHaarClassifierCascade
const int icv_object_win_border = 1;
const float icv_stage_threshold_bias = 0.0001f;
static CvHaarClassifierCascade*
icvCreateHaarClassifierCascade( int stage_count )
{
CvHaarClassifierCascade* cascade = 0;
int block_size = sizeof(*cascade) + stage_count*sizeof(*cascade->stage_classifier);
if( stage_count <= 0 )
CV_Error( CV_StsOutOfRange, "Number of stages should be positive" );
cascade = (CvHaarClassifierCascade*)cvAlloc( block_size );
memset( cascade, 0, block_size );
cascade->stage_classifier = (CvHaarStageClassifier*)(cascade + 1);
cascade->flags = CV_HAAR_MAGIC_VAL;
cascade->count = stage_count;
return cascade;
}
static void
icvReleaseHidHaarClassifierCascade( CvHidHaarClassifierCascade** _cascade )
{
@@ -1057,7 +1037,6 @@ public:
}
CvSeq*
cvHaarDetectObjectsForROC( const CvArr* _img,
CvHaarClassifierCascade* cascade, CvMemStorage* storage,
@@ -1373,6 +1352,32 @@ cvHaarDetectObjects( const CvArr* _img,
}
CV_IMPL void
cvReleaseHaarClassifierCascade( CvHaarClassifierCascade** _cascade )
{
if( _cascade && *_cascade )
{
int i, j;
CvHaarClassifierCascade* cascade = *_cascade;
for( i = 0; i < cascade->count; i++ )
{
for( j = 0; j < cascade->stage_classifier[i].count; j++ )
cvFree( &cascade->stage_classifier[i].classifier[j].haar_feature );
cvFree( &cascade->stage_classifier[i].classifier );
}
icvReleaseHidHaarClassifierCascade( &cascade->hid_cascade );
cvFree( _cascade );
}
}
CV_IMPL CvHaarClassifierCascade*
cvLoadHaarClassifierCascade( const char*, CvSize )
{
return 0;
}
#if 0
static CvHaarClassifierCascade*
icvLoadCascadeCART( const char** input_cascade, int n, CvSize orig_window_size )
@@ -1398,7 +1403,7 @@ icvLoadCascadeCART( const char** input_cascade, int n, CvSize orig_window_size )
CV_Assert( count > 0 && count < CV_HAAR_STAGE_MAX);
cascade->stage_classifier[i].count = count;
cascade->stage_classifier[i].classifier =
(CvHaarClassifier*)cvAlloc( count*sizeof(cascade->stage_classifier[i].classifier[0]));
(CvHaarClassifier*)cvAlloc( count*sizeof(cascade->stage_classifier[i].classifier[0]));
for( j = 0; j < count; j++ )
{
@@ -1411,11 +1416,11 @@ icvLoadCascadeCART( const char** input_cascade, int n, CvSize orig_window_size )
CV_Assert( classifier->count > 0 && classifier->count< CV_HAAR_STAGE_MAX);
classifier->haar_feature = (CvHaarFeature*) cvAlloc(
classifier->count * ( sizeof( *classifier->haar_feature ) +
sizeof( *classifier->threshold ) +
sizeof( *classifier->left ) +
sizeof( *classifier->right ) ) +
(classifier->count + 1) * sizeof( *classifier->alpha ) );
classifier->count * ( sizeof( *classifier->haar_feature ) +
sizeof( *classifier->threshold ) +
sizeof( *classifier->left ) +
sizeof( *classifier->right ) ) +
(classifier->count + 1) * sizeof( *classifier->alpha ) );
classifier->threshold = (float*) (classifier->haar_feature+classifier->count);
classifier->left = (int*) (classifier->threshold + classifier->count);
classifier->right = (int*) (classifier->left + classifier->count);
@@ -1433,8 +1438,8 @@ icvLoadCascadeCART( const char** input_cascade, int n, CvSize orig_window_size )
cv::Rect r;
int band = 0;
sscanf( stage, "%d%d%d%d%d%f%n",
&r.x, &r.y, &r.width, &r.height, &band,
&(classifier->haar_feature[l].rect[k].weight), &dl );
&r.x, &r.y, &r.width, &r.height, &band,
&(classifier->haar_feature[l].rect[k].weight), &dl );
stage += dl;
classifier->haar_feature[l].rect[k].r = cvRect(r);
}
@@ -1446,12 +1451,12 @@ icvLoadCascadeCART( const char** input_cascade, int n, CvSize orig_window_size )
for( k = rects; k < CV_HAAR_FEATURE_MAX; k++ )
{
memset( classifier->haar_feature[l].rect + k, 0,
sizeof(classifier->haar_feature[l].rect[k]) );
sizeof(classifier->haar_feature[l].rect[k]) );
}
sscanf( stage, "%f%d%d%n", &(classifier->threshold[l]),
&(classifier->left[l]),
&(classifier->right[l]), &dl );
&(classifier->left[l]),
&(classifier->right[l]), &dl );
stage += dl;
}
for( l = 0; l <= classifier->count; l++ )
@@ -1557,27 +1562,6 @@ cvLoadHaarClassifierCascade( const char* directory, CvSize orig_window_size )
return cascade;
}
CV_IMPL void
cvReleaseHaarClassifierCascade( CvHaarClassifierCascade** _cascade )
{
if( _cascade && *_cascade )
{
int i, j;
CvHaarClassifierCascade* cascade = *_cascade;
for( i = 0; i < cascade->count; i++ )
{
for( j = 0; j < cascade->stage_classifier[i].count; j++ )
cvFree( &cascade->stage_classifier[i].classifier[j].haar_feature );
cvFree( &cascade->stage_classifier[i].classifier );
}
icvReleaseHidHaarClassifierCascade( &cascade->hid_cascade );
cvFree( _cascade );
}
}
/****************************************************************************************\
* Persistence functions *
\****************************************************************************************/
@@ -1605,6 +1589,26 @@ icvIsHaarClassifier( const void* struct_ptr )
return CV_IS_HAAR_CLASSIFIER( struct_ptr );
}
static CvHaarClassifierCascade*
icvCreateHaarClassifierCascade( int stage_count )
{
CvHaarClassifierCascade* cascade = 0;
int block_size = sizeof(*cascade) + stage_count*sizeof(*cascade->stage_classifier);
if( stage_count <= 0 )
CV_Error( CV_StsOutOfRange, "Number of stages should be positive" );
cascade = (CvHaarClassifierCascade*)cvAlloc( block_size );
memset( cascade, 0, block_size );
cascade->stage_classifier = (CvHaarStageClassifier*)(cascade + 1);
cascade->flags = CV_HAAR_MAGIC_VAL;
cascade->count = stage_count;
return cascade;
}
static void*
icvReadHaarClassifier( CvFileStorage* fs, CvFileNode* node )
{
@@ -2124,4 +2128,6 @@ CvType haar_type( CV_TYPE_NAME_HAAR, icvIsHaarClassifier,
icvReadHaarClassifier, icvWriteHaarClassifier,
icvCloneHaarClassifier );
#endif
/* End of file. */
-56
View File
@@ -2118,62 +2118,6 @@ void HOGDescriptor::detectMultiScale(InputArray img, std::vector<Rect>& foundLoc
padding, scale0, finalThreshold, useMeanshiftGrouping);
}
template<typename _ClsName> struct RTTIImpl
{
public:
static int isInstance(const void* ptr)
{
static _ClsName dummy;
static void* dummyp = &dummy;
union
{
const void* p;
const void** pp;
} a, b;
a.p = dummyp;
b.p = ptr;
return *a.pp == *b.pp;
}
static void release(void** dbptr)
{
if(dbptr && *dbptr)
{
delete (_ClsName*)*dbptr;
*dbptr = 0;
}
}
static void* read(CvFileStorage* fs, CvFileNode* n)
{
FileNode fn(fs, n);
_ClsName* obj = new _ClsName;
if(obj->read(fn))
return obj;
delete obj;
return 0;
}
static void write(CvFileStorage* _fs, const char* name, const void* ptr, CvAttrList)
{
if(ptr && _fs)
{
FileStorage fs(_fs, false);
((const _ClsName*)ptr)->write(fs, String(name));
}
}
static void* clone(const void* ptr)
{
if(!ptr)
return 0;
return new _ClsName(*(const _ClsName*)ptr);
}
};
typedef RTTIImpl<HOGDescriptor> HOGRTTI;
CvType hog_type( CV_TYPE_NAME_HOG_DESCRIPTOR, HOGRTTI::isInstance,
HOGRTTI::release, HOGRTTI::read, HOGRTTI::write, HOGRTTI::clone);
std::vector<float> HOGDescriptor::getDefaultPeopleDetector()
{
static const float detector[] = {