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*/ 57CV_IMPL double 58cvMatchShapes( 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*/ 222CV_IMPL double 223cvMatchContourTrees( 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