roserek Temat założony przez niniejszego użytkownika |
dziedziczenie w programie klasy z biblioteki » 2013-07-13 12:26:59 Witam. Próbuję napisać program który będzie rozpoznawał twarze. Używam do tego biblioteki opencv i gotowej klasy z tej biblioteki fisherface. Ta klasa uczy się twarzy za pomocą metod train i save, zapisuje wektory zdjęć do pliku yml. W tym miejscy chciałbym wnieść poprawki w tej klasie aby te funkcje nie zapisywały wektorów do pliku ale bezpośrednio do bazy danych mysql. Zastanawiam się jak będzie lepiej to zrobić, czy zmienić funkcję w bibliotece ( ale tutaj jest problem ponieważ samo zmienianie kodu nie pomaga, trzeba chyba jeszcze przekompilować bibliotekę a nie wiem jak to zrobić ), innym pomysłem jest napisanie nowej klasy w moim programie która będzie dziedziczyć po klasie fisherface z biblioteki i nadpisać interesujące mnie funkcje. W tej chwili jestem bardziej przychylny tej drugiej opcji ale nie mogę sobie poradzić z dziedziczeniem, cały czas jak próbuję dziedziczyć pokazuje mi błąd: "not a class or struct name" , czyli nie widzi tej klasy. Dlatego moje pytanie czy ktoś wie jak odziedziczyć klasę z biblioteki , czy w ogóle jest to możliwe ??? Przekopałem już całe google i nic nie znalazłem konkretnego na ten temat. |
|
pekfos |
» 2013-07-13 13:13:05 Po każdej klasie można dziedziczyć, ale czasem nie ma sensu tego robić. cały czas jak próbuję dziedziczyć pokazuje mi błąd: "not a class or struct name" , czyli nie widzi tej klasy. |
Błąd jest w twoim kodzie i/lub w OpenCV nie da się tego zrobić. Podaj kod.. |
|
roserek Temat założony przez niniejszego użytkownika |
» 2013-07-13 13:33:21 Podejrzewam, że na pewno błąd jest w moim kodzie. Nigdy nie potrzebowałem takich zabiegów jak poprawki biblioteki... Mój kod nie jest rozbudowany, ponieważ cały czas się zastanawiam czemu nie mogę odziedziczyć. Ale ok kopiuję swój "kod" i najważniejsze fragmenty pliku *.cpp z biblioteki (które mnie interesują). kod biblioteki: #include "precomp.hpp" #include <set>
namespace cv { using std::set; template < typename _Tp > inline void readFileNodeList( const FileNode & fn, vector < _Tp >& result ) { if( fn.type() == FileNode::SEQ ) { for( FileNodeIterator it = fn.begin(); it != fn.end(); ) { _Tp item; it >> item; result.push_back( item ); } } } template < typename _Tp > inline void writeFileNodeList( FileStorage & fs, const string & name, const vector < _Tp >& items ) { typedef typename vector < _Tp >::const_iterator constVecIterator; fs << name << "["; for( constVecIterator it = items.begin(); it != items.end(); ++it ) { fs << * it; } fs << "]"; } static Mat asRowMatrix( InputArrayOfArrays src, int rtype, double alpha = 1, double beta = 0 ) { if( src.kind() != _InputArray::STD_VECTOR_MAT && src.kind() != _InputArray::STD_VECTOR_VECTOR ) { string error_message = "The data is expected as InputArray::STD_VECTOR_MAT (a std::vector<Mat>) or _InputArray::STD_VECTOR_VECTOR (a std::vector< vector<...> >)."; CV_Error( CV_StsBadArg, error_message ); } size_t n = src.total(); if( n == 0 ) return Mat(); size_t d = src.getMat( 0 ).total(); Mat data(( int ) n,( int ) d, rtype ); for( unsigned int i = 0; i < n; i++ ) { if( src.getMat( i ).total() != d ) { string error_message = format( "Wrong number of elements in matrix #%d! Expected %d was %d.", i, d, src.getMat( i ).total() ); CV_Error( CV_StsBadArg, error_message ); } Mat xi = data.row( i ); if( src.getMat( i ).isContinuous() ) { src.getMat( i ).reshape( 1, 1 ).convertTo( xi, rtype, alpha, beta ); } else { src.getMat( i ).clone().reshape( 1, 1 ).convertTo( xi, rtype, alpha, beta ); } } return data; } template < typename _Tp > inline vector < _Tp > remove_dups( const vector < _Tp >& src ) { typedef typename set < _Tp >::const_iterator constSetIterator; typedef typename vector < _Tp >::const_iterator constVecIterator; set < _Tp > set_elems; for( constVecIterator it = src.begin(); it != src.end(); ++it ) set_elems.insert( * it ); vector < _Tp > elems; for( constSetIterator it = set_elems.begin(); it != set_elems.end(); ++it ) elems.push_back( * it ); return elems; } class Eigenfaces : public FaceRecognizer { private: int _num_components; double _threshold; vector < Mat > _projections; Mat _labels; Mat _eigenvectors; Mat _eigenvalues; Mat _mean; public: using FaceRecognizer::save; using FaceRecognizer::load; Eigenfaces( int num_components = 0, double threshold = DBL_MAX ) : _num_components( num_components ) , _threshold( threshold ) { } Eigenfaces( InputArrayOfArrays src, InputArray labels, int num_components = 0, double threshold = DBL_MAX ) : _num_components( num_components ) , _threshold( threshold ) { train( src, labels ); } void train( InputArrayOfArrays src, InputArray labels ); int predict( InputArray src ) const; void predict( InputArray _src, int & label, double & dist ) const; void load( const FileStorage & fs ); void save( FileStorage & fs ) const; AlgorithmInfo * info() const; }; class Fisherfaces : public FaceRecognizer { private: int _num_components; double _threshold; Mat _eigenvectors; Mat _eigenvalues; Mat _mean; vector < Mat > _projections; Mat _labels; public: using FaceRecognizer::save; using FaceRecognizer::load; myFisherfaces( int num_components = 0, double threshold = DBL_MAX ) : _num_components( num_components ) , _threshold( threshold ) { } myFisherfaces( InputArrayOfArrays src, InputArray labels, int num_components = 0, double threshold = DBL_MAX ) : _num_components( num_components ) , _threshold( threshold ) { train( src, labels ); } ~myFisherfaces() { } void train( InputArrayOfArrays src, InputArray labels ); int predict( InputArray src ) const; void predict( InputArray _src, int & label, double & dist ) const; void load( const FileStorage & fs ); void save( FileStorage & fs ) const; AlgorithmInfo * info() const; }; void Fisherfaces::train( InputArrayOfArrays src, InputArray _lbls ) { if( src.total() == 0 ) { string error_message = format( "Empty training data was given. You'll need more than one sample to learn a model." ); CV_Error( CV_StsBadArg, error_message ); } else if( _lbls.getMat().type() != CV_32SC1 ) { string error_message = format( "Labels must be given as integer (CV_32SC1). Expected %d, but was %d.", CV_32SC1, _lbls.type() ); CV_Error( CV_StsBadArg, error_message ); } if( src.total() > 1 ) { for( int i = 1; i < static_cast < int >( src.total() ); i++ ) { if( src.getMat( i - 1 ).total() != src.getMat( i ).total() ) { string error_message = format( "In the Fisherfaces method all input samples (training images) must be of equal size! Expected %d pixels, but was %d pixels.", src.getMat( i - 1 ).total(), src.getMat( i ).total() ); CV_Error( CV_StsUnsupportedFormat, error_message ); } } } Mat labels = _lbls.getMat(); Mat data = asRowMatrix( src, CV_64FC1 ); int N = data.rows; if( labels.total() !=( size_t ) N ) { string error_message = format( "The number of samples (src) must equal the number of labels (labels)! len(src)=%d, len(labels)=%d.", N, labels.total() ); CV_Error( CV_StsBadArg, error_message ); } else if( labels.rows != 1 && labels.cols != 1 ) { string error_message = format( "Expected the labels in a matrix with one row or column! Given dimensions are rows=%s, cols=%d.", labels.rows, labels.cols ); CV_Error( CV_StsBadArg, error_message ); } _labels.release(); _projections.clear(); vector < int > ll; for( unsigned int i = 0; i < labels.total(); i++ ) { ll.push_back( labels.at < int >( i ) ); } int C =( int ) remove_dups( ll ).size(); if(( _num_components <= 0 ) ||( _num_components >( C - 1 ) ) ) _num_components =( C - 1 ); PCA pca( data, Mat(), CV_PCA_DATA_AS_ROW,( N - C ) ); LDA lda( pca.project( data ), labels, _num_components ); _mean = pca.mean.reshape( 1, 1 ); _labels = labels.clone(); lda.eigenvalues().convertTo( _eigenvalues, CV_64FC1 ); gemm( pca.eigenvectors, lda.eigenvectors(), 1.0, Mat(), 0.0, _eigenvectors, GEMM_1_T ); for( int sampleIdx = 0; sampleIdx < data.rows; sampleIdx++ ) { Mat p = subspaceProject( _eigenvectors, _mean, data.row( sampleIdx ) ); _projections.push_back( p ); } } void Fisherfaces::predict( InputArray _src, int & minClass, double & minDist ) const { Mat src = _src.getMat(); if( _projections.empty() ) { string error_message = "This Fisherfaces model is not computed yet. Did you call Fisherfaces::train?"; CV_Error( CV_StsBadArg, error_message ); } else if( src.total() !=( size_t ) _eigenvectors.rows ) { string error_message = format( "Wrong input image size. Reason: Training and Test images must be of equal size! Expected an image with %d elements, but got %d.", _eigenvectors.rows, src.total() ); CV_Error( CV_StsBadArg, error_message ); } Mat q = subspaceProject( _eigenvectors, _mean, src.reshape( 1, 1 ) ); minDist = DBL_MAX; minClass = - 1; for( size_t sampleIdx = 0; sampleIdx < _projections.size(); sampleIdx++ ) { double dist = norm( _projections[ sampleIdx ], q, NORM_L2 ); if(( dist < minDist ) &&( dist < _threshold ) ) { minDist = dist; minClass = _labels.at < int >(( int ) sampleIdx ); } } } int Fisherfaces::predict( InputArray _src ) const { int label; double dummy; predict( _src, label, dummy ); return label; } void Fisherfaces::load( const FileStorage & fs ) { fs[ "num_components" ] >> _num_components; fs[ "mean" ] >> _mean; fs[ "eigenvalues" ] >> _eigenvalues; fs[ "eigenvectors" ] >> _eigenvectors; readFileNodeList( fs[ "projections" ], _projections ); fs[ "labels" ] >> _labels; } void Fisherfaces::save( FileStorage & fs ) const { write matrices fs << "num_components" << _num_components; fs << "mean" << _mean; fs << "eigenvalues" << _eigenvalues; fs << "eigenvectors" << _eigenvectors; write sequences writeFileNodeList( fs, "projections", _projections ); fs << "labels" << _labels; }
Teraz mój kod - ubogi ;) #pragma once
#include "opencv.hpp" #include <set>
class mojfisher : public Fisherface { public: mojfisher( void ); ~mojfisher( void ); };
|
|
pekfos |
» 2013-07-13 13:37:25 I jak chcesz dziedziczyć po Fisherface skoro takiego typu nie ma? |
|
roserek Temat założony przez niniejszego użytkownika |
» 2013-07-13 13:51:16 Chcę odziedziczyć po tej klasie : class Fisherfaces : public FaceRecognizer { private: int _num_components; double _threshold; Mat _eigenvectors; Mat _eigenvalues; Mat _mean; vector < Mat > _projections; Mat _labels; public: using FaceRecognizer::save; using FaceRecognizer::load; myFisherfaces( int num_components = 0, double threshold = DBL_MAX ) : _num_components( num_components ) , _threshold( threshold ) { } myFisherfaces( InputArrayOfArrays src, InputArray labels, int num_components = 0, double threshold = DBL_MAX ) : _num_components( num_components ) , _threshold( threshold ) { train( src, labels ); } ~myFisherfaces() { } void train( InputArrayOfArrays src, InputArray labels ); int predict( InputArray src ) const; void predict( InputArray _src, int & label, double & dist ) const; void load( const FileStorage & fs ); void save( FileStorage & fs ) const; AlgorithmInfo * info() const; };
Literówka na końcu niema znaczenia. Mój błąd, przy kopiowaniu. Ale po poprawieniu też nie wykrywa. |
|
Monika90 |
» 2013-07-13 13:58:19 Jeżeli ta klasa znajduje się tak jak napisałeś w pliku cpp, a nie w h czy w hpp, to jest oczywiste, że nie możesz z niej dziedziczyć.
Zainteresuj się flagą FileStorage::MEMORY. |
|
pekfos |
» 2013-07-13 14:06:38 Ale po poprawieniu też nie wykrywa |
Nie określiłeś przestrzeni nazw. |
|
roserek Temat założony przez niniejszego użytkownika |
» 2013-07-13 14:15:28 #pragma once
#include "opencv.hpp" #include <set>
using namespace cv;
class mojfisher : public Fisherfaces { public: mojfisher( void ); ~mojfisher( void ); };
Dalej to samo.... Monika90 mogła byś trochę mi to rozjaśnić... (sory za moją tempotę :P) |
|
« 1 » 2 3 |