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 // For Open Source Computer Vision Library 12 // 13 // Copyright (C) 2000, Intel Corporation, all rights reserved. 14 // Third party copyrights are property of their respective owners. 15 // 16 // Redistribution and use in source and binary forms, with or without modification, 17 // are permitted provided that the following conditions are met: 18 // 19 // * Redistribution's of source code must retain the above copyright notice, 20 // this list of conditions and the following disclaimer. 21 // 22 // * Redistribution's in binary form must reproduce the above copyright notice, 23 // this list of conditions and the following disclaimer in the documentation 24 // and/or other materials provided with the distribution. 25 // 26 // * The name of Intel Corporation may not be used to endorse or promote products 27 // derived from this software without specific prior written permission. 28 // 29 // This software is provided by the copyright holders and contributors "as is" and 30 // any express or implied warranties, including, but not limited to, the implied 31 // warranties of merchantability and fitness for a particular purpose are disclaimed. 32 // In no event shall the Intel Corporation or contributors be liable for any direct, 33 // indirect, incidental, special, exemplary, or consequential damages 34 // (including, but not limited to, procurement of substitute goods or services; 35 // loss of use, data, or profits; or business interruption) however caused 36 // and on any theory of liability, whether in contract, strict liability, 37 // or tort (including negligence or otherwise) arising in any way out of 38 // the use of this software, even if advised of the possibility of such damage. 39 // 40 //M*/ 41 #include "_cv.h" 42 43 /*F/////////////////////////////////////////////////////////////////////////////////////// 44 // Name: cvMatchContours 45 // Purpose: 46 // Calculates matching of the two contours 47 // Context: 48 // Parameters: 49 // contour_1 - pointer to the first input contour object. 50 // contour_2 - pointer to the second input contour object. 51 // method - method for the matching calculation 52 // (now CV_IPPI_CONTOURS_MATCH_I1, CV_CONTOURS_MATCH_I2 or 53 // CV_CONTOURS_MATCH_I3 only ) 54 // rezult - output calculated measure 55 // 56 //F*/ 57 CV_IMPL double 58 cvMatchShapes( const void* contour1, const void* contour2, 59 int method, double /*parameter*/ ) 60 { 61 CvMoments moments; 62 CvHuMoments huMoments; 63 double ma[7], mb[7]; 64 int i, sma, smb; 65 double eps = 1.e-5; 66 double mmm; 67 double result = 0; 68 69 CV_FUNCNAME( "cvMatchShapes" ); 70 71 __BEGIN__; 72 73 if( !contour1 || !contour2 ) 74 CV_ERROR( CV_StsNullPtr, "" ); 75 76 /* first moments calculation */ 77 CV_CALL( cvMoments( contour1, &moments )); 78 79 /* Hu moments calculation */ 80 CV_CALL( cvGetHuMoments( &moments, &huMoments )); 81 82 ma[0] = huMoments.hu1; 83 ma[1] = huMoments.hu2; 84 ma[2] = huMoments.hu3; 85 ma[3] = huMoments.hu4; 86 ma[4] = huMoments.hu5; 87 ma[5] = huMoments.hu6; 88 ma[6] = huMoments.hu7; 89 90 91 /* second moments calculation */ 92 CV_CALL( cvMoments( contour2, &moments )); 93 94 /* Hu moments calculation */ 95 CV_CALL( cvGetHuMoments( &moments, &huMoments )); 96 97 mb[0] = huMoments.hu1; 98 mb[1] = huMoments.hu2; 99 mb[2] = huMoments.hu3; 100 mb[3] = huMoments.hu4; 101 mb[4] = huMoments.hu5; 102 mb[5] = huMoments.hu6; 103 mb[6] = huMoments.hu7; 104 105 switch (method) 106 { 107 case 1: 108 { 109 for( i = 0; i < 7; i++ ) 110 { 111 double ama = fabs( ma[i] ); 112 double amb = fabs( mb[i] ); 113 114 if( ma[i] > 0 ) 115 sma = 1; 116 else if( ma[i] < 0 ) 117 sma = -1; 118 else 119 sma = 0; 120 if( mb[i] > 0 ) 121 smb = 1; 122 else if( mb[i] < 0 ) 123 smb = -1; 124 else 125 smb = 0; 126 127 if( ama > eps && amb > eps ) 128 { 129 ama = 1. / (sma * log10( ama )); 130 amb = 1. / (smb * log10( amb )); 131 result += fabs( -ama + amb ); 132 } 133 } 134 break; 135 } 136 137 case 2: 138 { 139 for( i = 0; i < 7; i++ ) 140 { 141 double ama = fabs( ma[i] ); 142 double amb = fabs( mb[i] ); 143 144 if( ma[i] > 0 ) 145 sma = 1; 146 else if( ma[i] < 0 ) 147 sma = -1; 148 else 149 sma = 0; 150 if( mb[i] > 0 ) 151 smb = 1; 152 else if( mb[i] < 0 ) 153 smb = -1; 154 else 155 smb = 0; 156 157 if( ama > eps && amb > eps ) 158 { 159 ama = sma * log10( ama ); 160 amb = smb * log10( amb ); 161 result += fabs( -ama + amb ); 162 } 163 } 164 break; 165 } 166 167 case 3: 168 { 169 for( i = 0; i < 7; i++ ) 170 { 171 double ama = fabs( ma[i] ); 172 double amb = fabs( mb[i] ); 173 174 if( ma[i] > 0 ) 175 sma = 1; 176 else if( ma[i] < 0 ) 177 sma = -1; 178 else 179 sma = 0; 180 if( mb[i] > 0 ) 181 smb = 1; 182 else if( mb[i] < 0 ) 183 smb = -1; 184 else 185 smb = 0; 186 187 if( ama > eps && amb > eps ) 188 { 189 ama = sma * log10( ama ); 190 amb = smb * log10( amb ); 191 mmm = fabs( (ama - amb) / ama ); 192 if( result < mmm ) 193 result = mmm; 194 } 195 } 196 break; 197 } 198 default: 199 CV_ERROR_FROM_STATUS( CV_BADCOEF_ERR ); 200 } 201 202 __END__; 203 204 return result; 205 } 206 207 208 209 /*F/////////////////////////////////////////////////////////////////////////////////////// 210 // Name: icvMatchContourTrees 211 // Purpose: 212 // Calculates matching of the two contour trees 213 // Context: 214 // Parameters: 215 // tree1 - pointer to the first input contour tree object. 216 // tree2 - pointer to the second input contour tree object. 217 // method - method for the matching calculation 218 // (now CV_CONTOUR_TREES_MATCH_I1 only ) 219 // threshold - threshold for the contour trees matching 220 // result - output calculated measure 221 //F*/ 222 CV_IMPL double 223 cvMatchContourTrees( const CvContourTree* tree1, const CvContourTree* tree2, 224 int method, double threshold ) 225 { 226 _CvTrianAttr **ptr_p1 = 0, **ptr_p2 = 0; /*pointers to the pointer's buffer */ 227 _CvTrianAttr **ptr_n1 = 0, **ptr_n2 = 0; /*pointers to the pointer's buffer */ 228 _CvTrianAttr **ptr11, **ptr12, **ptr21, **ptr22; 229 230 int lpt1, lpt2, lpt, flag, flag_n, i, j, ibuf, ibuf1; 231 double match_v, d12, area1, area2, r11, r12, r21, r22, w1, w2; 232 double eps = 1.e-5; 233 char s1, s2; 234 _CvTrianAttr tree_1, tree_2; /*current vertex 1 and 2 tree */ 235 CvSeqReader reader1, reader2; 236 double result = 0; 237 238 CV_FUNCNAME("cvMatchContourTrees"); 239 __BEGIN__; 240 241 if( !tree1 || !tree2 ) 242 CV_ERROR( CV_StsNullPtr, "" ); 243 244 if( method != CV_CONTOUR_TREES_MATCH_I1 ) 245 CV_ERROR( CV_StsBadArg, "Unknown/unsupported comparison method" ); 246 247 if( !CV_IS_SEQ_POLYGON_TREE( tree1 )) 248 CV_ERROR( CV_StsBadArg, "The first argument is not a valid contour tree" ); 249 250 if( !CV_IS_SEQ_POLYGON_TREE( tree2 )) 251 CV_ERROR( CV_StsBadArg, "The second argument is not a valid contour tree" ); 252 253 lpt1 = tree1->total; 254 lpt2 = tree2->total; 255 lpt = lpt1 > lpt2 ? lpt1 : lpt2; 256 257 ptr_p1 = ptr_n1 = ptr_p2 = ptr_n2 = NULL; 258 CV_CALL( ptr_p1 = (_CvTrianAttr **) cvAlloc( lpt * sizeof( _CvTrianAttr * ))); 259 CV_CALL( ptr_p2 = (_CvTrianAttr **) cvAlloc( lpt * sizeof( _CvTrianAttr * ))); 260 261 CV_CALL( ptr_n1 = (_CvTrianAttr **) cvAlloc( lpt * sizeof( _CvTrianAttr * ))); 262 CV_CALL( ptr_n2 = (_CvTrianAttr **) cvAlloc( lpt * sizeof( _CvTrianAttr * ))); 263 264 cvStartReadSeq( (CvSeq *) tree1, &reader1, 0 ); 265 cvStartReadSeq( (CvSeq *) tree2, &reader2, 0 ); 266 267 /*read the root of the first and second tree*/ 268 CV_READ_SEQ_ELEM( tree_1, reader1 ); 269 CV_READ_SEQ_ELEM( tree_2, reader2 ); 270 271 /*write to buffer pointers to root's childs vertexs*/ 272 ptr_p1[0] = tree_1.next_v1; 273 ptr_p1[1] = tree_1.next_v2; 274 ptr_p2[0] = tree_2.next_v1; 275 ptr_p2[1] = tree_2.next_v2; 276 i = 2; 277 match_v = 0.; 278 area1 = tree_1.area; 279 area2 = tree_2.area; 280 281 if( area1 < eps || area2 < eps || lpt < 4 ) 282 CV_ERROR( CV_StsBadSize, "" ); 283 284 r11 = r12 = r21 = r22 = w1 = w2 = d12 = 0; 285 flag = 0; 286 s1 = s2 = 0; 287 do 288 { 289 if( flag == 0 ) 290 { 291 ptr11 = ptr_p1; 292 ptr12 = ptr_n1; 293 ptr21 = ptr_p2; 294 ptr22 = ptr_n2; 295 flag = 1; 296 } 297 else 298 { 299 ptr11 = ptr_n1; 300 ptr12 = ptr_p1; 301 ptr21 = ptr_n2; 302 ptr22 = ptr_p2; 303 flag = 0; 304 } 305 ibuf = 0; 306 for( j = 0; j < i; j++ ) 307 { 308 flag_n = 0; 309 if( ptr11[j] != NULL ) 310 { 311 r11 = ptr11[j]->r1; 312 r12 = ptr11[j]->r2; 313 flag_n = 1; 314 w1 = ptr11[j]->area / area1; 315 s1 = ptr11[j]->sign; 316 } 317 else 318 { 319 r11 = r21 = 0; 320 } 321 if( ptr21[j] != NULL ) 322 { 323 r21 = ptr21[j]->r1; 324 r22 = ptr21[j]->r2; 325 flag_n = 1; 326 w2 = ptr21[j]->area / area2; 327 s2 = ptr21[j]->sign; 328 } 329 else 330 { 331 r21 = r22 = 0; 332 } 333 if( flag_n != 0 ) 334 /* calculate node distance */ 335 { 336 switch (method) 337 { 338 case 1: 339 { 340 double t0, t1; 341 if( s1 != s2 ) 342 { 343 t0 = fabs( r11 * w1 + r21 * w2 ); 344 t1 = fabs( r12 * w1 + r22 * w2 ); 345 } 346 else 347 { 348 t0 = fabs( r11 * w1 - r21 * w2 ); 349 t1 = fabs( r12 * w1 - r22 * w2 ); 350 } 351 d12 = t0 + t1; 352 break; 353 } 354 } 355 match_v += d12; 356 ibuf1 = ibuf + 1; 357 /*write to buffer the pointer to child vertexes*/ 358 if( ptr11[j] != NULL ) 359 { 360 ptr12[ibuf] = ptr11[j]->next_v1; 361 ptr12[ibuf1] = ptr11[j]->next_v2; 362 } 363 else 364 { 365 ptr12[ibuf] = NULL; 366 ptr12[ibuf1] = NULL; 367 } 368 if( ptr21[j] != NULL ) 369 { 370 ptr22[ibuf] = ptr21[j]->next_v1; 371 ptr22[ibuf1] = ptr21[j]->next_v2; 372 } 373 else 374 { 375 ptr22[ibuf] = NULL; 376 ptr22[ibuf1] = NULL; 377 } 378 ibuf += 2; 379 } 380 } 381 i = ibuf; 382 } 383 while( i > 0 && match_v < threshold ); 384 385 result = match_v; 386 387 __END__; 388 389 cvFree( &ptr_n2 ); 390 cvFree( &ptr_n1 ); 391 cvFree( &ptr_p2 ); 392 cvFree( &ptr_p1 ); 393 394 return result; 395 } 396 397 398 /* End of file. */ 399