now C++ classes can be read/written with cvRead/cvWrite/cvLoad/cvSave. Tested on...
authorVadim Pisarevsky <no@email>
Tue, 1 Jun 2010 13:53:20 +0000 (13:53 +0000)
committerVadim Pisarevsky <no@email>
Tue, 1 Jun 2010 13:53:20 +0000 (13:53 +0000)
modules/core/include/opencv2/core/operations.hpp
modules/objdetect/include/opencv2/objdetect/objdetect.hpp
modules/objdetect/src/hog.cpp

index 8e02a68..b0b56bb 100644 (file)
@@ -2622,6 +2622,51 @@ template<typename _Tp> inline bool operator != (const SeqIterator<_Tp>& a,
     return !(a == b);
 }
 
+
+template<typename _ClsName> struct CV_EXPORTS RTTIImpl
+{
+public:
+    static int isInstance(const void* ptr)
+    {
+        static _ClsName dummy;
+        return *(const void**)&dummy == *(const void**)ptr;
+    }
+    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);
+            fs.fs.addref();
+            ((const _ClsName*)ptr)->write(fs, string(name));
+        }
+    }
+    
+    static void* clone(const void* ptr)
+    {
+        if(!ptr)
+            return 0;
+        return new _ClsName(*(const _ClsName*)ptr);
+    }
+};
+    
 }
 
 #endif // __cplusplus
index db1bc25..78e8d3f 100644 (file)
@@ -257,6 +257,11 @@ public:
         load(filename);
     }
     
+    HOGDescriptor(const HOGDescriptor& d)
+    {
+        d.copyTo(*this);
+    }
+    
     virtual ~HOGDescriptor() {}
     
     size_t getDescriptorSize() const;
@@ -265,8 +270,12 @@ public:
     
     virtual void setSVMDetector(const vector<float>& _svmdetector);
     
+    virtual bool read(FileNode& fn);
+    virtual void write(FileStorage& fs, const String& objname) const;
+    
     virtual bool load(const String& filename, const String& objname=String());
     virtual void save(const String& filename, const String& objname=String()) const;
+    virtual void copyTo(HOGDescriptor& c) const;
     
     virtual void compute(const Mat& img,
                          vector<float>& descriptors,
index b237282..9b6c30f 100644 (file)
@@ -87,10 +87,10 @@ void HOGDescriptor::setSVMDetector(const vector<float>& _svmDetector)
     CV_Assert( checkDetectorSize() );
 }
 
-bool HOGDescriptor::load(const String& filename, const String& objname)
+#define CV_TYPE_NAME_HOG_DESCRIPTOR "opencv-object-detector-hog"
+
+bool HOGDescriptor::read(FileNode& obj)
 {
-    FileStorage fs(filename, FileStorage::READ);
-    FileNode obj = !objname.empty() ? fs[objname] : fs.getFirstTopLevelNode();
     if( !obj.isMap() )
         return false;
     FileNodeIterator it = obj["winSize"].begin();
@@ -107,7 +107,7 @@ bool HOGDescriptor::load(const String& filename, const String& objname)
     obj["histogramNormType"] >> histogramNormType;
     obj["L2HysThreshold"] >> L2HysThreshold;
     obj["gammaCorrection"] >> gammaCorrection;
-
+    
     FileNode vecNode = obj["SVMDetector"];
     if( vecNode.isSeq() )
     {
@@ -116,27 +116,56 @@ bool HOGDescriptor::load(const String& filename, const String& objname)
     }
     return true;
 }
-
-void HOGDescriptor::save(const String& filename, const String& objName) const
+    
+void HOGDescriptor::write(FileStorage& fs, const String& objName) const
 {
-    FileStorage fs(filename, FileStorage::WRITE);
-    fs << (!objName.empty() ? objName : FileStorage::getDefaultObjectName(filename)) << "{";
-
-    fs  << "winSize" << winSize
-        << "blockSize" << blockSize
-        << "blockStride" << blockStride
-        << "cellSize" << cellSize
-        << "nbins" << nbins
-        << "derivAperture" << derivAperture
-        << "winSigma" << getWinSigma()
-        << "histogramNormType" << histogramNormType
-        << "L2HysThreshold" << L2HysThreshold
-        << "gammaCorrection" << gammaCorrection;
+    if( !objName.empty() )
+        fs << objName;
+    
+    fs << "{" CV_TYPE_NAME_HOG_DESCRIPTOR
+    << "winSize" << winSize
+    << "blockSize" << blockSize
+    << "blockStride" << blockStride
+    << "cellSize" << cellSize
+    << "nbins" << nbins
+    << "derivAperture" << derivAperture
+    << "winSigma" << getWinSigma()
+    << "histogramNormType" << histogramNormType
+    << "L2HysThreshold" << L2HysThreshold
+    << "gammaCorrection" << gammaCorrection;
     if( !svmDetector.empty() )
         fs << "SVMDetector" << "[:" << svmDetector << "]";
     fs << "}";
 }
+    
+bool HOGDescriptor::load(const String& filename, const String& objname)
+{
+    FileStorage fs(filename, FileStorage::READ);
+    FileNode obj = !objname.empty() ? fs[objname] : fs.getFirstTopLevelNode();
+    return read(obj);
+}
+
+void HOGDescriptor::save(const String& filename, const String& objName) const
+{
+    FileStorage fs(filename, FileStorage::WRITE);
+    write(fs, !objName.empty() ? objName : FileStorage::getDefaultObjectName(filename));
+}
 
+void HOGDescriptor::copyTo(HOGDescriptor& c) const
+{
+    c.winSize = winSize;
+    c.blockSize = blockSize;
+    c.blockStride = blockStride;
+    c.cellSize = cellSize;
+    c.nbins = nbins;
+    c.derivAperture = derivAperture;
+    c.winSigma = winSigma;
+    c.histogramNormType = histogramNormType;
+    c.L2HysThreshold = L2HysThreshold;
+    c.gammaCorrection = gammaCorrection;
+    c.svmDetector = svmDetector;
+}
+    
 void HOGDescriptor::computeGradient(const Mat& img, Mat& grad, Mat& qangle,
                                     Size paddingTL, Size paddingBR) const
 {
@@ -870,6 +899,12 @@ void HOGDescriptor::detectMultiScale(
     groupRectangles(foundLocations, groupThreshold, 0.2);
 }
 
+    
+typedef RTTIImpl<HOGDescriptor> HOGRTTI;
+
+CvType hog_type( CV_TYPE_NAME_HOG_DESCRIPTOR, HOGRTTI::isInstance,
+                 HOGRTTI::release, HOGRTTI::read, HOGRTTI::write, HOGRTTI::clone);
+    
 vector<float> HOGDescriptor::getDefaultPeopleDetector()
 {
     static const float detector[] = {