Flame 1 Жалоба Опубликовано June 10, 2012 ага, вроде разобрался. dctSize - Размер окна в котором будем находить коэффициенты ДКП obsSize - Количество значимых коэффициентов. delta - А вот это сдвиг (в пикселях?) только я не совсем понял, в дефолтных параметрах размер сдвига 4 на 4, тоесть всего лишь по 4 пикселя раждый раз? и еще непонятно почему в исходниках #define MAX_DCT_SIZE 32 тоесть максимум окно может быть 32 х 32 пикселя. Тоесть не получится сканировать например прямоугольным окном чисто по вертикали. Видимо создатели библиотеки посчитали 32 максимально оптимальным Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано June 10, 2012 Самый простой способ, разобраться с работой функции вытащить ее к себе в исходник и посмотреть её работу в отладчике, можно и с параметрами поэкспериментировать. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
RamaChandra 0 Жалоба Опубликовано February 11, 2014 Дорогие друзья! Увидел здесь много умных людей, прошу вашей помощи. Очень важно. Программа распознавание лиц HMM. Так и не понял как решить эту проблему с функцией cvEstimateObsProb Пробовал OpenCV 2.3.1, 2.4.3, 2.4.6 - 2.4.8 Visual studio 2010 и 2012. Подскажите, люди добрые, что делать? void EHMMObjRecognition::Train( ImgObj &imgObj, EHMMObj &ehmmObj ) { const int MAX_ITER = 80; const double STOP_STEP_ITER = 0.01; CvImgObsInfo **obsInfoVec; IplImage *iplImg; int obsVecLen = _noDCTCoeff.width * _noDCTCoeff.height; CvSize _noObs; CvEHMM *tmplEhmm = ehmmObj.GetEHMM( ).GetCvEHMM( ); int numImages = (int)imgObj.GetNoImages( ); bool trained = false; float oldLikelihood = 0; int counter = 0; int i; assert( _imgWidth != -1 ); assert( _imgHeight != -1 ); if( _suppressIntensity ) { //Suppress first DCT coefficient obsVecLen--; } //Create the obsinfo array obsInfoVec = new CvImgObsInfo*[ numImages ]; assert( obsInfoVec != 0 ); for( i = 0; i < numImages; i++ ) { iplImg = imgObj.GetGrayScaleImage( i, _imgWidth, _imgHeight ); //Get how many DCT transforms we compute CountObs( *iplImg->roi, _dctSize, _stepSize, _noObs ); //Create the observation for each of the transforms obsInfoVec[ i ] = cvCreateObsInfo( _noObs, obsVecLen ); if( _suppressIntensity ) { float *observations = new float[ _noObs.height * _noObs.width * ( obsVecLen + 1 ) ]; cvImgToObs_DCT( iplImg, observations, _dctSize, _noDCTCoeff, _stepSize ); ExtractDCT( observations, obsInfoVec[ i ]->obs, _noObs.height * _noObs.width, obsVecLen ); if ( observations ) { delete( observations); } } else { cvImgToObs_DCT( iplImg, obsInfoVec[ i ]->obs, _dctSize, _noDCTCoeff, _stepSize ); } cvUniformImgSegm( obsInfoVec[ i ], tmplEhmm ); cvReleaseImage( &iplImg ); } cvInitMixSegm( obsInfoVec, numImages, tmplEhmm ); //Start the iterative training procedure while( ( !trained ) && ( counter < MAX_ITER ) ) { int j; float likelihood = 0; counter++; cvEstimateHMMStateParams( obsInfoVec, numImages, tmplEhmm ); cvEstimateTransProb( obsInfoVec, numImages, tmplEhmm); for( j = 0; j < numImages; j++ ) { cvEstimateObsProb( obsInfoVec[ j ], tmplEhmm ); /// в этой функции //причем первую итерацию завершает без ошибок // со второй выдает assertion failed и программа выходит likelihood += cvEViterbi( obsInfoVec[ j ], tmplEhmm ); } likelihood /= numImages * obsInfoVec[ 0 ]->obs_size; cvMixSegmL2( &obsInfoVec[ 0 ], numImages, tmplEhmm ); trained = ( fabs( likelihood - oldLikelihood ) < STOP_STEP_ITER ); oldLikelihood = likelihood; } //Clear the observations for( i = 0; i < numImages; i++ ) { cvReleaseObsInfo( &(obsInfoVec[ i ]) ); } delete []obsInfoVec; ehmmObj.GetEHMM( ).SetTrained( trained ); } что пишет: Assertion failed file: ...opencv\modules\legacy\src\hmm.cpp line: 636 Expression: sizeof(float*)==sizeof(int) Сам кусочек из hmm.cpp static CvStatus CV_STDCALL icvEstimateObsProb( CvImgObsInfo* obs_info, CvEHMM* hmm ) { int i, j; int total_states = 0; /* check if matrix exist and check current size if not sufficient - realloc */ int status = 0; /* 1 - not allocated, 2 - allocated but small size, 3 - size is enough, but distribution is bad, 0 - all ok */ for( j = 0; j < hmm->num_states; j++ ) { total_states += hmm->u.ehmm[j].num_states; } if ( hmm->obsProb == NULL ) { /* allocare memory */ int need_size = ( obs_info->obs_x * obs_info->obs_y * total_states * sizeof(float) + obs_info->obs_y * hmm->num_states * sizeof( CvMatr32f) ); int* buffer = (int*)cvAlloc( need_size + 3 * sizeof(int) ); buffer[0] = need_size; buffer[1] = obs_info->obs_y; buffer[2] = obs_info->obs_x; hmm->obsProb = (float**) (buffer + 3); status = 3; } else { /* check current size */ int* total= (int*)(((int*)(hmm->obsProb)) - 3); int need_size = ( obs_info->obs_x * obs_info->obs_y * total_states * sizeof(float) + obs_info->obs_y * hmm->num_states * sizeof( CvMatr32f/*(float*)*/ ) ); assert( sizeof(float*) == sizeof(int) ); /////////вот здесь. соответственно возвращает 3 if ( need_size > (*total) ) { int* buffer = ((int*)(hmm->obsProb)) - 3; cvFree( &buffer); buffer = (int*)cvAlloc( need_size + 3 * sizeof(int)); buffer[0] = need_size; buffer[1] = obs_info->obs_y; buffer[2] = obs_info->obs_x; hmm->obsProb = (float**)(buffer + 3); status = 3; } } if (!status) { int* obsx = ((int*)(hmm->obsProb)) - 1; int* obsy = ((int*)(hmm->obsProb)) - 2; assert( (*obsx > 0) && (*obsy > 0) ); /* is good distribution? */ if ( (obs_info->obs_x > (*obsx) ) || (obs_info->obs_y > (*obsy) ) ) status = 3; } ...... Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано February 11, 2014 Есть подозрение что это assert( sizeof(float*) == sizeof(int) ); Возникает на 64 разрядных машинках. Так как размер указателей зависит от установленной разрядности. Размер int на windows имеет размер 4 байта. А размер указателя на память в 32 разрядной версии равен 32, а в 64 разрядной 64. Вот и выбрасывается исключение. Можете попробовать соорудить 32 разрядную версию, нужно только установить 32 разрядных OpenCV, и создать 32-разрядный профиль проекта. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано June 11, 2014 Реанимировал распознавалку на марковских моделях. Правда сыро все пока, больше всего сомнений вызывает выделение памяти, см. мои пометки в файле hmm.cpp строки 28,29. Распознает вроде все все отлично, но надо допиливать под нормальный C++. Если у кого руки до этого дойдут, прошу поучаствовать. HMM.RAR Как тестить: 1) запустить 2) выбрать папку faces 3) подождать 4) нажимать кнопку, он выдаст фотки из обучающей выборки, лица которое он распознал по невиданной ранее фотке этого лица. 5) нажать кнопку в консоли. Предъявляемый невиданный индивид задается в файле main.cpp строчках 345,346. 1 Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
mrgloom 242 Жалоба Опубликовано June 16, 2014 а откуда изначально сорцы? в legacy модуле opencv тоже есть что то посвященное HMM https://github.com/Itseez/opencv/blob/ff9a0815b9ad88f09bc55e8b8320745aa94869da/modules/legacy/include/opencv2/legacy.hpp https://github.com/Itseez/opencv/blob/ef91d7e8830c36785f0b6fdbf2045da48413dd76/modules/legacy/src/hmmobs.cpp https://github.com/Itseez/opencv/blob/e59c74e1c7672ad16056f32136a491b1e008e295/modules/legacy/src/hmm.cpp Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано June 16, 2014 Из opencv-шного legacy (то, что Вы указали, они не хотели у меня работать из-за assert-a ) и те, что вначале темы для билдера. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Krok27 1 Жалоба Опубликовано November 24, 2014 Сохранение и загрузка сохраненной модели: Сохранение: void HMM_Save( const std::string &fileName, CvEHMM* _ehmm, int _vecSize ) { int i = 0; int j = 0; int m = 0; int k = 0; vector<int> NumStates; assert( _ehmm != 0 ); FileStorage fs; fs.open(fileName, FileStorage::WRITE); if(!fs.isOpened()) return; // записываем топологию fs << "NumSuperStates" << _ehmm->num_states; fs << "NumStates" << "["; for( i = 0; i < _ehmm->num_states; i++ ) { fs << _ehmm->u.ehmm[ i ].num_states; } fs << "]"; fs << "NumGaussMixtures" << "["; for( i = 0; i < _ehmm->num_states; i++ ) { CvEHMM* ehmm = &( _ehmm->u.ehmm[ i ] ); for( int j = 0; j < ehmm->num_states; j++ ) { fs << ehmm->u.state[ j ].num_mix ; } } fs << "]"; fs << "VecSize" << _vecSize; //Пишем все hmms CvEHMM* hmm = _ehmm; fs << "DataHMM" << "{"; for( i = 0; i < _ehmm->num_states + 1; i++ ) { if ( hmm->level == 0 ) { fs << "EmbeddedHMM"+ToString(i) << "{" ; } else { fs << "ExternalHMM" << "{" ; } fs << "NumStates" << hmm->num_states; if ( hmm->level == 0 ) { for ( j = 0; j < hmm->num_states; j++) { CvEHMMState* state = &( hmm->u.state[ j ] ); fs << "State" + ToString(j) << "{"; fs << "NumMixes" << state->num_mix; float* mu = state->mu; float* inv_var = state->inv_var; for( m = 0; m < state->num_mix; m++) { fs << "Mixture" + ToString(m)<< "{"; fs << "Weight" << state->weight[ m ]; fs << "Mean" << "[" ; for ( k = 0; k < _vecSize; k++) { fs << mu[ 0 ]; mu++; } fs << "]" ; // mean fs << "Inverted_Deviation" << "["; for ( k = 0; k < _vecSize; k++) { fs << inv_var[ 0 ]; inv_var++; } fs << "]"; //Inverted_Deviation fs << "LogVarVal" << state->log_var_val[ m ]; fs << "}"; //mixture } fs << "}";// state } } // fs << "TransP" << "["; float* prob = hmm->transP; for ( int j = 0; j < hmm->num_states; j++) { for ( int k = 0; k < hmm->num_states; k++) { fs << *prob; prob++; } } fs << "]"; //TransP fs << "}"; // EmbeddedHMM или ExternalHMM hmm = &( _ehmm->u.ehmm[ i ] ); } fs << "}"; //DataHMM fs.release(); } //***************************************************************************** Загрузка: bool HMM_Load( const string &fileName, CvEHMM** _ehmm) { vector<int> states; vector<int> GaussMix; vector<float> TransP; vector<float> Mean; string Tmp; int NumSuperStates = 0; int VecSize = 0; FileStorage fs; fs.open(fileName, FileStorage::READ | FileStorage::FORMAT_XML); if(!fs.isOpened()) return false; fs["NumSuperStates"] >> NumSuperStates; fs["NumStates"] >> states; states.insert(states.begin(),NumSuperStates); int size = states.size(); fs["NumGaussMixtures"] >> GaussMix; fs["VecSize"] >> VecSize; (*_ehmm) = cvCreate2DHMM( &states[0], &GaussMix[0], VecSize); CvEHMM* hmm = *_ehmm; FileNode DataHMM = fs["DataHMM"]; int idx = 0; FileNodeIterator it_beg = DataHMM.begin(); FileNodeIterator it_end = DataHMM.end(); for(it_beg; it_beg != it_end; ++it_beg, ++idx) { if(idx != 0) { for(int j=0; j < states[idx]; j++) { FileNode node = (*it_beg)["State"+ToString(j)];//State0 int count = node.size(); string name = node.name(); CvEHMMState* state = &( hmm->u.state[ j ] ); float* mu = state->mu; float* inv_var = state->inv_var; for( int m = 0; m < state->num_mix; m++) { FileNode node_mix = node["Mixture"+ToString(m)]; Mean.clear(); state->weight[ m ] = node_mix["Weight"]; node_mix["Mean"] >> Mean; for ( int k = 0; k < VecSize; k++) { (*mu) = Mean[k]; ++mu; } Mean.clear(); node_mix["Inverted_Deviation"] >> Mean; for ( int k = 0; k < VecSize; k++) { (*inv_var) = Mean[k]; ++inv_var; } state->log_var_val[ m ] = node_mix["LogVarVal"]; } } } TransP.clear(); (*it_beg)["TransP"] >> TransP; float* prob = hmm->transP; int counter = 0; for ( int j = 0; j < hmm->num_states; j++) { for ( int k = 0; k < hmm->num_states; k++) { *prob = TransP[counter++]; prob++; } } hmm = &( (*_ehmm)->u.ehmm[ idx] ); } return true; } 1 Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
count0 0 Жалоба Опубликовано March 10, 2016 Господа, пример с HMM грешит утечками, как чиновник взятками. Часть вроде поправил, сейчас бьюсь с этим куском: // Рассчитываем, сколько нужно произвести ДКП (DCT) noObs.width = ( img->width - dctSize.width + stepSize.width ) / stepSize.width; noObs.height = ( img->height - dctSize.height + stepSize.height ) / stepSize.height; info = cvCreateObsInfo( noObs, obsVecLen ); <<--- Большая, жирная утечка. По мегабайту-двум за 1 выполнение. assert( info != 0 ); И далее: if( SUPPRESS_INTESITY ) { float *observations = new float[ noObs.height * noObs.width * ( obsVecLen + 1 ) ]; cvImgToObs_DCT( img, observations, dctSize, noDCTCoeff, stepSize ); ExtractDCT( observations, info->obs, noObs.height * noObs.width, obsVecLen ); <<--- Маленькая утечка, по 0.5 Мб за проход. if ( observations ) { delete( observations); } } else { cvImgToObs_DCT( img, info->obs, dctSize, noDCTCoeff, stepSize ); } cvEstimateObsProb( info, &tmplEhmm ); Добавил в конце функции распознавания (после return) cvReleaseObsInfo(&info); delete info; Не помогло особо. Есть мысли? Версия опенцв 1я вроде. ----------------------- P. S. Вроде нашёл как правильно память чистить. В конце Compute...: float temp; temp=cvEViterbi( info, &tmplEhmm ); cvReleaseObsInfo(&info); delete info; return temp; Теперь память не утекает. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
count0 0 Жалоба Опубликовано March 25, 2016 Где-то в коде загрузки, или сохранения модели закрался косячек. Сохранять сохраняет, грузит, но потом при ComputeLikeHood вываливается в segfault после 1го сравнения. Причем значение выдает правильное, как при обычном обучении. Сообщение об ошибке в opencv_legacy, а в какой функции - не говорит. Куда копать - пока не знаю. Опытным путем установлено, что ошибка возникает тут: cvEstimateObsProb( info, &tmplEhmm ); // Here!! Однако, если эту строку закомментировать, она всё равно вывалится. Значит, cvEViterbi( info, &tmplEhmm ); работает некорректно. Что-то в загруженной модели не так. Накосячить я мог только в одном месте - размере vecSize, который передается HMM_Save при сохранении. Пробовал значения vecSizeM = NO_DCT_COEFF_X * NO_DCT_COEFF_Y - 1; Без -1. Просто от балды. Не работает. Кто-нибудь делал загрузку и сохранение модели? Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано March 25, 2016 В коде больше не копался, но есть подозрение что память под объект не выделяется (может где new воткнуть надо). Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
count0 0 Жалоба Опубликовано March 25, 2016 А в новой версии opencv нет реализации hmm? Нашёл реализации LBPH и SVM, там вообще модель в 3 строки инициализируется, в 2 - сохраняется-загружается. Но HMM показывает самые лучшие результаты. Гоняю сейчас на выборке в 300 человек, по 3 фото. И модель строится долговато, минуты 3. Ей бы загрузку-сохранение допилить - будет красота. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах