old_ml_inner_functions.cpp 51 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688
  1. /*M///////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
  4. //
  5. // By downloading, copying, installing or using the software you agree to this license.
  6. // If you do not agree to this license, do not download, install,
  7. // copy or use the software.
  8. //
  9. //
  10. // Intel License Agreement
  11. //
  12. // Copyright (C) 2000, Intel Corporation, all rights reserved.
  13. // Third party copyrights are property of their respective owners.
  14. //
  15. // Redistribution and use in source and binary forms, with or without modification,
  16. // are permitted provided that the following conditions are met:
  17. //
  18. // * Redistribution's of source code must retain the above copyright notice,
  19. // this list of conditions and the following disclaimer.
  20. //
  21. // * Redistribution's in binary form must reproduce the above copyright notice,
  22. // this list of conditions and the following disclaimer in the documentation
  23. // and/or other materials provided with the distribution.
  24. //
  25. // * The name of Intel Corporation may not be used to endorse or promote products
  26. // derived from this software without specific prior written permission.
  27. //
  28. // This software is provided by the copyright holders and contributors "as is" and
  29. // any express or implied warranties, including, but not limited to, the implied
  30. // warranties of merchantability and fitness for a particular purpose are disclaimed.
  31. // In no event shall the Intel Corporation or contributors be liable for any direct,
  32. // indirect, incidental, special, exemplary, or consequential damages
  33. // (including, but not limited to, procurement of substitute goods or services;
  34. // loss of use, data, or profits; or business interruption) however caused
  35. // and on any theory of liability, whether in contract, strict liability,
  36. // or tort (including negligence or otherwise) arising in any way out of
  37. // the use of this software, even if advised of the possibility of such damage.
  38. //
  39. //M*/
  40. #include "old_ml_precomp.hpp"
  41. CvStatModel::CvStatModel()
  42. {
  43. default_model_name = "my_stat_model";
  44. }
  45. CvStatModel::~CvStatModel()
  46. {
  47. clear();
  48. }
  49. void CvStatModel::clear()
  50. {
  51. }
  52. void CvStatModel::save( const char* filename, const char* name ) const
  53. {
  54. CvFileStorage* fs = 0;
  55. CV_FUNCNAME( "CvStatModel::save" );
  56. __BEGIN__;
  57. CV_CALL( fs = cvOpenFileStorage( filename, 0, CV_STORAGE_WRITE ));
  58. if( !fs )
  59. CV_ERROR( CV_StsError, "Could not open the file storage. Check the path and permissions" );
  60. write( fs, name ? name : default_model_name );
  61. __END__;
  62. cvReleaseFileStorage( &fs );
  63. }
  64. void CvStatModel::load( const char* filename, const char* name )
  65. {
  66. CvFileStorage* fs = 0;
  67. CV_FUNCNAME( "CvAlgorithm::load" );
  68. __BEGIN__;
  69. CvFileNode* model_node = 0;
  70. CV_CALL( fs = cvOpenFileStorage( filename, 0, CV_STORAGE_READ ));
  71. if( !fs )
  72. EXIT;
  73. if( name )
  74. model_node = cvGetFileNodeByName( fs, 0, name );
  75. else
  76. {
  77. CvFileNode* root = cvGetRootFileNode( fs );
  78. if( root->data.seq->total > 0 )
  79. model_node = (CvFileNode*)cvGetSeqElem( root->data.seq, 0 );
  80. }
  81. read( fs, model_node );
  82. __END__;
  83. cvReleaseFileStorage( &fs );
  84. }
  85. void CvStatModel::write( CvFileStorage*, const char* ) const
  86. {
  87. OPENCV_ERROR( CV_StsNotImplemented, "CvStatModel::write", "" );
  88. }
  89. void CvStatModel::read( CvFileStorage*, CvFileNode* )
  90. {
  91. OPENCV_ERROR( CV_StsNotImplemented, "CvStatModel::read", "" );
  92. }
  93. CvMat* icvGenerateRandomClusterCenters ( int seed, const CvMat* data,
  94. int num_of_clusters, CvMat* _centers )
  95. {
  96. CvMat* centers = _centers;
  97. CV_FUNCNAME("icvGenerateRandomClusterCenters");
  98. __BEGIN__;
  99. CvRNG rng;
  100. CvMat data_comp, centers_comp;
  101. CvPoint minLoc, maxLoc; // Not used, just for function "cvMinMaxLoc"
  102. double minVal, maxVal;
  103. int i;
  104. int dim = data ? data->cols : 0;
  105. if( ICV_IS_MAT_OF_TYPE(data, CV_32FC1) )
  106. {
  107. if( _centers && !ICV_IS_MAT_OF_TYPE (_centers, CV_32FC1) )
  108. {
  109. CV_ERROR(CV_StsBadArg,"");
  110. }
  111. else if( !_centers )
  112. CV_CALL(centers = cvCreateMat (num_of_clusters, dim, CV_32FC1));
  113. }
  114. else if( ICV_IS_MAT_OF_TYPE(data, CV_64FC1) )
  115. {
  116. if( _centers && !ICV_IS_MAT_OF_TYPE (_centers, CV_64FC1) )
  117. {
  118. CV_ERROR(CV_StsBadArg,"");
  119. }
  120. else if( !_centers )
  121. CV_CALL(centers = cvCreateMat (num_of_clusters, dim, CV_64FC1));
  122. }
  123. else
  124. CV_ERROR (CV_StsBadArg,"");
  125. if( num_of_clusters < 1 )
  126. CV_ERROR (CV_StsBadArg,"");
  127. rng = cvRNG(seed);
  128. for (i = 0; i < dim; i++)
  129. {
  130. CV_CALL(cvGetCol (data, &data_comp, i));
  131. CV_CALL(cvMinMaxLoc (&data_comp, &minVal, &maxVal, &minLoc, &maxLoc));
  132. CV_CALL(cvGetCol (centers, &centers_comp, i));
  133. CV_CALL(cvRandArr (&rng, &centers_comp, CV_RAND_UNI, cvScalarAll(minVal), cvScalarAll(maxVal)));
  134. }
  135. __END__;
  136. if( (cvGetErrStatus () < 0) || (centers != _centers) )
  137. cvReleaseMat (&centers);
  138. return _centers ? _centers : centers;
  139. } // end of icvGenerateRandomClusterCenters
  140. static int CV_CDECL
  141. icvCmpIntegers( const void* a, const void* b )
  142. {
  143. return *(const int*)a - *(const int*)b;
  144. }
  145. static int CV_CDECL
  146. icvCmpIntegersPtr( const void* _a, const void* _b )
  147. {
  148. int a = **(const int**)_a;
  149. int b = **(const int**)_b;
  150. return (a < b ? -1 : 0)|(a > b);
  151. }
  152. static int icvCmpSparseVecElems( const void* a, const void* b )
  153. {
  154. return ((CvSparseVecElem32f*)a)->idx - ((CvSparseVecElem32f*)b)->idx;
  155. }
  156. CvMat*
  157. cvPreprocessIndexArray( const CvMat* idx_arr, int data_arr_size, bool check_for_duplicates )
  158. {
  159. CvMat* idx = 0;
  160. CV_FUNCNAME( "cvPreprocessIndexArray" );
  161. __BEGIN__;
  162. int i, idx_total, idx_selected = 0, step, type, prev = INT_MIN, is_sorted = 1;
  163. uchar* srcb = 0;
  164. int* srci = 0;
  165. int* dsti;
  166. if( !CV_IS_MAT(idx_arr) )
  167. CV_ERROR( CV_StsBadArg, "Invalid index array" );
  168. if( idx_arr->rows != 1 && idx_arr->cols != 1 )
  169. CV_ERROR( CV_StsBadSize, "the index array must be 1-dimensional" );
  170. idx_total = idx_arr->rows + idx_arr->cols - 1;
  171. srcb = idx_arr->data.ptr;
  172. srci = idx_arr->data.i;
  173. type = CV_MAT_TYPE(idx_arr->type);
  174. step = CV_IS_MAT_CONT(idx_arr->type) ? 1 : idx_arr->step/CV_ELEM_SIZE(type);
  175. switch( type )
  176. {
  177. case CV_8UC1:
  178. case CV_8SC1:
  179. // idx_arr is array of 1's and 0's -
  180. // i.e. it is a mask of the selected components
  181. if( idx_total != data_arr_size )
  182. CV_ERROR( CV_StsUnmatchedSizes,
  183. "Component mask should contain as many elements as the total number of input variables" );
  184. for( i = 0; i < idx_total; i++ )
  185. idx_selected += srcb[i*step] != 0;
  186. if( idx_selected == 0 )
  187. CV_ERROR( CV_StsOutOfRange, "No components/input_variables is selected!" );
  188. break;
  189. case CV_32SC1:
  190. // idx_arr is array of integer indices of selected components
  191. if( idx_total > data_arr_size )
  192. CV_ERROR( CV_StsOutOfRange,
  193. "index array may not contain more elements than the total number of input variables" );
  194. idx_selected = idx_total;
  195. // check if sorted already
  196. for( i = 0; i < idx_total; i++ )
  197. {
  198. int val = srci[i*step];
  199. if( val >= prev )
  200. {
  201. is_sorted = 0;
  202. break;
  203. }
  204. prev = val;
  205. }
  206. break;
  207. default:
  208. CV_ERROR( CV_StsUnsupportedFormat, "Unsupported index array data type "
  209. "(it should be 8uC1, 8sC1 or 32sC1)" );
  210. }
  211. CV_CALL( idx = cvCreateMat( 1, idx_selected, CV_32SC1 ));
  212. dsti = idx->data.i;
  213. if( type < CV_32SC1 )
  214. {
  215. for( i = 0; i < idx_total; i++ )
  216. if( srcb[i*step] )
  217. *dsti++ = i;
  218. }
  219. else
  220. {
  221. for( i = 0; i < idx_total; i++ )
  222. dsti[i] = srci[i*step];
  223. if( !is_sorted )
  224. qsort( dsti, idx_total, sizeof(dsti[0]), icvCmpIntegers );
  225. if( dsti[0] < 0 || dsti[idx_total-1] >= data_arr_size )
  226. CV_ERROR( CV_StsOutOfRange, "the index array elements are out of range" );
  227. if( check_for_duplicates )
  228. {
  229. for( i = 1; i < idx_total; i++ )
  230. if( dsti[i] <= dsti[i-1] )
  231. CV_ERROR( CV_StsBadArg, "There are duplicated index array elements" );
  232. }
  233. }
  234. __END__;
  235. if( cvGetErrStatus() < 0 )
  236. cvReleaseMat( &idx );
  237. return idx;
  238. }
  239. CvMat*
  240. cvPreprocessVarType( const CvMat* var_type, const CvMat* var_idx,
  241. int var_count, int* response_type )
  242. {
  243. CvMat* out_var_type = 0;
  244. CV_FUNCNAME( "cvPreprocessVarType" );
  245. if( response_type )
  246. *response_type = -1;
  247. __BEGIN__;
  248. int i, tm_size, tm_step;
  249. //int* map = 0;
  250. const uchar* src;
  251. uchar* dst;
  252. if( !CV_IS_MAT(var_type) )
  253. CV_ERROR( var_type ? CV_StsBadArg : CV_StsNullPtr, "Invalid or absent var_type array" );
  254. if( var_type->rows != 1 && var_type->cols != 1 )
  255. CV_ERROR( CV_StsBadSize, "var_type array must be 1-dimensional" );
  256. if( !CV_IS_MASK_ARR(var_type))
  257. CV_ERROR( CV_StsUnsupportedFormat, "type mask must be 8uC1 or 8sC1 array" );
  258. tm_size = var_type->rows + var_type->cols - 1;
  259. tm_step = var_type->rows == 1 ? 1 : var_type->step/CV_ELEM_SIZE(var_type->type);
  260. if( /*tm_size != var_count &&*/ tm_size != var_count + 1 )
  261. CV_ERROR( CV_StsBadArg,
  262. "type mask must be of <input var count> + 1 size" );
  263. if( response_type && tm_size > var_count )
  264. *response_type = var_type->data.ptr[var_count*tm_step] != 0;
  265. if( var_idx )
  266. {
  267. if( !CV_IS_MAT(var_idx) || CV_MAT_TYPE(var_idx->type) != CV_32SC1 ||
  268. (var_idx->rows != 1 && var_idx->cols != 1) || !CV_IS_MAT_CONT(var_idx->type) )
  269. CV_ERROR( CV_StsBadArg, "var index array should be continuous 1-dimensional integer vector" );
  270. if( var_idx->rows + var_idx->cols - 1 > var_count )
  271. CV_ERROR( CV_StsBadSize, "var index array is too large" );
  272. //map = var_idx->data.i;
  273. var_count = var_idx->rows + var_idx->cols - 1;
  274. }
  275. CV_CALL( out_var_type = cvCreateMat( 1, var_count, CV_8UC1 ));
  276. src = var_type->data.ptr;
  277. dst = out_var_type->data.ptr;
  278. for( i = 0; i < var_count; i++ )
  279. {
  280. //int idx = map ? map[i] : i;
  281. assert( (unsigned)/*idx*/i < (unsigned)tm_size );
  282. dst[i] = (uchar)(src[/*idx*/i*tm_step] != 0);
  283. }
  284. __END__;
  285. return out_var_type;
  286. }
  287. CvMat*
  288. cvPreprocessOrderedResponses( const CvMat* responses, const CvMat* sample_idx, int sample_all )
  289. {
  290. CvMat* out_responses = 0;
  291. CV_FUNCNAME( "cvPreprocessOrderedResponses" );
  292. __BEGIN__;
  293. int i, r_type, r_step;
  294. const int* map = 0;
  295. float* dst;
  296. int sample_count = sample_all;
  297. if( !CV_IS_MAT(responses) )
  298. CV_ERROR( CV_StsBadArg, "Invalid response array" );
  299. if( responses->rows != 1 && responses->cols != 1 )
  300. CV_ERROR( CV_StsBadSize, "Response array must be 1-dimensional" );
  301. if( responses->rows + responses->cols - 1 != sample_count )
  302. CV_ERROR( CV_StsUnmatchedSizes,
  303. "Response array must contain as many elements as the total number of samples" );
  304. r_type = CV_MAT_TYPE(responses->type);
  305. if( r_type != CV_32FC1 && r_type != CV_32SC1 )
  306. CV_ERROR( CV_StsUnsupportedFormat, "Unsupported response type" );
  307. r_step = responses->step ? responses->step / CV_ELEM_SIZE(responses->type) : 1;
  308. if( r_type == CV_32FC1 && CV_IS_MAT_CONT(responses->type) && !sample_idx )
  309. {
  310. out_responses = cvCloneMat( responses );
  311. EXIT;
  312. }
  313. if( sample_idx )
  314. {
  315. if( !CV_IS_MAT(sample_idx) || CV_MAT_TYPE(sample_idx->type) != CV_32SC1 ||
  316. (sample_idx->rows != 1 && sample_idx->cols != 1) || !CV_IS_MAT_CONT(sample_idx->type) )
  317. CV_ERROR( CV_StsBadArg, "sample index array should be continuous 1-dimensional integer vector" );
  318. if( sample_idx->rows + sample_idx->cols - 1 > sample_count )
  319. CV_ERROR( CV_StsBadSize, "sample index array is too large" );
  320. map = sample_idx->data.i;
  321. sample_count = sample_idx->rows + sample_idx->cols - 1;
  322. }
  323. CV_CALL( out_responses = cvCreateMat( 1, sample_count, CV_32FC1 ));
  324. dst = out_responses->data.fl;
  325. if( r_type == CV_32FC1 )
  326. {
  327. const float* src = responses->data.fl;
  328. for( i = 0; i < sample_count; i++ )
  329. {
  330. int idx = map ? map[i] : i;
  331. assert( (unsigned)idx < (unsigned)sample_all );
  332. dst[i] = src[idx*r_step];
  333. }
  334. }
  335. else
  336. {
  337. const int* src = responses->data.i;
  338. for( i = 0; i < sample_count; i++ )
  339. {
  340. int idx = map ? map[i] : i;
  341. assert( (unsigned)idx < (unsigned)sample_all );
  342. dst[i] = (float)src[idx*r_step];
  343. }
  344. }
  345. __END__;
  346. return out_responses;
  347. }
  348. CvMat*
  349. cvPreprocessCategoricalResponses( const CvMat* responses,
  350. const CvMat* sample_idx, int sample_all,
  351. CvMat** out_response_map, CvMat** class_counts )
  352. {
  353. CvMat* out_responses = 0;
  354. int** response_ptr = 0;
  355. CV_FUNCNAME( "cvPreprocessCategoricalResponses" );
  356. if( out_response_map )
  357. *out_response_map = 0;
  358. if( class_counts )
  359. *class_counts = 0;
  360. __BEGIN__;
  361. int i, r_type, r_step;
  362. int cls_count = 1, prev_cls, prev_i;
  363. const int* map = 0;
  364. const int* srci;
  365. const float* srcfl;
  366. int* dst;
  367. int* cls_map;
  368. int* cls_counts = 0;
  369. int sample_count = sample_all;
  370. if( !CV_IS_MAT(responses) )
  371. CV_ERROR( CV_StsBadArg, "Invalid response array" );
  372. if( responses->rows != 1 && responses->cols != 1 )
  373. CV_ERROR( CV_StsBadSize, "Response array must be 1-dimensional" );
  374. if( responses->rows + responses->cols - 1 != sample_count )
  375. CV_ERROR( CV_StsUnmatchedSizes,
  376. "Response array must contain as many elements as the total number of samples" );
  377. r_type = CV_MAT_TYPE(responses->type);
  378. if( r_type != CV_32FC1 && r_type != CV_32SC1 )
  379. CV_ERROR( CV_StsUnsupportedFormat, "Unsupported response type" );
  380. r_step = responses->rows == 1 ? 1 : responses->step / CV_ELEM_SIZE(responses->type);
  381. if( sample_idx )
  382. {
  383. if( !CV_IS_MAT(sample_idx) || CV_MAT_TYPE(sample_idx->type) != CV_32SC1 ||
  384. (sample_idx->rows != 1 && sample_idx->cols != 1) || !CV_IS_MAT_CONT(sample_idx->type) )
  385. CV_ERROR( CV_StsBadArg, "sample index array should be continuous 1-dimensional integer vector" );
  386. if( sample_idx->rows + sample_idx->cols - 1 > sample_count )
  387. CV_ERROR( CV_StsBadSize, "sample index array is too large" );
  388. map = sample_idx->data.i;
  389. sample_count = sample_idx->rows + sample_idx->cols - 1;
  390. }
  391. CV_CALL( out_responses = cvCreateMat( 1, sample_count, CV_32SC1 ));
  392. if( !out_response_map )
  393. CV_ERROR( CV_StsNullPtr, "out_response_map pointer is NULL" );
  394. CV_CALL( response_ptr = (int**)cvAlloc( sample_count*sizeof(response_ptr[0])));
  395. srci = responses->data.i;
  396. srcfl = responses->data.fl;
  397. dst = out_responses->data.i;
  398. for( i = 0; i < sample_count; i++ )
  399. {
  400. int idx = map ? map[i] : i;
  401. assert( (unsigned)idx < (unsigned)sample_all );
  402. if( r_type == CV_32SC1 )
  403. dst[i] = srci[idx*r_step];
  404. else
  405. {
  406. float rf = srcfl[idx*r_step];
  407. int ri = cvRound(rf);
  408. if( ri != rf )
  409. {
  410. char buf[100];
  411. sprintf( buf, "response #%d is not integral", idx );
  412. CV_ERROR( CV_StsBadArg, buf );
  413. }
  414. dst[i] = ri;
  415. }
  416. response_ptr[i] = dst + i;
  417. }
  418. qsort( response_ptr, sample_count, sizeof(int*), icvCmpIntegersPtr );
  419. // count the classes
  420. for( i = 1; i < sample_count; i++ )
  421. cls_count += *response_ptr[i] != *response_ptr[i-1];
  422. if( cls_count < 2 )
  423. CV_ERROR( CV_StsBadArg, "There is only a single class" );
  424. CV_CALL( *out_response_map = cvCreateMat( 1, cls_count, CV_32SC1 ));
  425. if( class_counts )
  426. {
  427. CV_CALL( *class_counts = cvCreateMat( 1, cls_count, CV_32SC1 ));
  428. cls_counts = (*class_counts)->data.i;
  429. }
  430. // compact the class indices and build the map
  431. prev_cls = ~*response_ptr[0];
  432. cls_count = -1;
  433. cls_map = (*out_response_map)->data.i;
  434. for( i = 0, prev_i = -1; i < sample_count; i++ )
  435. {
  436. int cur_cls = *response_ptr[i];
  437. if( cur_cls != prev_cls )
  438. {
  439. if( cls_counts && cls_count >= 0 )
  440. cls_counts[cls_count] = i - prev_i;
  441. cls_map[++cls_count] = prev_cls = cur_cls;
  442. prev_i = i;
  443. }
  444. *response_ptr[i] = cls_count;
  445. }
  446. if( cls_counts )
  447. cls_counts[cls_count] = i - prev_i;
  448. __END__;
  449. cvFree( &response_ptr );
  450. return out_responses;
  451. }
  452. const float**
  453. cvGetTrainSamples( const CvMat* train_data, int tflag,
  454. const CvMat* var_idx, const CvMat* sample_idx,
  455. int* _var_count, int* _sample_count,
  456. bool always_copy_data )
  457. {
  458. float** samples = 0;
  459. CV_FUNCNAME( "cvGetTrainSamples" );
  460. __BEGIN__;
  461. int i, j, var_count, sample_count, s_step, v_step;
  462. bool copy_data;
  463. const float* data;
  464. const int *s_idx, *v_idx;
  465. if( !CV_IS_MAT(train_data) )
  466. CV_ERROR( CV_StsBadArg, "Invalid or NULL training data matrix" );
  467. var_count = var_idx ? var_idx->cols + var_idx->rows - 1 :
  468. tflag == CV_ROW_SAMPLE ? train_data->cols : train_data->rows;
  469. sample_count = sample_idx ? sample_idx->cols + sample_idx->rows - 1 :
  470. tflag == CV_ROW_SAMPLE ? train_data->rows : train_data->cols;
  471. if( _var_count )
  472. *_var_count = var_count;
  473. if( _sample_count )
  474. *_sample_count = sample_count;
  475. copy_data = tflag != CV_ROW_SAMPLE || var_idx || always_copy_data;
  476. CV_CALL( samples = (float**)cvAlloc(sample_count*sizeof(samples[0]) +
  477. (copy_data ? 1 : 0)*var_count*sample_count*sizeof(samples[0][0])) );
  478. data = train_data->data.fl;
  479. s_step = train_data->step / sizeof(samples[0][0]);
  480. v_step = 1;
  481. s_idx = sample_idx ? sample_idx->data.i : 0;
  482. v_idx = var_idx ? var_idx->data.i : 0;
  483. if( !copy_data )
  484. {
  485. for( i = 0; i < sample_count; i++ )
  486. samples[i] = (float*)(data + (s_idx ? s_idx[i] : i)*s_step);
  487. }
  488. else
  489. {
  490. samples[0] = (float*)(samples + sample_count);
  491. if( tflag != CV_ROW_SAMPLE )
  492. CV_SWAP( s_step, v_step, i );
  493. for( i = 0; i < sample_count; i++ )
  494. {
  495. float* dst = samples[i] = samples[0] + i*var_count;
  496. const float* src = data + (s_idx ? s_idx[i] : i)*s_step;
  497. if( !v_idx )
  498. for( j = 0; j < var_count; j++ )
  499. dst[j] = src[j*v_step];
  500. else
  501. for( j = 0; j < var_count; j++ )
  502. dst[j] = src[v_idx[j]*v_step];
  503. }
  504. }
  505. __END__;
  506. return (const float**)samples;
  507. }
  508. void
  509. cvCheckTrainData( const CvMat* train_data, int tflag,
  510. const CvMat* missing_mask,
  511. int* var_all, int* sample_all )
  512. {
  513. CV_FUNCNAME( "cvCheckTrainData" );
  514. if( var_all )
  515. *var_all = 0;
  516. if( sample_all )
  517. *sample_all = 0;
  518. __BEGIN__;
  519. // check parameter types and sizes
  520. if( !CV_IS_MAT(train_data) || CV_MAT_TYPE(train_data->type) != CV_32FC1 )
  521. CV_ERROR( CV_StsBadArg, "train data must be floating-point matrix" );
  522. if( missing_mask )
  523. {
  524. if( !CV_IS_MAT(missing_mask) || !CV_IS_MASK_ARR(missing_mask) ||
  525. !CV_ARE_SIZES_EQ(train_data, missing_mask) )
  526. CV_ERROR( CV_StsBadArg,
  527. "missing value mask must be 8-bit matrix of the same size as training data" );
  528. }
  529. if( tflag != CV_ROW_SAMPLE && tflag != CV_COL_SAMPLE )
  530. CV_ERROR( CV_StsBadArg,
  531. "Unknown training data layout (must be CV_ROW_SAMPLE or CV_COL_SAMPLE)" );
  532. if( var_all )
  533. *var_all = tflag == CV_ROW_SAMPLE ? train_data->cols : train_data->rows;
  534. if( sample_all )
  535. *sample_all = tflag == CV_ROW_SAMPLE ? train_data->rows : train_data->cols;
  536. __END__;
  537. }
  538. int
  539. cvPrepareTrainData( const char* /*funcname*/,
  540. const CvMat* train_data, int tflag,
  541. const CvMat* responses, int response_type,
  542. const CvMat* var_idx,
  543. const CvMat* sample_idx,
  544. bool always_copy_data,
  545. const float*** out_train_samples,
  546. int* _sample_count,
  547. int* _var_count,
  548. int* _var_all,
  549. CvMat** out_responses,
  550. CvMat** out_response_map,
  551. CvMat** out_var_idx,
  552. CvMat** out_sample_idx )
  553. {
  554. int ok = 0;
  555. CvMat* _var_idx = 0;
  556. CvMat* _sample_idx = 0;
  557. CvMat* _responses = 0;
  558. int sample_all = 0, sample_count = 0, var_all = 0, var_count = 0;
  559. CV_FUNCNAME( "cvPrepareTrainData" );
  560. // step 0. clear all the output pointers to ensure we do not try
  561. // to call free() with uninitialized pointers
  562. if( out_responses )
  563. *out_responses = 0;
  564. if( out_response_map )
  565. *out_response_map = 0;
  566. if( out_var_idx )
  567. *out_var_idx = 0;
  568. if( out_sample_idx )
  569. *out_sample_idx = 0;
  570. if( out_train_samples )
  571. *out_train_samples = 0;
  572. if( _sample_count )
  573. *_sample_count = 0;
  574. if( _var_count )
  575. *_var_count = 0;
  576. if( _var_all )
  577. *_var_all = 0;
  578. __BEGIN__;
  579. if( !out_train_samples )
  580. CV_ERROR( CV_StsBadArg, "output pointer to train samples is NULL" );
  581. CV_CALL( cvCheckTrainData( train_data, tflag, 0, &var_all, &sample_all ));
  582. if( sample_idx )
  583. CV_CALL( _sample_idx = cvPreprocessIndexArray( sample_idx, sample_all ));
  584. if( var_idx )
  585. CV_CALL( _var_idx = cvPreprocessIndexArray( var_idx, var_all ));
  586. if( responses )
  587. {
  588. if( !out_responses )
  589. CV_ERROR( CV_StsNullPtr, "output response pointer is NULL" );
  590. if( response_type == CV_VAR_NUMERICAL )
  591. {
  592. CV_CALL( _responses = cvPreprocessOrderedResponses( responses,
  593. _sample_idx, sample_all ));
  594. }
  595. else
  596. {
  597. CV_CALL( _responses = cvPreprocessCategoricalResponses( responses,
  598. _sample_idx, sample_all, out_response_map, 0 ));
  599. }
  600. }
  601. CV_CALL( *out_train_samples =
  602. cvGetTrainSamples( train_data, tflag, _var_idx, _sample_idx,
  603. &var_count, &sample_count, always_copy_data ));
  604. ok = 1;
  605. __END__;
  606. if( ok )
  607. {
  608. if( out_responses )
  609. *out_responses = _responses, _responses = 0;
  610. if( out_var_idx )
  611. *out_var_idx = _var_idx, _var_idx = 0;
  612. if( out_sample_idx )
  613. *out_sample_idx = _sample_idx, _sample_idx = 0;
  614. if( _sample_count )
  615. *_sample_count = sample_count;
  616. if( _var_count )
  617. *_var_count = var_count;
  618. if( _var_all )
  619. *_var_all = var_all;
  620. }
  621. else
  622. {
  623. if( out_response_map )
  624. cvReleaseMat( out_response_map );
  625. cvFree( out_train_samples );
  626. }
  627. if( _responses != responses )
  628. cvReleaseMat( &_responses );
  629. cvReleaseMat( &_var_idx );
  630. cvReleaseMat( &_sample_idx );
  631. return ok;
  632. }
  633. typedef struct CvSampleResponsePair
  634. {
  635. const float* sample;
  636. const uchar* mask;
  637. int response;
  638. int index;
  639. }
  640. CvSampleResponsePair;
  641. static int
  642. CV_CDECL icvCmpSampleResponsePairs( const void* a, const void* b )
  643. {
  644. int ra = ((const CvSampleResponsePair*)a)->response;
  645. int rb = ((const CvSampleResponsePair*)b)->response;
  646. int ia = ((const CvSampleResponsePair*)a)->index;
  647. int ib = ((const CvSampleResponsePair*)b)->index;
  648. return ra < rb ? -1 : ra > rb ? 1 : ia - ib;
  649. //return (ra > rb ? -1 : 0)|(ra < rb);
  650. }
  651. void
  652. cvSortSamplesByClasses( const float** samples, const CvMat* classes,
  653. int* class_ranges, const uchar** mask )
  654. {
  655. CvSampleResponsePair* pairs = 0;
  656. CV_FUNCNAME( "cvSortSamplesByClasses" );
  657. __BEGIN__;
  658. int i, k = 0, sample_count;
  659. if( !samples || !classes || !class_ranges )
  660. CV_ERROR( CV_StsNullPtr, "INTERNAL ERROR: some of the args are NULL pointers" );
  661. if( classes->rows != 1 || CV_MAT_TYPE(classes->type) != CV_32SC1 )
  662. CV_ERROR( CV_StsBadArg, "classes array must be a single row of integers" );
  663. sample_count = classes->cols;
  664. CV_CALL( pairs = (CvSampleResponsePair*)cvAlloc( (sample_count+1)*sizeof(pairs[0])));
  665. for( i = 0; i < sample_count; i++ )
  666. {
  667. pairs[i].sample = samples[i];
  668. pairs[i].mask = (mask) ? (mask[i]) : 0;
  669. pairs[i].response = classes->data.i[i];
  670. pairs[i].index = i;
  671. assert( classes->data.i[i] >= 0 );
  672. }
  673. qsort( pairs, sample_count, sizeof(pairs[0]), icvCmpSampleResponsePairs );
  674. pairs[sample_count].response = -1;
  675. class_ranges[0] = 0;
  676. for( i = 0; i < sample_count; i++ )
  677. {
  678. samples[i] = pairs[i].sample;
  679. if (mask)
  680. mask[i] = pairs[i].mask;
  681. classes->data.i[i] = pairs[i].response;
  682. if( pairs[i].response != pairs[i+1].response )
  683. class_ranges[++k] = i+1;
  684. }
  685. __END__;
  686. cvFree( &pairs );
  687. }
  688. void
  689. cvPreparePredictData( const CvArr* _sample, int dims_all,
  690. const CvMat* comp_idx, int class_count,
  691. const CvMat* prob, float** _row_sample,
  692. int as_sparse )
  693. {
  694. float* row_sample = 0;
  695. int* inverse_comp_idx = 0;
  696. CV_FUNCNAME( "cvPreparePredictData" );
  697. __BEGIN__;
  698. const CvMat* sample = (const CvMat*)_sample;
  699. float* sample_data;
  700. int sample_step;
  701. int is_sparse = CV_IS_SPARSE_MAT(sample);
  702. int d, sizes[CV_MAX_DIM];
  703. int i, dims_selected;
  704. int vec_size;
  705. if( !is_sparse && !CV_IS_MAT(sample) )
  706. CV_ERROR( !sample ? CV_StsNullPtr : CV_StsBadArg, "The sample is not a valid vector" );
  707. if( cvGetElemType( sample ) != CV_32FC1 )
  708. CV_ERROR( CV_StsUnsupportedFormat, "Input sample must have 32fC1 type" );
  709. CV_CALL( d = cvGetDims( sample, sizes ));
  710. if( !((is_sparse && d == 1) || (!is_sparse && d == 2 && (sample->rows == 1 || sample->cols == 1))) )
  711. CV_ERROR( CV_StsBadSize, "Input sample must be 1-dimensional vector" );
  712. if( d == 1 )
  713. sizes[1] = 1;
  714. if( sizes[0] + sizes[1] - 1 != dims_all )
  715. CV_ERROR( CV_StsUnmatchedSizes,
  716. "The sample size is different from what has been used for training" );
  717. if( !_row_sample )
  718. CV_ERROR( CV_StsNullPtr, "INTERNAL ERROR: The row_sample pointer is NULL" );
  719. if( comp_idx && (!CV_IS_MAT(comp_idx) || comp_idx->rows != 1 ||
  720. CV_MAT_TYPE(comp_idx->type) != CV_32SC1) )
  721. CV_ERROR( CV_StsBadArg, "INTERNAL ERROR: invalid comp_idx" );
  722. dims_selected = comp_idx ? comp_idx->cols : dims_all;
  723. if( prob )
  724. {
  725. if( !CV_IS_MAT(prob) )
  726. CV_ERROR( CV_StsBadArg, "The output matrix of probabilities is invalid" );
  727. if( (prob->rows != 1 && prob->cols != 1) ||
  728. (CV_MAT_TYPE(prob->type) != CV_32FC1 &&
  729. CV_MAT_TYPE(prob->type) != CV_64FC1) )
  730. CV_ERROR( CV_StsBadSize,
  731. "The matrix of probabilities must be 1-dimensional vector of 32fC1 type" );
  732. if( prob->rows + prob->cols - 1 != class_count )
  733. CV_ERROR( CV_StsUnmatchedSizes,
  734. "The vector of probabilities must contain as many elements as "
  735. "the number of classes in the training set" );
  736. }
  737. vec_size = !as_sparse ? dims_selected*sizeof(row_sample[0]) :
  738. (dims_selected + 1)*sizeof(CvSparseVecElem32f);
  739. if( CV_IS_MAT(sample) )
  740. {
  741. sample_data = sample->data.fl;
  742. sample_step = CV_IS_MAT_CONT(sample->type) ? 1 : sample->step/sizeof(row_sample[0]);
  743. if( !comp_idx && CV_IS_MAT_CONT(sample->type) && !as_sparse )
  744. *_row_sample = sample_data;
  745. else
  746. {
  747. CV_CALL( row_sample = (float*)cvAlloc( vec_size ));
  748. if( !comp_idx )
  749. for( i = 0; i < dims_selected; i++ )
  750. row_sample[i] = sample_data[sample_step*i];
  751. else
  752. {
  753. int* comp = comp_idx->data.i;
  754. for( i = 0; i < dims_selected; i++ )
  755. row_sample[i] = sample_data[sample_step*comp[i]];
  756. }
  757. *_row_sample = row_sample;
  758. }
  759. if( as_sparse )
  760. {
  761. const float* src = (const float*)row_sample;
  762. CvSparseVecElem32f* dst = (CvSparseVecElem32f*)row_sample;
  763. dst[dims_selected].idx = -1;
  764. for( i = dims_selected - 1; i >= 0; i-- )
  765. {
  766. dst[i].idx = i;
  767. dst[i].val = src[i];
  768. }
  769. }
  770. }
  771. else
  772. {
  773. CvSparseNode* node;
  774. CvSparseMatIterator mat_iterator;
  775. const CvSparseMat* sparse = (const CvSparseMat*)sample;
  776. assert( is_sparse );
  777. node = cvInitSparseMatIterator( sparse, &mat_iterator );
  778. CV_CALL( row_sample = (float*)cvAlloc( vec_size ));
  779. if( comp_idx )
  780. {
  781. CV_CALL( inverse_comp_idx = (int*)cvAlloc( dims_all*sizeof(int) ));
  782. memset( inverse_comp_idx, -1, dims_all*sizeof(int) );
  783. for( i = 0; i < dims_selected; i++ )
  784. inverse_comp_idx[comp_idx->data.i[i]] = i;
  785. }
  786. if( !as_sparse )
  787. {
  788. memset( row_sample, 0, vec_size );
  789. for( ; node != 0; node = cvGetNextSparseNode(&mat_iterator) )
  790. {
  791. int idx = *CV_NODE_IDX( sparse, node );
  792. if( inverse_comp_idx )
  793. {
  794. idx = inverse_comp_idx[idx];
  795. if( idx < 0 )
  796. continue;
  797. }
  798. row_sample[idx] = *(float*)CV_NODE_VAL( sparse, node );
  799. }
  800. }
  801. else
  802. {
  803. CvSparseVecElem32f* ptr = (CvSparseVecElem32f*)row_sample;
  804. for( ; node != 0; node = cvGetNextSparseNode(&mat_iterator) )
  805. {
  806. int idx = *CV_NODE_IDX( sparse, node );
  807. if( inverse_comp_idx )
  808. {
  809. idx = inverse_comp_idx[idx];
  810. if( idx < 0 )
  811. continue;
  812. }
  813. ptr->idx = idx;
  814. ptr->val = *(float*)CV_NODE_VAL( sparse, node );
  815. ptr++;
  816. }
  817. qsort( row_sample, ptr - (CvSparseVecElem32f*)row_sample,
  818. sizeof(ptr[0]), icvCmpSparseVecElems );
  819. ptr->idx = -1;
  820. }
  821. *_row_sample = row_sample;
  822. }
  823. __END__;
  824. if( inverse_comp_idx )
  825. cvFree( &inverse_comp_idx );
  826. if( cvGetErrStatus() < 0 && _row_sample )
  827. {
  828. cvFree( &row_sample );
  829. *_row_sample = 0;
  830. }
  831. }
  832. static void
  833. icvConvertDataToSparse( const uchar* src, int src_step, int src_type,
  834. uchar* dst, int dst_step, int dst_type,
  835. CvSize size, int* idx )
  836. {
  837. CV_FUNCNAME( "icvConvertDataToSparse" );
  838. __BEGIN__;
  839. int i, j;
  840. src_type = CV_MAT_TYPE(src_type);
  841. dst_type = CV_MAT_TYPE(dst_type);
  842. if( CV_MAT_CN(src_type) != 1 || CV_MAT_CN(dst_type) != 1 )
  843. CV_ERROR( CV_StsUnsupportedFormat, "The function supports only single-channel arrays" );
  844. if( src_step == 0 )
  845. src_step = CV_ELEM_SIZE(src_type);
  846. if( dst_step == 0 )
  847. dst_step = CV_ELEM_SIZE(dst_type);
  848. // if there is no "idx" and if both arrays are continuous,
  849. // do the whole processing (copying or conversion) in a single loop
  850. if( !idx && CV_ELEM_SIZE(src_type)*size.width == src_step &&
  851. CV_ELEM_SIZE(dst_type)*size.width == dst_step )
  852. {
  853. size.width *= size.height;
  854. size.height = 1;
  855. }
  856. if( src_type == dst_type )
  857. {
  858. int full_width = CV_ELEM_SIZE(dst_type)*size.width;
  859. if( full_width == sizeof(int) ) // another common case: copy int's or float's
  860. for( i = 0; i < size.height; i++, src += src_step )
  861. *(int*)(dst + dst_step*(idx ? idx[i] : i)) = *(int*)src;
  862. else
  863. for( i = 0; i < size.height; i++, src += src_step )
  864. memcpy( dst + dst_step*(idx ? idx[i] : i), src, full_width );
  865. }
  866. else if( src_type == CV_32SC1 && (dst_type == CV_32FC1 || dst_type == CV_64FC1) )
  867. for( i = 0; i < size.height; i++, src += src_step )
  868. {
  869. uchar* _dst = dst + dst_step*(idx ? idx[i] : i);
  870. if( dst_type == CV_32FC1 )
  871. for( j = 0; j < size.width; j++ )
  872. ((float*)_dst)[j] = (float)((int*)src)[j];
  873. else
  874. for( j = 0; j < size.width; j++ )
  875. ((double*)_dst)[j] = ((int*)src)[j];
  876. }
  877. else if( (src_type == CV_32FC1 || src_type == CV_64FC1) && dst_type == CV_32SC1 )
  878. for( i = 0; i < size.height; i++, src += src_step )
  879. {
  880. uchar* _dst = dst + dst_step*(idx ? idx[i] : i);
  881. if( src_type == CV_32FC1 )
  882. for( j = 0; j < size.width; j++ )
  883. ((int*)_dst)[j] = cvRound(((float*)src)[j]);
  884. else
  885. for( j = 0; j < size.width; j++ )
  886. ((int*)_dst)[j] = cvRound(((double*)src)[j]);
  887. }
  888. else if( (src_type == CV_32FC1 && dst_type == CV_64FC1) ||
  889. (src_type == CV_64FC1 && dst_type == CV_32FC1) )
  890. for( i = 0; i < size.height; i++, src += src_step )
  891. {
  892. uchar* _dst = dst + dst_step*(idx ? idx[i] : i);
  893. if( src_type == CV_32FC1 )
  894. for( j = 0; j < size.width; j++ )
  895. ((double*)_dst)[j] = ((float*)src)[j];
  896. else
  897. for( j = 0; j < size.width; j++ )
  898. ((float*)_dst)[j] = (float)((double*)src)[j];
  899. }
  900. else
  901. CV_ERROR( CV_StsUnsupportedFormat, "Unsupported combination of input and output vectors" );
  902. __END__;
  903. }
  904. void
  905. cvWritebackLabels( const CvMat* labels, CvMat* dst_labels,
  906. const CvMat* centers, CvMat* dst_centers,
  907. const CvMat* probs, CvMat* dst_probs,
  908. const CvMat* sample_idx, int samples_all,
  909. const CvMat* comp_idx, int dims_all )
  910. {
  911. CV_FUNCNAME( "cvWritebackLabels" );
  912. __BEGIN__;
  913. int samples_selected = samples_all, dims_selected = dims_all;
  914. if( dst_labels && !CV_IS_MAT(dst_labels) )
  915. CV_ERROR( CV_StsBadArg, "Array of output labels is not a valid matrix" );
  916. if( dst_centers )
  917. if( !ICV_IS_MAT_OF_TYPE(dst_centers, CV_32FC1) &&
  918. !ICV_IS_MAT_OF_TYPE(dst_centers, CV_64FC1) )
  919. CV_ERROR( CV_StsBadArg, "Array of cluster centers is not a valid matrix" );
  920. if( dst_probs && !CV_IS_MAT(dst_probs) )
  921. CV_ERROR( CV_StsBadArg, "Probability matrix is not valid" );
  922. if( sample_idx )
  923. {
  924. CV_ASSERT( sample_idx->rows == 1 && CV_MAT_TYPE(sample_idx->type) == CV_32SC1 );
  925. samples_selected = sample_idx->cols;
  926. }
  927. if( comp_idx )
  928. {
  929. CV_ASSERT( comp_idx->rows == 1 && CV_MAT_TYPE(comp_idx->type) == CV_32SC1 );
  930. dims_selected = comp_idx->cols;
  931. }
  932. if( dst_labels && (!labels || labels->data.ptr != dst_labels->data.ptr) )
  933. {
  934. if( !labels )
  935. CV_ERROR( CV_StsNullPtr, "NULL labels" );
  936. CV_ASSERT( labels->rows == 1 );
  937. if( dst_labels->rows != 1 && dst_labels->cols != 1 )
  938. CV_ERROR( CV_StsBadSize, "Array of output labels should be 1d vector" );
  939. if( dst_labels->rows + dst_labels->cols - 1 != samples_all )
  940. CV_ERROR( CV_StsUnmatchedSizes,
  941. "Size of vector of output labels is not equal to the total number of input samples" );
  942. CV_ASSERT( labels->cols == samples_selected );
  943. CV_CALL( icvConvertDataToSparse( labels->data.ptr, labels->step, labels->type,
  944. dst_labels->data.ptr, dst_labels->step, dst_labels->type,
  945. cvSize( 1, samples_selected ), sample_idx ? sample_idx->data.i : 0 ));
  946. }
  947. if( dst_centers && (!centers || centers->data.ptr != dst_centers->data.ptr) )
  948. {
  949. int i;
  950. if( !centers )
  951. CV_ERROR( CV_StsNullPtr, "NULL centers" );
  952. if( centers->rows != dst_centers->rows )
  953. CV_ERROR( CV_StsUnmatchedSizes, "Invalid number of rows in matrix of output centers" );
  954. if( dst_centers->cols != dims_all )
  955. CV_ERROR( CV_StsUnmatchedSizes,
  956. "Number of columns in matrix of output centers is "
  957. "not equal to the total number of components in the input samples" );
  958. CV_ASSERT( centers->cols == dims_selected );
  959. for( i = 0; i < centers->rows; i++ )
  960. CV_CALL( icvConvertDataToSparse( centers->data.ptr + i*centers->step, 0, centers->type,
  961. dst_centers->data.ptr + i*dst_centers->step, 0, dst_centers->type,
  962. cvSize( 1, dims_selected ), comp_idx ? comp_idx->data.i : 0 ));
  963. }
  964. if( dst_probs && (!probs || probs->data.ptr != dst_probs->data.ptr) )
  965. {
  966. if( !probs )
  967. CV_ERROR( CV_StsNullPtr, "NULL probs" );
  968. if( probs->cols != dst_probs->cols )
  969. CV_ERROR( CV_StsUnmatchedSizes, "Invalid number of columns in output probability matrix" );
  970. if( dst_probs->rows != samples_all )
  971. CV_ERROR( CV_StsUnmatchedSizes,
  972. "Number of rows in output probability matrix is "
  973. "not equal to the total number of input samples" );
  974. CV_ASSERT( probs->rows == samples_selected );
  975. CV_CALL( icvConvertDataToSparse( probs->data.ptr, probs->step, probs->type,
  976. dst_probs->data.ptr, dst_probs->step, dst_probs->type,
  977. cvSize( probs->cols, samples_selected ),
  978. sample_idx ? sample_idx->data.i : 0 ));
  979. }
  980. __END__;
  981. }
  982. #if 0
  983. CV_IMPL void
  984. cvStatModelMultiPredict( const CvStatModel* stat_model,
  985. const CvArr* predict_input,
  986. int flags, CvMat* predict_output,
  987. CvMat* probs, const CvMat* sample_idx )
  988. {
  989. CvMemStorage* storage = 0;
  990. CvMat* sample_idx_buffer = 0;
  991. CvSparseMat** sparse_rows = 0;
  992. int samples_selected = 0;
  993. CV_FUNCNAME( "cvStatModelMultiPredict" );
  994. __BEGIN__;
  995. int i;
  996. int predict_output_step = 1, sample_idx_step = 1;
  997. int type;
  998. int d, sizes[CV_MAX_DIM];
  999. int tflag = flags == CV_COL_SAMPLE;
  1000. int samples_all, dims_all;
  1001. int is_sparse = CV_IS_SPARSE_MAT(predict_input);
  1002. CvMat predict_input_part;
  1003. CvArr* sample = &predict_input_part;
  1004. CvMat probs_part;
  1005. CvMat* probs1 = probs ? &probs_part : 0;
  1006. if( !CV_IS_STAT_MODEL(stat_model) )
  1007. CV_ERROR( !stat_model ? CV_StsNullPtr : CV_StsBadArg, "Invalid statistical model" );
  1008. if( !stat_model->predict )
  1009. CV_ERROR( CV_StsNotImplemented, "There is no \"predict\" method" );
  1010. if( !predict_input || !predict_output )
  1011. CV_ERROR( CV_StsNullPtr, "NULL input or output matrices" );
  1012. if( !is_sparse && !CV_IS_MAT(predict_input) )
  1013. CV_ERROR( CV_StsBadArg, "predict_input should be a matrix or a sparse matrix" );
  1014. if( !CV_IS_MAT(predict_output) )
  1015. CV_ERROR( CV_StsBadArg, "predict_output should be a matrix" );
  1016. type = cvGetElemType( predict_input );
  1017. if( type != CV_32FC1 ||
  1018. (CV_MAT_TYPE(predict_output->type) != CV_32FC1 &&
  1019. CV_MAT_TYPE(predict_output->type) != CV_32SC1 ))
  1020. CV_ERROR( CV_StsUnsupportedFormat, "The input or output matrix has unsupported format" );
  1021. CV_CALL( d = cvGetDims( predict_input, sizes ));
  1022. if( d > 2 )
  1023. CV_ERROR( CV_StsBadSize, "The input matrix should be 1- or 2-dimensional" );
  1024. if( !tflag )
  1025. {
  1026. samples_all = samples_selected = sizes[0];
  1027. dims_all = sizes[1];
  1028. }
  1029. else
  1030. {
  1031. samples_all = samples_selected = sizes[1];
  1032. dims_all = sizes[0];
  1033. }
  1034. if( sample_idx )
  1035. {
  1036. if( !CV_IS_MAT(sample_idx) )
  1037. CV_ERROR( CV_StsBadArg, "Invalid sample_idx matrix" );
  1038. if( sample_idx->cols != 1 && sample_idx->rows != 1 )
  1039. CV_ERROR( CV_StsBadSize, "sample_idx must be 1-dimensional matrix" );
  1040. samples_selected = sample_idx->rows + sample_idx->cols - 1;
  1041. if( CV_MAT_TYPE(sample_idx->type) == CV_32SC1 )
  1042. {
  1043. if( samples_selected > samples_all )
  1044. CV_ERROR( CV_StsBadSize, "sample_idx is too large vector" );
  1045. }
  1046. else if( samples_selected != samples_all )
  1047. CV_ERROR( CV_StsUnmatchedSizes, "sample_idx has incorrect size" );
  1048. sample_idx_step = sample_idx->step ?
  1049. sample_idx->step / CV_ELEM_SIZE(sample_idx->type) : 1;
  1050. }
  1051. if( predict_output->rows != 1 && predict_output->cols != 1 )
  1052. CV_ERROR( CV_StsBadSize, "predict_output should be a 1-dimensional matrix" );
  1053. if( predict_output->rows + predict_output->cols - 1 != samples_all )
  1054. CV_ERROR( CV_StsUnmatchedSizes, "predict_output and predict_input have uncoordinated sizes" );
  1055. predict_output_step = predict_output->step ?
  1056. predict_output->step / CV_ELEM_SIZE(predict_output->type) : 1;
  1057. if( probs )
  1058. {
  1059. if( !CV_IS_MAT(probs) )
  1060. CV_ERROR( CV_StsBadArg, "Invalid matrix of probabilities" );
  1061. if( probs->rows != samples_all )
  1062. CV_ERROR( CV_StsUnmatchedSizes,
  1063. "matrix of probabilities must have as many rows as the total number of samples" );
  1064. if( CV_MAT_TYPE(probs->type) != CV_32FC1 )
  1065. CV_ERROR( CV_StsUnsupportedFormat, "matrix of probabilities must have 32fC1 type" );
  1066. }
  1067. if( is_sparse )
  1068. {
  1069. CvSparseNode* node;
  1070. CvSparseMatIterator mat_iterator;
  1071. CvSparseMat* sparse = (CvSparseMat*)predict_input;
  1072. if( sample_idx && CV_MAT_TYPE(sample_idx->type) == CV_32SC1 )
  1073. {
  1074. CV_CALL( sample_idx_buffer = cvCreateMat( 1, samples_all, CV_8UC1 ));
  1075. cvZero( sample_idx_buffer );
  1076. for( i = 0; i < samples_selected; i++ )
  1077. sample_idx_buffer->data.ptr[sample_idx->data.i[i*sample_idx_step]] = 1;
  1078. samples_selected = samples_all;
  1079. sample_idx = sample_idx_buffer;
  1080. sample_idx_step = 1;
  1081. }
  1082. CV_CALL( sparse_rows = (CvSparseMat**)cvAlloc( samples_selected*sizeof(sparse_rows[0])));
  1083. for( i = 0; i < samples_selected; i++ )
  1084. {
  1085. if( sample_idx && sample_idx->data.ptr[i*sample_idx_step] == 0 )
  1086. continue;
  1087. CV_CALL( sparse_rows[i] = cvCreateSparseMat( 1, &dims_all, type ));
  1088. if( !storage )
  1089. storage = sparse_rows[i]->heap->storage;
  1090. else
  1091. {
  1092. // hack: to decrease memory footprint, make all the sparse matrices
  1093. // reside in the same storage
  1094. int elem_size = sparse_rows[i]->heap->elem_size;
  1095. cvReleaseMemStorage( &sparse_rows[i]->heap->storage );
  1096. sparse_rows[i]->heap = cvCreateSet( 0, sizeof(CvSet), elem_size, storage );
  1097. }
  1098. }
  1099. // put each row (or column) of predict_input into separate sparse matrix.
  1100. node = cvInitSparseMatIterator( sparse, &mat_iterator );
  1101. for( ; node != 0; node = cvGetNextSparseNode( &mat_iterator ))
  1102. {
  1103. int* idx = CV_NODE_IDX( sparse, node );
  1104. int idx0 = idx[tflag ^ 1];
  1105. int idx1 = idx[tflag];
  1106. if( sample_idx && sample_idx->data.ptr[idx0*sample_idx_step] == 0 )
  1107. continue;
  1108. assert( sparse_rows[idx0] != 0 );
  1109. *(float*)cvPtrND( sparse, &idx1, 0, 1, 0 ) = *(float*)CV_NODE_VAL( sparse, node );
  1110. }
  1111. }
  1112. for( i = 0; i < samples_selected; i++ )
  1113. {
  1114. int idx = i;
  1115. float response;
  1116. if( sample_idx )
  1117. {
  1118. if( CV_MAT_TYPE(sample_idx->type) == CV_32SC1 )
  1119. {
  1120. idx = sample_idx->data.i[i*sample_idx_step];
  1121. if( (unsigned)idx >= (unsigned)samples_all )
  1122. CV_ERROR( CV_StsOutOfRange, "Some of sample_idx elements are out of range" );
  1123. }
  1124. else if( CV_MAT_TYPE(sample_idx->type) == CV_8UC1 &&
  1125. sample_idx->data.ptr[i*sample_idx_step] == 0 )
  1126. continue;
  1127. }
  1128. if( !is_sparse )
  1129. {
  1130. if( !tflag )
  1131. cvGetRow( predict_input, &predict_input_part, idx );
  1132. else
  1133. {
  1134. cvGetCol( predict_input, &predict_input_part, idx );
  1135. }
  1136. }
  1137. else
  1138. sample = sparse_rows[idx];
  1139. if( probs )
  1140. cvGetRow( probs, probs1, idx );
  1141. CV_CALL( response = stat_model->predict( stat_model, (CvMat*)sample, probs1 ));
  1142. if( CV_MAT_TYPE(predict_output->type) == CV_32FC1 )
  1143. predict_output->data.fl[idx*predict_output_step] = response;
  1144. else
  1145. {
  1146. CV_ASSERT( cvRound(response) == response );
  1147. predict_output->data.i[idx*predict_output_step] = cvRound(response);
  1148. }
  1149. }
  1150. __END__;
  1151. if( sparse_rows )
  1152. {
  1153. int i;
  1154. for( i = 0; i < samples_selected; i++ )
  1155. if( sparse_rows[i] )
  1156. {
  1157. sparse_rows[i]->heap->storage = 0;
  1158. cvReleaseSparseMat( &sparse_rows[i] );
  1159. }
  1160. cvFree( &sparse_rows );
  1161. }
  1162. cvReleaseMat( &sample_idx_buffer );
  1163. cvReleaseMemStorage( &storage );
  1164. }
  1165. #endif
  1166. // By P. Yarykin - begin -
  1167. void cvCombineResponseMaps (CvMat* _responses,
  1168. const CvMat* old_response_map,
  1169. CvMat* new_response_map,
  1170. CvMat** out_response_map)
  1171. {
  1172. int** old_data = NULL;
  1173. int** new_data = NULL;
  1174. CV_FUNCNAME ("cvCombineResponseMaps");
  1175. __BEGIN__
  1176. int i,j;
  1177. int old_n, new_n, out_n;
  1178. int samples, free_response;
  1179. int* first;
  1180. int* responses;
  1181. int* out_data;
  1182. if( out_response_map )
  1183. *out_response_map = 0;
  1184. // Check input data.
  1185. if ((!ICV_IS_MAT_OF_TYPE (_responses, CV_32SC1)) ||
  1186. (!ICV_IS_MAT_OF_TYPE (old_response_map, CV_32SC1)) ||
  1187. (!ICV_IS_MAT_OF_TYPE (new_response_map, CV_32SC1)))
  1188. {
  1189. CV_ERROR (CV_StsBadArg, "Some of input arguments is not the CvMat")
  1190. }
  1191. // Prepare sorted responses.
  1192. first = new_response_map->data.i;
  1193. new_n = new_response_map->cols;
  1194. CV_CALL (new_data = (int**)cvAlloc (new_n * sizeof (new_data[0])));
  1195. for (i = 0; i < new_n; i++)
  1196. new_data[i] = first + i;
  1197. qsort (new_data, new_n, sizeof(int*), icvCmpIntegersPtr);
  1198. first = old_response_map->data.i;
  1199. old_n = old_response_map->cols;
  1200. CV_CALL (old_data = (int**)cvAlloc (old_n * sizeof (old_data[0])));
  1201. for (i = 0; i < old_n; i++)
  1202. old_data[i] = first + i;
  1203. qsort (old_data, old_n, sizeof(int*), icvCmpIntegersPtr);
  1204. // Count the number of different responses.
  1205. for (i = 0, j = 0, out_n = 0; i < old_n && j < new_n; out_n++)
  1206. {
  1207. if (*old_data[i] == *new_data[j])
  1208. {
  1209. i++;
  1210. j++;
  1211. }
  1212. else if (*old_data[i] < *new_data[j])
  1213. i++;
  1214. else
  1215. j++;
  1216. }
  1217. out_n += old_n - i + new_n - j;
  1218. // Create and fill the result response maps.
  1219. CV_CALL (*out_response_map = cvCreateMat (1, out_n, CV_32SC1));
  1220. out_data = (*out_response_map)->data.i;
  1221. memcpy (out_data, first, old_n * sizeof (int));
  1222. free_response = old_n;
  1223. for (i = 0, j = 0; i < old_n && j < new_n; )
  1224. {
  1225. if (*old_data[i] == *new_data[j])
  1226. {
  1227. *new_data[j] = (int)(old_data[i] - first);
  1228. i++;
  1229. j++;
  1230. }
  1231. else if (*old_data[i] < *new_data[j])
  1232. i++;
  1233. else
  1234. {
  1235. out_data[free_response] = *new_data[j];
  1236. *new_data[j] = free_response++;
  1237. j++;
  1238. }
  1239. }
  1240. for (; j < new_n; j++)
  1241. {
  1242. out_data[free_response] = *new_data[j];
  1243. *new_data[j] = free_response++;
  1244. }
  1245. CV_ASSERT (free_response == out_n);
  1246. // Change <responses> according to out response map.
  1247. samples = _responses->cols + _responses->rows - 1;
  1248. responses = _responses->data.i;
  1249. first = new_response_map->data.i;
  1250. for (i = 0; i < samples; i++)
  1251. {
  1252. responses[i] = first[responses[i]];
  1253. }
  1254. __END__
  1255. cvFree(&old_data);
  1256. cvFree(&new_data);
  1257. }
  1258. static int icvGetNumberOfCluster( double* prob_vector, int num_of_clusters, float r,
  1259. float outlier_thresh, int normalize_probs )
  1260. {
  1261. int max_prob_loc = 0;
  1262. CV_FUNCNAME("icvGetNumberOfCluster");
  1263. __BEGIN__;
  1264. double prob, maxprob, sum;
  1265. int i;
  1266. CV_ASSERT(prob_vector);
  1267. CV_ASSERT(num_of_clusters >= 0);
  1268. maxprob = prob_vector[0];
  1269. max_prob_loc = 0;
  1270. sum = maxprob;
  1271. for( i = 1; i < num_of_clusters; i++ )
  1272. {
  1273. prob = prob_vector[i];
  1274. sum += prob;
  1275. if( prob > maxprob )
  1276. {
  1277. max_prob_loc = i;
  1278. maxprob = prob;
  1279. }
  1280. }
  1281. if( normalize_probs && fabs(sum - 1.) > FLT_EPSILON )
  1282. {
  1283. for( i = 0; i < num_of_clusters; i++ )
  1284. prob_vector[i] /= sum;
  1285. }
  1286. if( fabs(r - 1.) > FLT_EPSILON && fabs(sum - 1.) < outlier_thresh )
  1287. max_prob_loc = -1;
  1288. __END__;
  1289. return max_prob_loc;
  1290. } // End of icvGetNumberOfCluster
  1291. void icvFindClusterLabels( const CvMat* probs, float outlier_thresh, float r,
  1292. const CvMat* labels )
  1293. {
  1294. CvMat* counts = 0;
  1295. CV_FUNCNAME("icvFindClusterLabels");
  1296. __BEGIN__;
  1297. int nclusters, nsamples;
  1298. int i, j;
  1299. double* probs_data;
  1300. CV_ASSERT( ICV_IS_MAT_OF_TYPE(probs, CV_64FC1) );
  1301. CV_ASSERT( ICV_IS_MAT_OF_TYPE(labels, CV_32SC1) );
  1302. nclusters = probs->cols;
  1303. nsamples = probs->rows;
  1304. CV_ASSERT( nsamples == labels->cols );
  1305. CV_CALL( counts = cvCreateMat( 1, nclusters + 1, CV_32SC1 ) );
  1306. CV_CALL( cvSetZero( counts ));
  1307. for( i = 0; i < nsamples; i++ )
  1308. {
  1309. labels->data.i[i] = icvGetNumberOfCluster( probs->data.db + i*probs->cols,
  1310. nclusters, r, outlier_thresh, 1 );
  1311. counts->data.i[labels->data.i[i] + 1]++;
  1312. }
  1313. CV_ASSERT((int)cvSum(counts).val[0] == nsamples);
  1314. // Filling empty clusters with the vector, that has the maximal probability
  1315. for( j = 0; j < nclusters; j++ ) // outliers are ignored
  1316. {
  1317. int maxprob_loc = -1;
  1318. double maxprob = 0;
  1319. if( counts->data.i[j+1] ) // j-th class is not empty
  1320. continue;
  1321. // look for the presentative, which is not lonely in it's cluster
  1322. // and that has a maximal probability among all these vectors
  1323. probs_data = probs->data.db;
  1324. for( i = 0; i < nsamples; i++, probs_data++ )
  1325. {
  1326. int label = labels->data.i[i];
  1327. double prob;
  1328. if( counts->data.i[label+1] == 0 ||
  1329. (counts->data.i[label+1] <= 1 && label != -1) )
  1330. continue;
  1331. prob = *probs_data;
  1332. if( prob >= maxprob )
  1333. {
  1334. maxprob = prob;
  1335. maxprob_loc = i;
  1336. }
  1337. }
  1338. // maxprob_loc == 0 <=> number of vectors less then number of clusters
  1339. CV_ASSERT( maxprob_loc >= 0 );
  1340. counts->data.i[labels->data.i[maxprob_loc] + 1]--;
  1341. labels->data.i[maxprob_loc] = j;
  1342. counts->data.i[j + 1]++;
  1343. }
  1344. __END__;
  1345. cvReleaseMat( &counts );
  1346. } // End of icvFindClusterLabels
  1347. /* End of file */