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 42 #include "_cxcore.h" 43 44 CV_IMPL void 45 cvKMeans2( const CvArr* samples_arr, int cluster_count, 46 CvArr* labels_arr, CvTermCriteria termcrit ) 47 { 48 CvMat* centers = 0; 49 CvMat* old_centers = 0; 50 CvMat* counters = 0; 51 52 CV_FUNCNAME( "cvKMeans2" ); 53 54 __BEGIN__; 55 56 CvMat samples_stub, labels_stub; 57 CvMat* samples = (CvMat*)samples_arr; 58 CvMat* labels = (CvMat*)labels_arr; 59 CvMat* temp = 0; 60 CvRNG rng = CvRNG(-1); 61 int i, j, k, sample_count, dims; 62 int ids_delta, iter; 63 double max_dist; 64 65 if( !CV_IS_MAT( samples )) 66 CV_CALL( samples = cvGetMat( samples, &samples_stub )); 67 68 if( !CV_IS_MAT( labels )) 69 CV_CALL( labels = cvGetMat( labels, &labels_stub )); 70 71 if( cluster_count < 1 ) 72 CV_ERROR( CV_StsOutOfRange, "Number of clusters should be positive" ); 73 74 if( CV_MAT_DEPTH(samples->type) != CV_32F || CV_MAT_TYPE(labels->type) != CV_32SC1 ) 75 CV_ERROR( CV_StsUnsupportedFormat, 76 "samples should be floating-point matrix, cluster_idx - integer vector" ); 77 78 if( (labels->rows != 1 && (labels->cols != 1 || !CV_IS_MAT_CONT(labels->type))) || 79 labels->rows + labels->cols - 1 != samples->rows ) 80 CV_ERROR( CV_StsUnmatchedSizes, 81 "cluster_idx should be 1D vector of the same number of elements as samples' number of rows" ); 82 83 CV_CALL( termcrit = cvCheckTermCriteria( termcrit, 1e-6, 100 )); 84 85 termcrit.epsilon *= termcrit.epsilon; 86 sample_count = samples->rows; 87 88 if( cluster_count > sample_count ) 89 cluster_count = sample_count; 90 91 dims = samples->cols*CV_MAT_CN(samples->type); 92 ids_delta = labels->step ? labels->step/(int)sizeof(int) : 1; 93 94 CV_CALL( centers = cvCreateMat( cluster_count, dims, CV_64FC1 )); 95 CV_CALL( old_centers = cvCreateMat( cluster_count, dims, CV_64FC1 )); 96 CV_CALL( counters = cvCreateMat( 1, cluster_count, CV_32SC1 )); 97 98 // init centers 99 for( i = 0; i < sample_count; i++ ) 100 labels->data.i[i] = cvRandInt(&rng) % cluster_count; 101 102 counters->cols = cluster_count; // cut down counters 103 max_dist = termcrit.epsilon*2; 104 105 for( iter = 0; iter < termcrit.max_iter; iter++ ) 106 { 107 // computer centers 108 cvZero( centers ); 109 cvZero( counters ); 110 111 for( i = 0; i < sample_count; i++ ) 112 { 113 float* s = (float*)(samples->data.ptr + i*samples->step); 114 k = labels->data.i[i*ids_delta]; 115 double* c = (double*)(centers->data.ptr + k*centers->step); 116 for( j = 0; j <= dims - 4; j += 4 ) 117 { 118 double t0 = c[j] + s[j]; 119 double t1 = c[j+1] + s[j+1]; 120 121 c[j] = t0; 122 c[j+1] = t1; 123 124 t0 = c[j+2] + s[j+2]; 125 t1 = c[j+3] + s[j+3]; 126 127 c[j+2] = t0; 128 c[j+3] = t1; 129 } 130 for( ; j < dims; j++ ) 131 c[j] += s[j]; 132 counters->data.i[k]++; 133 } 134 135 if( iter > 0 ) 136 max_dist = 0; 137 138 for( k = 0; k < cluster_count; k++ ) 139 { 140 double* c = (double*)(centers->data.ptr + k*centers->step); 141 if( counters->data.i[k] != 0 ) 142 { 143 double scale = 1./counters->data.i[k]; 144 for( j = 0; j < dims; j++ ) 145 c[j] *= scale; 146 } 147 else 148 { 149 i = cvRandInt( &rng ) % sample_count; 150 float* s = (float*)(samples->data.ptr + i*samples->step); 151 for( j = 0; j < dims; j++ ) 152 c[j] = s[j]; 153 } 154 155 if( iter > 0 ) 156 { 157 double dist = 0; 158 double* c_o = (double*)(old_centers->data.ptr + k*old_centers->step); 159 for( j = 0; j < dims; j++ ) 160 { 161 double t = c[j] - c_o[j]; 162 dist += t*t; 163 } 164 if( max_dist < dist ) 165 max_dist = dist; 166 } 167 } 168 169 // assign labels 170 for( i = 0; i < sample_count; i++ ) 171 { 172 float* s = (float*)(samples->data.ptr + i*samples->step); 173 int k_best = 0; 174 double min_dist = DBL_MAX; 175 176 for( k = 0; k < cluster_count; k++ ) 177 { 178 double* c = (double*)(centers->data.ptr + k*centers->step); 179 double dist = 0; 180 181 j = 0; 182 for( ; j <= dims - 4; j += 4 ) 183 { 184 double t0 = c[j] - s[j]; 185 double t1 = c[j+1] - s[j+1]; 186 dist += t0*t0 + t1*t1; 187 t0 = c[j+2] - s[j+2]; 188 t1 = c[j+3] - s[j+3]; 189 dist += t0*t0 + t1*t1; 190 } 191 192 for( ; j < dims; j++ ) 193 { 194 double t = c[j] - s[j]; 195 dist += t*t; 196 } 197 198 if( min_dist > dist ) 199 { 200 min_dist = dist; 201 k_best = k; 202 } 203 } 204 205 labels->data.i[i*ids_delta] = k_best; 206 } 207 208 if( max_dist < termcrit.epsilon ) 209 break; 210 211 CV_SWAP( centers, old_centers, temp ); 212 } 213 214 cvZero( counters ); 215 for( i = 0; i < sample_count; i++ ) 216 counters->data.i[labels->data.i[i]]++; 217 218 // ensure that we do not have empty clusters 219 for( k = 0; k < cluster_count; k++ ) 220 if( counters->data.i[k] == 0 ) 221 for(;;) 222 { 223 i = cvRandInt(&rng) % sample_count; 224 j = labels->data.i[i]; 225 if( counters->data.i[j] > 1 ) 226 { 227 labels->data.i[i] = k; 228 counters->data.i[j]--; 229 counters->data.i[k]++; 230 break; 231 } 232 } 233 234 __END__; 235 236 cvReleaseMat( ¢ers ); 237 cvReleaseMat( &old_centers ); 238 cvReleaseMat( &counters ); 239 } 240 241 242 /* 243 Finds real roots of cubic, quadratic or linear equation. 244 The original code has been taken from Ken Turkowski web page 245 (http://www.worldserver.com/turk/opensource/) and adopted for OpenCV. 246 Here is the copyright notice. 247 248 ----------------------------------------------------------------------- 249 Copyright (C) 1978-1999 Ken Turkowski. <turk (at) computer.org> 250 251 All rights reserved. 252 253 Warranty Information 254 Even though I have reviewed this software, I make no warranty 255 or representation, either express or implied, with respect to this 256 software, its quality, accuracy, merchantability, or fitness for a 257 particular purpose. As a result, this software is provided "as is," 258 and you, its user, are assuming the entire risk as to its quality 259 and accuracy. 260 261 This code may be used and freely distributed as long as it includes 262 this copyright notice and the above warranty information. 263 ----------------------------------------------------------------------- 264 */ 265 CV_IMPL int 266 cvSolveCubic( const CvMat* coeffs, CvMat* roots ) 267 { 268 int n = 0; 269 270 CV_FUNCNAME( "cvSolveCubic" ); 271 272 __BEGIN__; 273 274 double a0 = 1., a1, a2, a3; 275 double x0 = 0., x1 = 0., x2 = 0.; 276 int step = 1, coeff_count; 277 278 if( !CV_IS_MAT(coeffs) ) 279 CV_ERROR( !coeffs ? CV_StsNullPtr : CV_StsBadArg, "Input parameter is not a valid matrix" ); 280 281 if( !CV_IS_MAT(roots) ) 282 CV_ERROR( !roots ? CV_StsNullPtr : CV_StsBadArg, "Output parameter is not a valid matrix" ); 283 284 if( (CV_MAT_TYPE(coeffs->type) != CV_32FC1 && CV_MAT_TYPE(coeffs->type) != CV_64FC1) || 285 (CV_MAT_TYPE(roots->type) != CV_32FC1 && CV_MAT_TYPE(roots->type) != CV_64FC1) ) 286 CV_ERROR( CV_StsUnsupportedFormat, 287 "Both matrices should be floating-point (single or double precision)" ); 288 289 coeff_count = coeffs->rows + coeffs->cols - 1; 290 291 if( (coeffs->rows != 1 && coeffs->cols != 1) || (coeff_count != 3 && coeff_count != 4) ) 292 CV_ERROR( CV_StsBadSize, 293 "The matrix of coefficients must be 1-dimensional vector of 3 or 4 elements" ); 294 295 if( (roots->rows != 1 && roots->cols != 1) || 296 roots->rows + roots->cols - 1 != 3 ) 297 CV_ERROR( CV_StsBadSize, 298 "The matrix of roots must be 1-dimensional vector of 3 elements" ); 299 300 if( CV_MAT_TYPE(coeffs->type) == CV_32FC1 ) 301 { 302 const float* c = coeffs->data.fl; 303 if( coeffs->rows > 1 ) 304 step = coeffs->step/sizeof(c[0]); 305 if( coeff_count == 4 ) 306 a0 = c[0], c += step; 307 a1 = c[0]; 308 a2 = c[step]; 309 a3 = c[step*2]; 310 } 311 else 312 { 313 const double* c = coeffs->data.db; 314 if( coeffs->rows > 1 ) 315 step = coeffs->step/sizeof(c[0]); 316 if( coeff_count == 4 ) 317 a0 = c[0], c += step; 318 a1 = c[0]; 319 a2 = c[step]; 320 a3 = c[step*2]; 321 } 322 323 if( a0 == 0 ) 324 { 325 if( a1 == 0 ) 326 { 327 if( a2 == 0 ) 328 n = a3 == 0 ? -1 : 0; 329 else 330 { 331 // linear equation 332 x0 = a3/a2; 333 n = 1; 334 } 335 } 336 else 337 { 338 // quadratic equation 339 double d = a2*a2 - 4*a1*a3; 340 if( d >= 0 ) 341 { 342 d = sqrt(d); 343 double q = (-a2 + (a2 < 0 ? -d : d)) * 0.5; 344 x0 = q / a1; 345 x1 = a3 / q; 346 n = d > 0 ? 2 : 1; 347 } 348 } 349 } 350 else 351 { 352 a0 = 1./a0; 353 a1 *= a0; 354 a2 *= a0; 355 a3 *= a0; 356 357 double Q = (a1 * a1 - 3 * a2) * (1./9); 358 double R = (2 * a1 * a1 * a1 - 9 * a1 * a2 + 27 * a3) * (1./54); 359 double Qcubed = Q * Q * Q; 360 double d = Qcubed - R * R; 361 362 if( d >= 0 ) 363 { 364 double theta = acos(R / sqrt(Qcubed)); 365 double sqrtQ = sqrt(Q); 366 double t0 = -2 * sqrtQ; 367 double t1 = theta * (1./3); 368 double t2 = a1 * (1./3); 369 x0 = t0 * cos(t1) - t2; 370 x1 = t0 * cos(t1 + (2.*CV_PI/3)) - t2; 371 x2 = t0 * cos(t1 + (4.*CV_PI/3)) - t2; 372 n = 3; 373 } 374 else 375 { 376 double e; 377 d = sqrt(-d); 378 e = pow(d + fabs(R), 0.333333333333); 379 if( R > 0 ) 380 e = -e; 381 x0 = (e + Q / e) - a1 * (1./3); 382 n = 1; 383 } 384 } 385 386 step = 1; 387 388 if( CV_MAT_TYPE(roots->type) == CV_32FC1 ) 389 { 390 float* r = roots->data.fl; 391 if( roots->rows > 1 ) 392 step = roots->step/sizeof(r[0]); 393 r[0] = (float)x0; 394 r[step] = (float)x1; 395 r[step*2] = (float)x2; 396 } 397 else 398 { 399 double* r = roots->data.db; 400 if( roots->rows > 1 ) 401 step = roots->step/sizeof(r[0]); 402 r[0] = x0; 403 r[step] = x1; 404 r[step*2] = x2; 405 } 406 407 __END__; 408 409 return n; 410 } 411 412 413 /* 414 Finds real and complex roots of polynomials of any degree with real 415 coefficients. The original code has been taken from Ken Turkowski's web 416 page (http://www.worldserver.com/turk/opensource/) and adopted for OpenCV. 417 Here is the copyright notice. 418 419 ----------------------------------------------------------------------- 420 Copyright (C) 1981-1999 Ken Turkowski. <turk (at) computer.org> 421 422 All rights reserved. 423 424 Warranty Information 425 Even though I have reviewed this software, I make no warranty 426 or representation, either express or implied, with respect to this 427 software, its quality, accuracy, merchantability, or fitness for a 428 particular purpose. As a result, this software is provided "as is," 429 and you, its user, are assuming the entire risk as to its quality 430 and accuracy. 431 432 This code may be used and freely distributed as long as it includes 433 this copyright notice and the above warranty information. 434 */ 435 436 437 /******************************************************************************* 438 * FindPolynomialRoots 439 * 440 * The Bairstow and Newton correction formulae are used for a simultaneous 441 * linear and quadratic iterated synthetic division. The coefficients of 442 * a polynomial of degree n are given as a[i] (i=0,i,..., n) where a[0] is 443 * the constant term. The coefficients are scaled by dividing them by 444 * their geometric mean. The Bairstow or Newton iteration method will 445 * nearly always converge to the number of figures carried, fig, either to 446 * root values or to their reciprocals. If the simultaneous Newton and 447 * Bairstow iteration fails to converge on root values or their 448 * reciprocals in maxiter iterations, the convergence requirement will be 449 * successively reduced by one decimal figure. This program anticipates 450 * and protects against loss of significance in the quadratic synthetic 451 * division. (Refer to "On Programming the Numerical Solution of 452 * Polynomial Equations," by K. W. Ellenberger, Commun. ACM 3 (Dec. 1960), 453 * 644-647.) The real and imaginary part of each root is stated as u[i] 454 * and v[i], respectively. 455 * 456 * ACM algorithm #30 - Numerical Solution of the Polynomial Equation 457 * K. W. Ellenberger 458 * Missle Division, North American Aviation, Downey, California 459 * Converted to C, modified, optimized, and structured by 460 * Ken Turkowski 461 * CADLINC, Inc., Palo Alto, California 462 *******************************************************************************/ 463 464 #define MAXN 16 465 466 static void icvFindPolynomialRoots(const double *a, double *u, int n, int maxiter, int fig) 467 { 468 int i; 469 int j; 470 double h[MAXN + 3], b[MAXN + 3], c[MAXN + 3], d[MAXN + 3], e[MAXN + 3]; 471 // [-2 : n] 472 double K, ps, qs, pt, qt, s, rev, r = 0; 473 int t; 474 double p = 0, q = 0, qq; 475 476 // Zero elements with negative indices 477 b[2 + -1] = b[2 + -2] = 478 c[2 + -1] = c[2 + -2] = 479 d[2 + -1] = d[2 + -2] = 480 e[2 + -1] = e[2 + -2] = 481 h[2 + -1] = h[2 + -2] = 0.0; 482 483 // Copy polynomial coefficients to working storage 484 for (j = n; j >= 0; j--) 485 h[2 + j] = *a++; // Note reversal of coefficients 486 487 t = 1; 488 K = pow(10.0, (double)(fig)); // Relative accuracy 489 490 for (; h[2 + n] == 0.0; n--) { // Look for zero high-order coeff. 491 *u++ = 0.0; 492 *u++ = 0.0; 493 } 494 495 INIT: 496 if (n == 0) 497 return; 498 499 ps = qs = pt = qt = s = 0.0; 500 rev = 1.0; 501 K = pow(10.0, (double)(fig)); 502 503 if (n == 1) { 504 r = -h[2 + 1] / h[2 + 0]; 505 goto LINEAR; 506 } 507 508 for (j = n; j >= 0; j--) // Find geometric mean of coeff's 509 if (h[2 + j] != 0.0) 510 s += log(fabs(h[2 + j])); 511 s = exp(s / (n + 1)); 512 513 for (j = n; j >= 0; j--) // Normalize coeff's by mean 514 h[2 + j] /= s; 515 516 if (fabs(h[2 + 1] / h[2 + 0]) < fabs(h[2 + n - 1] / h[2 + n])) { 517 REVERSE: 518 t = -t; 519 for (j = (n - 1) / 2; j >= 0; j--) { 520 s = h[2 + j]; 521 h[2 + j] = h[2 + n - j]; 522 h[2 + n - j] = s; 523 } 524 } 525 if (qs != 0.0) { 526 p = ps; 527 q = qs; 528 } else { 529 if (h[2 + n - 2] == 0.0) { 530 q = 1.0; 531 p = -2.0; 532 } else { 533 q = h[2 + n] / h[2 + n - 2]; 534 p = (h[2 + n - 1] - q * h[2 + n - 3]) / h[2 + n - 2]; 535 } 536 if (n == 2) 537 goto QADRTIC; 538 r = 0.0; 539 } 540 ITERATE: 541 for (i = maxiter; i > 0; i--) { 542 543 for (j = 0; j <= n; j++) { // BAIRSTOW 544 b[2 + j] = h[2 + j] - p * b[2 + j - 1] - q * b[2 + j - 2]; 545 c[2 + j] = b[2 + j] - p * c[2 + j - 1] - q * c[2 + j - 2]; 546 } 547 if ((h[2 + n - 1] != 0.0) && (b[2 + n - 1] != 0.0)) { 548 if (fabs(h[2 + n - 1] / b[2 + n - 1]) >= K) { 549 b[2 + n] = h[2 + n] - q * b[2 + n - 2]; 550 } 551 if (b[2 + n] == 0.0) 552 goto QADRTIC; 553 if (K < fabs(h[2 + n] / b[2 + n])) 554 goto QADRTIC; 555 } 556 557 for (j = 0; j <= n; j++) { // NEWTON 558 d[2 + j] = h[2 + j] + r * d[2 + j - 1]; // Calculate polynomial at r 559 e[2 + j] = d[2 + j] + r * e[2 + j - 1]; // Calculate derivative at r 560 } 561 if (d[2 + n] == 0.0) 562 goto LINEAR; 563 if (K < fabs(h[2 + n] / d[2 + n])) 564 goto LINEAR; 565 566 c[2 + n - 1] = -p * c[2 + n - 2] - q * c[2 + n - 3]; 567 s = c[2 + n - 2] * c[2 + n - 2] - c[2 + n - 1] * c[2 + n - 3]; 568 if (s == 0.0) { 569 p -= 2.0; 570 q *= (q + 1.0); 571 } else { 572 p += (b[2 + n - 1] * c[2 + n - 2] - b[2 + n] * c[2 + n - 3]) / s; 573 q += (-b[2 + n - 1] * c[2 + n - 1] + b[2 + n] * c[2 + n - 2]) / s; 574 } 575 if (e[2 + n - 1] == 0.0) 576 r -= 1.0; // Minimum step 577 else 578 r -= d[2 + n] / e[2 + n - 1]; // Newton's iteration 579 } 580 ps = pt; 581 qs = qt; 582 pt = p; 583 qt = q; 584 if (rev < 0.0) 585 K /= 10.0; 586 rev = -rev; 587 goto REVERSE; 588 589 LINEAR: 590 if (t < 0) 591 r = 1.0 / r; 592 n--; 593 *u++ = r; 594 *u++ = 0.0; 595 596 for (j = n; j >= 0; j--) { // Polynomial deflation by lin-nomial 597 if ((d[2 + j] != 0.0) && (fabs(h[2 + j] / d[2 + j]) < K)) 598 h[2 + j] = d[2 + j]; 599 else 600 h[2 + j] = 0.0; 601 } 602 603 if (n == 0) 604 return; 605 goto ITERATE; 606 607 QADRTIC: 608 if (t < 0) { 609 p /= q; 610 q = 1.0 / q; 611 } 612 n -= 2; 613 614 if (0.0 < (q - (p * p / 4.0))) { // Two complex roots 615 s = sqrt(q - (p * p / 4.0)); 616 *u++ = -p / 2.0; 617 *u++ = s; 618 *u++ = -p / 2.0; 619 *u++ = -s; 620 } else { // Two real roots 621 s = sqrt(((p * p / 4.0)) - q); 622 if (p < 0.0) 623 *u++ = qq = -p / 2.0 + s; 624 else 625 *u++ = qq = -p / 2.0 - s; 626 *u++ = 0.0; 627 *u++ = q / qq; 628 *u++ = 0.0; 629 } 630 631 for (j = n; j >= 0; j--) { // Polynomial deflation by quadratic 632 if ((b[2 + j] != 0.0) && (fabs(h[2 + j] / b[2 + j]) < K)) 633 h[2 + j] = b[2 + j]; 634 else 635 h[2 + j] = 0.0; 636 } 637 goto INIT; 638 } 639 640 #undef MAXN 641 642 void cvSolvePoly(const CvMat* a, CvMat *r, int maxiter, int fig) 643 { 644 __BEGIN__; 645 646 int m, n; 647 double *ad = 0, *rd = 0; 648 649 CV_FUNCNAME("cvSolvePoly"); 650 651 if (CV_MAT_TYPE(a->type) != CV_32FC1 && 652 CV_MAT_TYPE(a->type) != CV_64FC1) 653 CV_ERROR(CV_StsUnsupportedFormat, "coeffs must be either CV_32FC1 or CV_64FC1"); 654 if (CV_MAT_TYPE(r->type) != CV_32FC2 && 655 CV_MAT_TYPE(r->type) != CV_64FC2) 656 CV_ERROR(CV_StsUnsupportedFormat, "roots must be either CV_32FC2 or CV_64FC2"); 657 m = a->rows * a->cols; 658 n = r->rows * r->cols; 659 660 if (m - 1 != n) 661 CV_ERROR(CV_StsUnmatchedFormats, "must have n + 1 coefficients"); 662 663 if( CV_MAT_TYPE(a->type) == CV_32F || !CV_IS_MAT_CONT(a->type)) 664 { 665 ad = (double*)cvStackAlloc(m*sizeof(ad[0])); 666 CvMat _a = cvMat( a->rows, a->cols, CV_64F, ad ); 667 cvConvert( a, &_a ); 668 } 669 else 670 ad = a->data.db; 671 672 if( CV_MAT_TYPE(r->type) == CV_32F || !CV_IS_MAT_CONT(r->type)) 673 rd = (double*)cvStackAlloc(n*sizeof(ad[0])); 674 else 675 rd = r->data.db; 676 677 icvFindPolynomialRoots( ad, rd, n, maxiter, fig); 678 if( rd != r->data.db ) 679 { 680 CvMat _r = cvMat( r->rows, r->cols, CV_64F, rd ); 681 cvConvert( &_r, r ); 682 } 683 684 __END__; 685 } 686 687 688 CV_IMPL void cvNormalize( const CvArr* src, CvArr* dst, 689 double a, double b, int norm_type, const CvArr* mask ) 690 { 691 CvMat* tmp = 0; 692 693 CV_FUNCNAME( "cvNormalize" ); 694 695 __BEGIN__; 696 697 double scale, shift; 698 699 if( norm_type == CV_MINMAX ) 700 { 701 double smin = 0, smax = 0; 702 double dmin = MIN( a, b ), dmax = MAX( a, b ); 703 cvMinMaxLoc( src, &smin, &smax, 0, 0, mask ); 704 scale = (dmax - dmin)*(smax - smin > DBL_EPSILON ? 1./(smax - smin) : 0); 705 shift = dmin - smin*scale; 706 } 707 else if( norm_type == CV_L2 || norm_type == CV_L1 || norm_type == CV_C ) 708 { 709 CvMat *s = (CvMat*)src, *d = (CvMat*)dst; 710 711 if( CV_IS_MAT(s) && CV_IS_MAT(d) && CV_IS_MAT_CONT(s->type & d->type) && 712 CV_ARE_TYPES_EQ(s,d) && CV_ARE_SIZES_EQ(s,d) && !mask && 713 s->cols*s->rows <= CV_MAX_INLINE_MAT_OP_SIZE*CV_MAX_INLINE_MAT_OP_SIZE ) 714 { 715 int i, len = s->cols*s->rows; 716 double norm = 0, v; 717 718 if( CV_MAT_TYPE(s->type) == CV_32FC1 ) 719 { 720 const float* sptr = s->data.fl; 721 float* dptr = d->data.fl; 722 723 if( norm_type == CV_L2 ) 724 { 725 for( i = 0; i < len; i++ ) 726 { 727 v = sptr[i]; 728 norm += v*v; 729 } 730 norm = sqrt(norm); 731 } 732 else if( norm_type == CV_L1 ) 733 for( i = 0; i < len; i++ ) 734 { 735 v = fabs((double)sptr[i]); 736 norm += v; 737 } 738 else 739 for( i = 0; i < len; i++ ) 740 { 741 v = fabs((double)sptr[i]); 742 norm = MAX(norm,v); 743 } 744 745 norm = norm > DBL_EPSILON ? 1./norm : 0.; 746 for( i = 0; i < len; i++ ) 747 dptr[i] = (float)(sptr[i]*norm); 748 EXIT; 749 } 750 751 if( CV_MAT_TYPE(s->type) == CV_64FC1 ) 752 { 753 const double* sptr = s->data.db; 754 double* dptr = d->data.db; 755 756 if( norm_type == CV_L2 ) 757 { 758 for( i = 0; i < len; i++ ) 759 { 760 v = sptr[i]; 761 norm += v*v; 762 } 763 norm = sqrt(norm); 764 } 765 else if( norm_type == CV_L1 ) 766 for( i = 0; i < len; i++ ) 767 { 768 v = fabs(sptr[i]); 769 norm += v; 770 } 771 else 772 for( i = 0; i < len; i++ ) 773 { 774 v = fabs(sptr[i]); 775 norm = MAX(norm,v); 776 } 777 778 norm = norm > DBL_EPSILON ? 1./norm : 0.; 779 for( i = 0; i < len; i++ ) 780 dptr[i] = sptr[i]*norm; 781 EXIT; 782 } 783 } 784 785 scale = cvNorm( src, 0, norm_type, mask ); 786 scale = scale > DBL_EPSILON ? 1./scale : 0.; 787 shift = 0; 788 } 789 else 790 CV_ERROR( CV_StsBadArg, "Unknown/unsupported norm type" ); 791 792 if( !mask ) 793 cvConvertScale( src, dst, scale, shift ); 794 else 795 { 796 CvMat stub, *dmat; 797 CV_CALL( dmat = cvGetMat(dst, &stub)); 798 CV_CALL( tmp = cvCreateMat(dmat->rows, dmat->cols, dmat->type) ); 799 cvConvertScale( src, tmp, scale, shift ); 800 cvCopy( tmp, dst, mask ); 801 } 802 803 __END__; 804 805 if( tmp ) 806 cvReleaseMat( &tmp ); 807 } 808 809 810 CV_IMPL void cvRandShuffle( CvArr* arr, CvRNG* rng, double iter_factor ) 811 { 812 CV_FUNCNAME( "cvRandShuffle" ); 813 814 __BEGIN__; 815 816 const int sizeof_int = (int)sizeof(int); 817 CvMat stub, *mat = (CvMat*)arr; 818 int i, j, k, iters, delta = 0; 819 int cont_flag, arr_size, elem_size, cols, step; 820 const int pair_buf_sz = 100; 821 int* pair_buf = (int*)cvStackAlloc( pair_buf_sz*sizeof(pair_buf[0])*2 ); 822 CvMat _pair_buf = cvMat( 1, pair_buf_sz*2, CV_32S, pair_buf ); 823 CvRNG _rng = cvRNG(-1); 824 uchar* data = 0; 825 int* idata = 0; 826 827 if( !CV_IS_MAT(mat) ) 828 CV_CALL( mat = cvGetMat( mat, &stub )); 829 830 if( !rng ) 831 rng = &_rng; 832 833 cols = mat->cols; 834 step = mat->step; 835 arr_size = cols*mat->rows; 836 iters = cvRound(iter_factor*arr_size)*2; 837 cont_flag = CV_IS_MAT_CONT(mat->type); 838 elem_size = CV_ELEM_SIZE(mat->type); 839 if( elem_size % sizeof_int == 0 && (cont_flag || step % sizeof_int == 0) ) 840 { 841 idata = mat->data.i; 842 step /= sizeof_int; 843 elem_size /= sizeof_int; 844 } 845 else 846 data = mat->data.ptr; 847 848 for( i = 0; i < iters; i += delta ) 849 { 850 delta = MIN( iters - i, pair_buf_sz*2 ); 851 _pair_buf.cols = delta; 852 cvRandArr( rng, &_pair_buf, CV_RAND_UNI, cvRealScalar(0), cvRealScalar(arr_size) ); 853 854 if( cont_flag ) 855 { 856 if( idata ) 857 for( j = 0; j < delta; j += 2 ) 858 { 859 int* p = idata + pair_buf[j]*elem_size, *q = idata + pair_buf[j+1]*elem_size, t; 860 for( k = 0; k < elem_size; k++ ) 861 CV_SWAP( p[k], q[k], t ); 862 } 863 else 864 for( j = 0; j < delta; j += 2 ) 865 { 866 uchar* p = data + pair_buf[j]*elem_size, *q = data + pair_buf[j+1]*elem_size, t; 867 for( k = 0; k < elem_size; k++ ) 868 CV_SWAP( p[k], q[k], t ); 869 } 870 } 871 else 872 { 873 if( idata ) 874 for( j = 0; j < delta; j += 2 ) 875 { 876 int idx1 = pair_buf[j], idx2 = pair_buf[j+1], row1, row2; 877 int* p, *q, t; 878 row1 = idx1/step; row2 = idx2/step; 879 p = idata + row1*step + (idx1 - row1*cols)*elem_size; 880 q = idata + row2*step + (idx2 - row2*cols)*elem_size; 881 882 for( k = 0; k < elem_size; k++ ) 883 CV_SWAP( p[k], q[k], t ); 884 } 885 else 886 for( j = 0; j < delta; j += 2 ) 887 { 888 int idx1 = pair_buf[j], idx2 = pair_buf[j+1], row1, row2; 889 uchar* p, *q, t; 890 row1 = idx1/step; row2 = idx2/step; 891 p = data + row1*step + (idx1 - row1*cols)*elem_size; 892 q = data + row2*step + (idx2 - row2*cols)*elem_size; 893 894 for( k = 0; k < elem_size; k++ ) 895 CV_SWAP( p[k], q[k], t ); 896 } 897 } 898 } 899 900 __END__; 901 } 902 903 904 CV_IMPL CvArr* 905 cvRange( CvArr* arr, double start, double end ) 906 { 907 int ok = 0; 908 909 CV_FUNCNAME( "cvRange" ); 910 911 __BEGIN__; 912 913 CvMat stub, *mat = (CvMat*)arr; 914 double delta; 915 int type, step; 916 double val = start; 917 int i, j; 918 int rows, cols; 919 920 if( !CV_IS_MAT(mat) ) 921 CV_CALL( mat = cvGetMat( mat, &stub) ); 922 923 rows = mat->rows; 924 cols = mat->cols; 925 type = CV_MAT_TYPE(mat->type); 926 delta = (end-start)/(rows*cols); 927 928 if( CV_IS_MAT_CONT(mat->type) ) 929 { 930 cols *= rows; 931 rows = 1; 932 step = 1; 933 } 934 else 935 step = mat->step / CV_ELEM_SIZE(type); 936 937 if( type == CV_32SC1 ) 938 { 939 int* idata = mat->data.i; 940 int ival = cvRound(val), idelta = cvRound(delta); 941 942 if( fabs(val - ival) < DBL_EPSILON && 943 fabs(delta - idelta) < DBL_EPSILON ) 944 { 945 for( i = 0; i < rows; i++, idata += step ) 946 for( j = 0; j < cols; j++, ival += idelta ) 947 idata[j] = ival; 948 } 949 else 950 { 951 for( i = 0; i < rows; i++, idata += step ) 952 for( j = 0; j < cols; j++, val += delta ) 953 idata[j] = cvRound(val); 954 } 955 } 956 else if( type == CV_32FC1 ) 957 { 958 float* fdata = mat->data.fl; 959 for( i = 0; i < rows; i++, fdata += step ) 960 for( j = 0; j < cols; j++, val += delta ) 961 fdata[j] = (float)val; 962 } 963 else 964 CV_ERROR( CV_StsUnsupportedFormat, "The function only supports 32sC1 and 32fC1 datatypes" ); 965 966 ok = 1; 967 968 __END__; 969 970 return ok ? arr : 0; 971 } 972 973 974 #define ICV_LT_BY_IDX(a, b) (aux[a] < aux[b]) 975 976 static CV_IMPLEMENT_QSORT_EX( icvSortIdx64f, int, ICV_LT_BY_IDX, const double* ) 977 static CV_IMPLEMENT_QSORT_EX( icvSortIdx32f, int, ICV_LT_BY_IDX, const float* ) 978 static CV_IMPLEMENT_QSORT_EX( icvSortIdx32s, int, ICV_LT_BY_IDX, const int* ) 979 static CV_IMPLEMENT_QSORT_EX( icvSortIdx16u, int, ICV_LT_BY_IDX, const ushort* ) 980 static CV_IMPLEMENT_QSORT_EX( icvSortIdx16s, int, ICV_LT_BY_IDX, const short* ) 981 static CV_IMPLEMENT_QSORT_EX( icvSortIdx8u, int, ICV_LT_BY_IDX, const uchar* ) 982 static CV_IMPLEMENT_QSORT_EX( icvSortIdx8s, int, ICV_LT_BY_IDX, const schar* ) 983 984 static CV_IMPLEMENT_QSORT_EX( icvSort64f, double, CV_LT, int ) 985 static CV_IMPLEMENT_QSORT_EX( icvSort32f, float, CV_LT, int ) 986 static CV_IMPLEMENT_QSORT_EX( icvSort32s, int, CV_LT, int ) 987 static CV_IMPLEMENT_QSORT_EX( icvSort16u, ushort, CV_LT, int ) 988 static CV_IMPLEMENT_QSORT_EX( icvSort16s, short, CV_LT, int ) 989 static CV_IMPLEMENT_QSORT_EX( icvSort8u, uchar, CV_LT, int ) 990 static CV_IMPLEMENT_QSORT_EX( icvSort8s, schar, CV_LT, int ) 991 992 typedef void (*CvSortFunc)( void* arr, size_t n, int ); 993 typedef void (*CvSortIdxFunc)( int* arr, size_t n, const void* ); 994 995 static inline void 996 icvCopy1D( const void* src, int s, void* dst, int d, int n, int elemSize ) 997 { 998 int i; 999 switch( elemSize ) 1000 { 1001 case 1: 1002 for( i = 0; i < n; i++ ) 1003 ((uchar*)dst)[i*d] = ((uchar*)src)[i*s]; 1004 break; 1005 case 2: 1006 for( i = 0; i < n; i++ ) 1007 ((ushort*)dst)[i*d] = ((ushort*)src)[i*s]; 1008 break; 1009 case 4: 1010 for( i = 0; i < n; i++ ) 1011 ((int*)dst)[i*d] = ((int*)src)[i*s]; 1012 break; 1013 case 8: 1014 for( i = 0; i < n; i++ ) 1015 ((int64*)dst)[i*d] = ((int64*)src)[i*s]; 1016 break; 1017 default: 1018 assert(0); 1019 } 1020 } 1021 1022 static void 1023 icvShuffle1D( const uchar* src, const int* idx, uchar* dst, int d, int n, int elemSize ) 1024 { 1025 int i; 1026 switch( elemSize ) 1027 { 1028 case 1: 1029 for( i = 0; i < n; i++ ) 1030 dst[i*d] = src[idx[i]]; 1031 break; 1032 case 2: 1033 for( i = 0; i < n; i++ ) 1034 ((ushort*)dst)[i*d] = ((ushort*)src)[idx[i]]; 1035 break; 1036 case 4: 1037 for( i = 0; i < n; i++ ) 1038 ((int*)dst)[i*d] = ((int*)src)[idx[i]]; 1039 break; 1040 case 8: 1041 for( i = 0; i < n; i++ ) 1042 ((int64*)dst)[i*d] = ((int64*)src)[idx[i]]; 1043 break; 1044 default: 1045 assert(0); 1046 } 1047 } 1048 1049 1050 CV_IMPL void 1051 cvSort( const CvArr* _src, CvArr* _dst, CvArr* _idx, int flags ) 1052 { 1053 uchar *tsrc = 0; 1054 int* tidx = 0; 1055 1056 CV_FUNCNAME("cvSort"); 1057 1058 __BEGIN__; 1059 1060 CvMat sstub, *src = cvGetMat(_src, &sstub); 1061 CvMat dstub, *dst = _dst ? cvGetMat(_dst, &dstub) : 0; 1062 CvMat istub, *idx = _idx ? cvGetMat(_idx, &istub) : 0; 1063 int type = CV_MAT_TYPE(src->type), elemSize = CV_ELEM_SIZE(type); 1064 int sstep = src->step, dstep = dst ? dst->step : 0; 1065 int istep = idx ? idx->step/sizeof(int) : 0; 1066 int i, len = src->cols; 1067 CvSortFunc sortFunc = 0; 1068 CvSortIdxFunc sortIdxFunc = 0; 1069 1070 if( CV_MAT_CN( src->type ) != 1 ) 1071 CV_ERROR( CV_StsUnsupportedFormat, "The input matrix should be a one-channel matrix." ); 1072 if( idx ) 1073 { 1074 if( CV_MAT_TYPE( idx->type ) != CV_32SC1) 1075 CV_ERROR( CV_StsUnsupportedFormat, "The index matrix must be CV_32SC1." ); 1076 1077 if( !CV_ARE_SIZES_EQ( idx, src )) 1078 CV_ERROR( CV_StsUnmatchedSizes, "The input matrix and index matrix must be of the same size" ); 1079 } 1080 1081 if( dst ) 1082 { 1083 if( !CV_ARE_TYPES_EQ(src, dst) ) 1084 CV_ERROR( CV_StsUnmatchedFormats, "The input and output matrix must be of the same type" ); 1085 1086 if( !CV_ARE_SIZES_EQ(src, dst) ) 1087 CV_ERROR( CV_StsUnmatchedSizes, "The input and output matrix must be of the same size" ); 1088 } 1089 1090 if( !idx && !dst ) 1091 CV_ERROR( CV_StsNullPtr, "At least one of index array or destination array must be non-NULL" ); 1092 1093 if( type == CV_8U ) 1094 sortIdxFunc = (CvSortIdxFunc)icvSortIdx8u, sortFunc = (CvSortFunc)icvSort8u; 1095 else if( type == CV_8S ) 1096 sortIdxFunc = (CvSortIdxFunc)icvSortIdx8s, sortFunc = (CvSortFunc)icvSort8s; 1097 else if( type == CV_16U ) 1098 sortIdxFunc = (CvSortIdxFunc)icvSortIdx16u, sortFunc = (CvSortFunc)icvSort16u; 1099 else if( type == CV_16S ) 1100 sortIdxFunc = (CvSortIdxFunc)icvSortIdx16s, sortFunc = (CvSortFunc)icvSort16s; 1101 else if( type == CV_32S ) 1102 sortIdxFunc = (CvSortIdxFunc)icvSortIdx32s, sortFunc = (CvSortFunc)icvSort32s; 1103 else if( type == CV_32F ) 1104 sortIdxFunc = (CvSortIdxFunc)icvSortIdx32f, sortFunc = (CvSortFunc)icvSort32f; 1105 else if( type == CV_64F ) 1106 sortIdxFunc = (CvSortIdxFunc)icvSortIdx64f, sortFunc = (CvSortFunc)icvSort64f; 1107 else 1108 CV_ERROR( CV_StsUnsupportedFormat, "Unsupported format of the input array" ); 1109 1110 // single-column case, where all of src, idx & dst arrays are continuous, is 1111 // equivalent to "sort every row" mode. 1112 if( (flags & CV_SORT_EVERY_COLUMN) && 1113 (src->cols > 1 || !CV_IS_MAT_CONT(src->type & 1114 (dst ? dst->type : -1) & (idx ? idx->type : -1))) ) 1115 { 1116 uchar* dptr = dst ? dst->data.ptr : 0; 1117 int* idxptr = idx ? idx->data.i : 0; 1118 1119 len = src->rows; 1120 tsrc = (uchar*)cvAlloc(len*elemSize); 1121 if( idx ) 1122 { 1123 tidx = (int*)cvAlloc(len*sizeof(tidx[0])); 1124 for( i = 0; i < len; i++ ) 1125 tidx[i] = i; 1126 } 1127 1128 if( flags & CV_SORT_DESCENDING ) 1129 { 1130 dptr += dstep*(src->rows - 1); 1131 dstep = -dstep; 1132 idxptr += istep*(src->rows - 1); 1133 istep = -istep; 1134 } 1135 1136 sstep /= elemSize; 1137 dstep /= elemSize; 1138 1139 for( i = 0; i < src->cols; i++ ) 1140 { 1141 icvCopy1D( src->data.ptr + i*elemSize, sstep, tsrc, 1, len, elemSize ); 1142 if( tidx ) 1143 { 1144 sortIdxFunc( tidx, len, tsrc ); 1145 if( dst ) 1146 icvShuffle1D( tsrc, tidx, dptr + i*elemSize, dstep, len, elemSize ); 1147 icvCopy1D( tidx, 1, idxptr + i, istep, len, sizeof(int) ); 1148 } 1149 else 1150 { 1151 sortFunc( tsrc, len, 0 ); 1152 icvCopy1D( tsrc, 1, dptr + i*elemSize, dstep, len, elemSize ); 1153 } 1154 } 1155 } 1156 else 1157 { 1158 int j, t, count = src->rows; 1159 if( flags & CV_SORT_EVERY_COLUMN ) 1160 CV_SWAP( len, count, t ); 1161 1162 if( (flags & CV_SORT_DESCENDING) || (idx && dst && dst->data.ptr == src->data.ptr) ) 1163 tsrc = (uchar*)cvAlloc(len*elemSize); 1164 1165 for( i = 0; i < count; i++ ) 1166 { 1167 if( !idx ) 1168 { 1169 const uchar* sptr = src->data.ptr + i*sstep; 1170 uchar* dptr = dst->data.ptr + i*dstep; 1171 uchar* ptr = flags & CV_SORT_DESCENDING ? tsrc : dptr; 1172 if( ptr != sptr ) 1173 icvCopy1D( sptr, 1, ptr, 1, len, elemSize ); 1174 sortFunc( ptr, len, 0 ); 1175 if( flags & CV_SORT_DESCENDING ) 1176 icvCopy1D( ptr + (len-1)*elemSize, -1, dptr, 1, len, elemSize ); 1177 } 1178 else 1179 { 1180 int* idx_ = idx->data.i + istep*i; 1181 const uchar* sptr = src->data.ptr + sstep*i; 1182 uchar* dptr = dst ? dst->data.ptr + dstep*i : 0; 1183 for( j = 0; j < len; j++ ) 1184 idx_[j] = j; 1185 if( dptr && dptr == sptr ) 1186 { 1187 icvCopy1D( sptr, 1, tsrc, 1, len, elemSize ); 1188 sptr = tsrc; 1189 } 1190 sortIdxFunc( idx_, len, sptr ); 1191 if( flags & CV_SORT_DESCENDING ) 1192 for( j = 0; j < len/2; j++ ) 1193 CV_SWAP(idx_[j], idx_[len-j-1], t); 1194 if( dptr ) 1195 icvShuffle1D( sptr, idx_, dptr, 1, len, elemSize ); 1196 } 1197 } 1198 } 1199 1200 __END__; 1201 1202 cvFree( &tsrc ); 1203 cvFree( &tidx ); 1204 } 1205 1206 /* End of file. */ 1207