1 /* 2 Copyright (c) 2019 Ferhat Kurtulmuş 3 Boost Software License - Version 1.0 - August 17th, 2003 4 Permission is hereby granted, free of charge, to any person or organization 5 obtaining a copy of the software and accompanying documentation covered by 6 this license (the "Software") to use, reproduce, display, distribute, 7 execute, and transmit the Software, and to prepare derivative works of the 8 Software, and to permit third-parties to whom the Software is furnished to 9 do so, all subject to the following: 10 The copyright notices in the Software and this entire statement, including 11 the above license grant, this restriction and the following disclaimer, 12 must be included in all copies of the Software, in whole or in part, and 13 all derivative works of the Software, unless such copies or derivative 14 works are solely in the form of machine-executable object code generated by 15 a source language processor. 16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 19 SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 20 FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 21 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 DEALINGS IN THE SOFTWARE. 23 */ 24 25 module opencvd.cvcore; 26 27 import core.stdc.stdint; 28 import core.stdc.stdlib; 29 30 import std.conv; 31 32 struct Size { 33 int width; 34 int height; 35 36 alias rows = height; 37 alias cols = width; 38 } 39 40 struct ByteArray { 41 ubyte* data; 42 int length; 43 } 44 45 struct CStrings { 46 const char** strs; 47 int length; 48 } 49 50 struct Scalar { 51 double val1; 52 double val2; 53 double val3; 54 double val4; 55 56 static Scalar all(double val){ 57 return Scalar(val,val,val,val); 58 } 59 60 double opIndex(int i){ 61 double[4] tmp = [val1, val2, val3, val4]; 62 return tmp[i]; 63 } 64 65 void opIndexAssign(double val, int i){ 66 double*[4] tmp = [&val1, &val2, &val3, &val4]; 67 *tmp[i] = val; 68 } 69 70 bool opEquals(Scalar b){ 71 if (this is b) return true; 72 if ((this.val1 == b.val1)&& 73 (this.val1 == b.val1)&& 74 (this.val1 == b.val1)&& 75 (this.val1 == b.val1)) 76 return true; 77 return false; 78 } 79 } 80 81 alias Color = Scalar; 82 83 struct Vec4f { 84 float val1; 85 float val2; 86 float val3; 87 float val4; 88 89 static Vec4f all(float val){ 90 return Vec4f(val,val,val,val); 91 } 92 93 float opIndex(int i){ 94 float[4] tmp = [val1, val2, val3, val4]; 95 return tmp[i]; 96 } 97 98 void opIndexAssign(float val, int i){ 99 float*[4] tmp = [&val1, &val2, &val3, &val4]; 100 *tmp[i] = val; 101 } 102 } 103 104 struct Vec4fs { 105 Vec4f* vec4fs; 106 int length; 107 // alias vec4fs this;// todo for all 108 Vec4f opIndex(int i){ 109 return vec4fs[i]; 110 } 111 } 112 113 struct Vec3f { 114 float val1; 115 float val2; 116 float val3; 117 118 static Vec3f all(float val){ 119 return Vec3f(val,val,val); 120 } 121 122 float opIndex(int i){ 123 float[3] tmp = [val1, val2, val3]; 124 return tmp[i]; 125 } 126 127 void opIndexAssign(float val, int i){ 128 float*[3] tmp = [&val1, &val2, &val3]; 129 *tmp[i] = val; 130 } 131 } 132 133 struct Vec3fs{ 134 Vec3f* vec3fs; 135 int length; 136 137 Vec3f opIndex(int i){ 138 return vec3fs[i]; 139 } 140 } 141 142 struct Vec4i { 143 int val1; 144 int val2; 145 int val3; 146 int val4; 147 148 static Vec4i all(int val){ 149 return Vec4i(val,val,val,val); 150 } 151 152 int opIndex(int i){ 153 int[4] tmp = [val1, val2, val3, val4]; 154 return tmp[i]; 155 } 156 157 void opIndexAssign(int val, int i){ 158 int*[4] tmp = [&val1, &val2, &val3, &val4]; 159 *tmp[i] = val; 160 } 161 } 162 163 struct Vec4is{ 164 Vec4i* vec4is; 165 int length; 166 167 Vec4i opIndex(int i){ 168 return vec4is[i]; 169 } 170 } 171 172 struct Vec3i { 173 int val1; 174 int val2; 175 int val3; 176 177 static Vec3i all(int val){ 178 return Vec3i(val,val,val); 179 } 180 181 int opIndex(int i){ 182 int[3] tmp = [val1, val2, val3]; 183 return tmp[i]; 184 } 185 186 void opIndexAssign(int val, int i){ 187 int*[3] tmp = [&val1, &val2, &val3]; 188 *tmp[i] = val; 189 } 190 } 191 192 struct Vec3is { 193 Vec3i* vec3is; 194 int length; 195 196 Vec3i opIndex(int i){ 197 return vec3is[i]; 198 } 199 } 200 201 struct Vec2f { 202 float val1; 203 float val2; 204 205 static Vec2f all(float val){ 206 return Vec2f(val,val); 207 } 208 209 float opIndex(int i){ 210 float[2] tmp = [val1, val2]; 211 return tmp[i]; 212 } 213 214 void opIndexAssign(float val, int i){ 215 float*[2] tmp = [&val1, &val2]; 216 *tmp[i] = val; 217 } 218 219 } 220 221 struct Vec2fs { 222 Vec2f* vec2fs; 223 int length; 224 225 Vec2f opIndex(int i){ 226 return vec2fs[i]; 227 } 228 } 229 230 struct Vec6f { 231 float val1; 232 float val2; 233 float val3; 234 float val4; 235 float val5; 236 float val6; 237 238 static Vec6f all(float val){ 239 return Vec6f(val,val,val,val,val,val); 240 } 241 242 float opIndex(int i){ 243 float[6] tmp = [val1, val2, val3, val4, val5, val6]; 244 return tmp[i]; 245 } 246 247 void opIndexAssign(float val, int i){ 248 float*[6] tmp = [&val1, &val2, &val3, &val4, &val5, &val6]; 249 *tmp[i] = val; 250 } 251 } 252 253 struct Vec6fs { 254 Vec6f* vec6fs; 255 int length; 256 257 Vec6f opIndex(int i){ 258 return vec6fs[i]; 259 } 260 } 261 262 struct Hierarchy { 263 Scalar* scalars; 264 int length; 265 266 Scalar opIndex(int i){ 267 return scalars[i]; 268 } 269 } 270 271 alias Colors = Hierarchy; 272 273 struct IntVector { 274 int* val; 275 int length; 276 277 int opIndex(int i){ 278 return val[i]; 279 } 280 } 281 282 struct FloatVector { 283 float* val; 284 int length; 285 286 float opIndex(int i){ 287 return val[i]; 288 } 289 } 290 291 struct DoubleVector { 292 double* val; 293 int length; 294 295 double opIndex(int i){ 296 return val[i]; 297 } 298 } 299 300 struct CharVector { 301 char* val; 302 int length; 303 304 char opIndex(int i){ 305 return val[i]; 306 } 307 } 308 309 struct Rect { 310 int x; 311 int y; 312 int width; 313 int height; 314 } 315 316 bool contains(Rect r, Point p){ 317 return Rect_Contains(r, p); 318 } 319 320 struct Rects { 321 Rect* rects; 322 int length; 323 324 Rect opIndex(int i){ 325 return rects[i]; 326 } 327 } 328 329 struct RotatedRect { 330 Contour pts; 331 Rect boundingRect; 332 Point center; 333 Size size; 334 double angle; 335 336 Point[] points(){ 337 return pts.points[0..pts.length]; 338 } 339 340 static RotatedRect opCall(Point center, Size size, double angle){ 341 RotatedRect rr = New_RotatedRect(center, size, angle); 342 Point[] ps = rr.pts.points[0..rr.pts.length].dup; 343 Points_Close(rr.pts); 344 RotatedRect ret = {Contour(ps.ptr, cast(int)ps.length), rr.boundingRect, rr.center, rr.size, rr.angle}; 345 return ret; 346 } 347 } 348 349 struct RotatedRects { 350 RotatedRect* rects; 351 int length; 352 } 353 354 struct Point { 355 int x; 356 int y; 357 358 int opCmp(Point rhs) { 359 if (x < rhs.x) return -1; 360 if (rhs.x < x) return 1; 361 return 0; 362 } 363 364 void toString(scope void delegate(const(char)[]) sink) const { 365 import std.format; 366 sink("("); 367 formattedWrite(sink, "%d", x); 368 sink(","); 369 formattedWrite(sink, "%d", y); 370 sink(")"); 371 } 372 373 Point2f asFloat(){ 374 return Point2f(x.to!float, y.to!float); 375 } 376 377 Point opBinary(string op)(double a){ 378 static if (op == "+"){ 379 return Point((x+a).to!int,(y+a).to!int); 380 } 381 else static if (op == "-"){ 382 return Point((x-a).to!int,(y-a).to!int); 383 } 384 else static if (op == "*"){ 385 return Point((x*a).to!int,(y*a).to!int); 386 } 387 } 388 389 Point opBinary(string op)(Point a){ 390 static if (op == "+"){ 391 return Point((x+a.x).to!int,(y+a.y).to!int); 392 } 393 else static if (op == "-"){ 394 return Point((x-a.x).to!int,(y-a.y).to!int); 395 } 396 } 397 } 398 399 struct Point2f { 400 float x; 401 float y; 402 403 Point asInt(){ 404 return Point(x.to!int, y.to!int); 405 } 406 407 Point2f opBinary(string op)(double a){ 408 static if (op == "+"){ 409 return Point2f((x+a).to!float,(y+a).to!float); 410 } 411 else static if (op == "-"){ 412 return Point2f((x-a).to!float,(y-a).to!float); 413 }else static if (op == "*"){ 414 return Point2f(float(x*a),float(y*a)); 415 } 416 } 417 418 Point2f opBinary(string op)(Point2f a){ 419 static if (op == "+"){ 420 return Point2f((x+a.x).to!float,(y+a.y).to!float); 421 } 422 else static if (op == "-"){ 423 return Point2f((x-a.x).to!float,(y-a.y).to!float); 424 } 425 } 426 } 427 428 struct Point2fs { 429 Point2f* points; 430 int length; 431 432 Point2f opIndex(int i){ 433 return points[i]; 434 } 435 } 436 437 struct Point2fss { 438 Point2fs* point2fss; 439 int length; 440 441 Point2fs opIndex(int i){ 442 return point2fss[i]; 443 } 444 } 445 446 struct Points { 447 Point* points; 448 int length; 449 450 Point opIndex(int i){ 451 return points[i]; 452 } 453 } 454 455 struct Pointss { 456 Points* pointss; 457 int length; 458 459 Points opIndex(int i){ 460 return pointss[i]; 461 } 462 } 463 464 alias Contour = Points; 465 466 Point[] asInt(Point2f[] ip){ 467 468 Point[] ret; ret.length = ip.length; 469 foreach(j; 0..ip.length){ 470 Point p = Point(ip[j].x.to!int, ip[j].y.to!int); 471 ret[j] = p; 472 } 473 return ret; 474 } 475 476 Point[][] asInt(Point2f[][] pts){ 477 478 Point[][] ret; ret.length = pts.length; 479 foreach(i; 0..pts.length){ 480 Point2f[] ip = pts[i]; 481 Point[] iip; iip.length = ip.length; 482 foreach(j; 0..ip.length){ 483 Point p = Point(ip[j].x.to!int, ip[j].y.to!int); 484 iip[j] = p; 485 } 486 ret[i] = iip; 487 } 488 return ret; 489 } 490 491 Point2f[] asFloat(Point[] ip){ 492 493 Point2f[] ret; ret.length = ip.length; 494 foreach(j; 0..ip.length){ 495 Point2f p = Point2f(ip[j].x.to!float, ip[j].y.to!float); 496 ret[j] = p; 497 } 498 return ret; 499 } 500 501 Point2f[][] asFloat(Point[][] pts){ 502 503 Point2f[][] ret; ret.length = pts.length; 504 foreach(i; 0..pts.length){ 505 Point2f[] iip; 506 Point[] ip = pts[i]; 507 iip.length = ip.length; 508 foreach(j; 0..ip.length){ 509 Point2f p = Point2f(ip[j].x.to!float, ip[j].y.to!float); 510 iip[j] = p; 511 } 512 ret[i] = iip; 513 } 514 return ret; 515 } 516 517 struct Point2d { 518 double x; 519 double y; 520 521 Point asInt(){ 522 return Point(x.to!int, y.to!int); 523 } 524 525 Point2f asFloat(){ 526 return Point2f(x.to!float, y.to!float); 527 } 528 529 Point2d opBinary(string op)(double a){ 530 static if(op == "*") 531 return Point2d(double(x*a),double(y*a)); 532 else static assert(0, "Operator "~op~" not implemented"); 533 } 534 } 535 536 struct Contours { 537 Contour* contours; 538 int length; 539 540 Contour opIndex(int i){ 541 return contours[i]; 542 } 543 } 544 545 struct KeyPoint { 546 double x; 547 double y; 548 double size; 549 double angle; 550 double response; 551 int octave; 552 int classID; 553 554 Point2f pt(){ 555 return Point2f(x.to!float, y.to!float); 556 } 557 } 558 559 struct KeyPoints { 560 KeyPoint* keypoints; 561 int length; 562 563 KeyPoint opIndex(int i){ 564 return keypoints[i]; 565 } 566 } 567 568 struct DMatch { 569 int queryIdx; 570 int trainIdx; 571 int imgIdx; 572 float distance; 573 } 574 575 struct DMatches { 576 DMatch* dmatches; 577 int length; 578 579 DMatch opIndex(int i){ 580 return dmatches[i]; 581 } 582 } 583 584 struct MultiDMatches { 585 DMatches* dmatches; 586 int length; 587 588 DMatches opIndex(int i){ 589 return dmatches[i]; 590 } 591 } 592 593 struct Moment { 594 double m00; 595 double m10; 596 double m01; 597 double m20; 598 double m11; 599 double m02; 600 double m30; 601 double m21; 602 double m12; 603 double m03; 604 605 double mu20; 606 double mu11; 607 double mu02; 608 double mu30; 609 double mu21; 610 double mu12; 611 double mu03; 612 613 double nu20; 614 double nu11; 615 double nu02; 616 double nu30; 617 double nu21; 618 double nu12; 619 double nu03; 620 } 621 622 struct Mat { 623 void* p; 624 625 int rows() {return Mat_Rows(this);} 626 int cols() {return Mat_Cols(this);} 627 int type() {return Mat_Type(this);} 628 int channels(){return Mat_Channels(this);} 629 int step() {return Mat_Step(this);} 630 int dims() {return Mat_Dims(this);} 631 int height() {return rows();} 632 int width() {return cols();} 633 Size size() {return Size(width(), height());} 634 int size(int i){return Mat_SizeFromInd(this, i);} 635 int total() {return Mat_Total(this);} 636 int flatLength() {return Mat_FlatLength(this);} 637 void* rawDataPtr() {return Mat_DataPtrNoCast(this);} 638 ubyte* ptr(int i = 0) { return Mat_RowPtr(this, i);} 639 ubyte* ptr(int row, int col) { return Mat_RowPtr2(this, row, col);} 640 void* ptr(int i0, int i1, int i2) { return Mat_RowPtr3(this, i0, i1, i2);} 641 642 Scalar mean() {return Mat_Mean(this);} 643 Mat sqrt() {return Mat_Sqrt(this);} 644 645 bool isContinuous(){ 646 return Mat_IsContinuous(this); 647 } 648 649 bool isSubmatrix(){ 650 return Mat_IsSubmatrix(this); 651 } 652 653 void locateROI(Size* wholeSize, Point* ofs){ 654 Mat_LocateROI(this, wholeSize, ofs); 655 } 656 657 Mat opCall(Rect r){ 658 return matFromRect(this, r); 659 } 660 661 static Mat opCall(){ 662 return newMat(); 663 } 664 665 static Mat opCall(int rows, int cols, int mt ){ 666 return Mat_NewWithSize(rows, cols, mt); 667 } 668 669 static Mat opCall(Size sz, int mt ){ 670 return Mat_NewWithSize(sz.height, sz.width, mt); 671 } 672 673 static Mat opCall( const Scalar ar, int type){ 674 return Mat_NewFromScalar(ar, type); 675 } 676 677 static Mat opCall(const Scalar ar, int rows, int cols, int type){ 678 return Mat_NewWithSizeFromScalar(ar, rows, cols, type); 679 } 680 681 static Mat opCall(int rows, int cols, int type, ByteArray buf){ 682 return Mat_NewFromBytes(rows, cols, type, buf); 683 } 684 685 static Mat opCall(Mat m, int rows, int cols, int type, int prows, int pcols){ 686 return Mat_FromPtr(m, rows, cols, type, prows, pcols); 687 } 688 689 static Mat opCall(int rows, int cols, int type, void* data){ 690 return Mat_FromArrayPtr(rows, cols, type, data); 691 } 692 693 static Mat opCall(Point[] points){ 694 return newMatFromContour(points); 695 } 696 697 static Mat opCall(int[] data){ 698 return Mat_FromIntVector(IntVector(data.ptr, data.length.to!int)); 699 } 700 701 static Mat opCall(float[] data){ 702 return Mat_FromFloatVector(FloatVector(data.ptr, data.length.to!int)); 703 } 704 705 Mat opCall(Range rowRange, Range colRange = Range.all()){ 706 return Mat_FromRanges(this, rowRange, colRange); 707 } 708 709 int opDollar(int dimension)() { 710 static if (dimension == 0) { 711 return this.rows; 712 713 } else static if (dimension == 1){ 714 return this.cols; 715 } 716 } 717 718 Range opSlice(size_t dimension)(int start, int end){ 719 return Range(start, end); 720 } 721 722 /* syntactic sugar for Mat slicing 723 * Based on: http://ddili.org/ders/d.en/templates_more.html 724 * Mat m = img[0..$-50, 50 .. 200]; 725 */ 726 Mat opIndex(A...)(A arguments){ 727 Range rowRange = Range(0, this.rows); 728 Range colRange = Range(0, this.cols); 729 730 Range[2] ranges = [rowRange, colRange]; 731 732 foreach (dimension, a; arguments) { 733 static if (is (typeof(a) == Range)) { 734 ranges[dimension] = a; 735 } else 736 static if (is (typeof(a) : int) || is (typeof(a) : size_t)) { 737 ranges[dimension] = Range(a, a + 1); 738 } 739 else { 740 static assert( false, "Invalid index type!"); 741 } 742 } 743 744 return Mat_FromRanges(this, ranges[0], ranges[1]); 745 } 746 747 Mat opIndexAssign(A...)(Scalar value, A arguments){ 748 Mat subMatrix = opIndex(arguments); 749 subMatrix = value; 750 return subMatrix; 751 } 752 753 Mat opCall(Range[] ranges){ 754 return Mat_FromMultiRanges(this, RangeVector(ranges.ptr, ranges.length.to!int)); 755 } 756 757 Mat row(int y){ 758 return Mat_HeaderFromRow(this, y); 759 } 760 761 Mat col(int x){ 762 return Mat_HeaderFromCol(this, x); 763 } 764 765 void opAssign(Color c){ 766 this.setTo(c); 767 } 768 769 Mat opBinary(string op, V)(V a){ 770 static if (op == "*"){ 771 static if (is(V == ubyte)){ 772 multiplyUChar(this, a); 773 } else 774 static if (is(V == int)){ 775 Mat_MultiplyInt(this, a); 776 } else 777 static if (is(V == float)){ 778 Mat_MultiplyFloat(this, a); 779 } else 780 static if (is(V == double)){ 781 Mat_MultiplyDouble(this, a); 782 } 783 static if (is(V == Mat)){ 784 Mat_Multiply(this, a, this); 785 } 786 return this; 787 } else 788 static if (op == "/"){ 789 static if (is(V == float)){ 790 Mat_MultiplyFloat(this, 1.0f/a); 791 } else 792 static if (is(V == int)){ 793 Mat_DivideInt(this, a); 794 } else 795 static if (is(V == double)){ 796 Mat_MultiplyDouble(this, 1.0/a); 797 } 798 return this; 799 } else 800 static if (op == "+"){ 801 static if (is(V == int)){ 802 Mat_AddInt(this, a); 803 } else 804 static if (is(V == float)){ 805 Mat_AddFloat(this, a); 806 }else 807 static if (is(V == Mat)){ 808 add(this, a, this); 809 } else 810 static if (is(V == Scalar)){ 811 Mat_AddScalar(this, a); 812 } 813 return this; 814 } else 815 static if (op == "-"){ 816 static if (is(V == int)){ 817 Mat_SubtractInt(this, a); 818 } else 819 static if (is(V == float)){ 820 Mat_SubtractFloat(this, a); 821 } else 822 static if (is(V == Mat)){ 823 matSubtract(this, a, this); 824 } else 825 static if (is(V == Scalar)){ 826 Mat_AddScalar(this, Scalar(-a.val1, -a.val2, -a.val3, -a.val4)); 827 } 828 return this; 829 } else 830 static assert(0, "Operator "~op~" not implemented for type " ~ V.stringof); 831 } 832 833 // so sad that the D does not support struct > 5 834 Mat EQInt(int a){ 835 return Mat_EQInt(this, a); 836 } 837 838 Mat GTInt(int a){ 839 return Mat_GTInt(this, a); 840 } 841 842 Mat GEInt(int a){ 843 return Mat_GEInt(this, a); 844 } 845 846 Mat LTInt(int a){ 847 return Mat_LTInt(this, a); 848 } 849 850 Mat LEInt(int a){ 851 return Mat_LEInt(this, a); 852 } 853 Mat NEInt(int a){ 854 return Mat_NEInt(this, a); 855 } 856 857 Mat EQDouble(double a){ 858 return Mat_EQDouble(this, a); 859 } 860 861 Mat GTDouble(double a){ 862 return Mat_GTDouble(this, a); 863 } 864 865 Mat GEDouble(double a){ 866 return Mat_GEDouble(this, a); 867 } 868 869 Mat LTDouble(double a){ 870 return Mat_LTDouble(this, a); 871 } 872 873 Mat LEDouble(double a){ 874 return Mat_LEDouble(this, a); 875 } 876 877 Mat NEDouble(double a){ 878 return Mat_NEDouble(this, a); 879 } 880 881 string type2str(){ 882 import std.conv; 883 import core.stdc.stdlib; 884 885 auto chr = _type2str(type()); 886 string stype = chr.to!string.dup; 887 free(chr); 888 return stype; 889 } 890 891 ByteArray byteArray(){ // no reason to use this now. will be removed soon. 892 return Mat_DataPtr(this); 893 } 894 895 // retuns d array. use it like: double[] myarray = mat.array!double; 896 T[] array(T)(){ 897 T* ret = cast(T*)rawDataPtr(); 898 return ret[0..flatLength()]; 899 } 900 901 Scalar opIndex(int row, int col){ 902 return at(row, col); 903 } 904 905 /* Setters */ 906 void opIndexAssign(Scalar color, int row, int col){ 907 setColorAt(color, row, col); 908 } 909 910 void opIndexAssign(T)(T val, int row, int col){ 911 assert(this.channels == 1, "This is only allowed for single-channel Mat types!"); 912 this.set!T(row, col, cast(T)val); 913 } 914 915 void setColorAt(Scalar color, int row, int col){ 916 assert(this.channels > 1, "Color assignment is only allowed for multi-channel Mat types!"); 917 Mat_SetColorAt(this, color, row, col); 918 } 919 920 void set(T)(int row, int col, T val){ 921 static if (is(T == float)){ 922 setFloatAt(row, col, val); 923 } else static if (is(T == double)){ 924 setDoubleAt(row, col, val); 925 } else static if (is(T == int)){ 926 setIntAt(row, col, val); 927 } else static if (is(T == ubyte)){ 928 setUCharAt(row, col, val); 929 } else static if (is(T == byte)){ 930 setSCharAt(row, col, val); 931 } else static if (is(T == short)){ 932 setShortAt(row, col, val); 933 } 934 } 935 936 void setUCharAt(int row, int col, ubyte val){ 937 Mat_SetUChar(this, row, col, val); 938 } 939 940 void setUChar3At( int x, int y, int z, ubyte val){ 941 Mat_SetUChar3(this, x, y, z, val); 942 } 943 944 void setSCharAt(int row, int col, byte val){ 945 Mat_SetSChar(this, row, col, val); 946 } 947 948 void setSChar3At(int x, int y, int z, byte val){ 949 Mat_SetSChar3(this, x, y, z, val); 950 } 951 952 void setShortAt(int row, int col, short val){ 953 Mat_SetShort(this, row, col, val); 954 } 955 956 void setShort3At(int x, int y, int z, short val){ 957 Mat_SetShort3(this, x, y, z, val); 958 } 959 960 void setIntAt(int row, int col, int val){ 961 Mat_SetInt(this, row, col, val); 962 } 963 964 void setInt3At(int x, int y, int z, int val){ 965 Mat_SetInt3(this, x, y, z, val); 966 } 967 968 void setFloatAt(int row, int col, float val){ 969 Mat_SetFloat(this, row, col, val); 970 } 971 972 void setFloat3At(int x, int y, int z, float val){ 973 Mat_SetFloat3(this, x, y, z, val); 974 } 975 976 void setDoubleAt(int row, int col, double val){ 977 Mat_SetDouble(this, row, col, val); 978 } 979 980 void setDouble3At(int x, int y, int z, double val){ 981 Mat_SetDouble3(this, x, y, z, val); 982 } 983 984 /* Getters */ 985 986 T at(T)(int row, int col){ 987 static if (is(T == float)){ 988 return getFloatAt(row, col); 989 } else static if (is(T == double)){ 990 return getDoubleAt(row, col); 991 } else static if (is(T == int)){ 992 return getIntAt(row, col); 993 } else static if (is(T == ubyte)){ 994 return getUCharAt(row, col); 995 } else static if (is(T == byte)){ 996 return getSCharAt(row, col); 997 } else static if (is(T == short)){ 998 return getShortAt(row, col); 999 } 1000 } 1001 1002 T at(T)(int flatInd){ 1003 T* ret = cast(T*)rawDataPtr(); 1004 return ret[flatInd]; 1005 } 1006 1007 Color at(int row, int col){ 1008 return Mat_ColorAt(this, row, col); 1009 } 1010 1011 ubyte getUCharAt(int row, int col){ 1012 return Mat_GetUChar(this, row, col); 1013 } 1014 1015 ubyte getUChar3At(int x, int y, int z){ 1016 return Mat_GetUChar3(this, x, y, z); 1017 } 1018 1019 byte getSCharAt(int row, int col){ 1020 return Mat_GetSChar(this, row, col); 1021 } 1022 1023 byte getSChar3At(int x, int y, int z){ 1024 return Mat_GetSChar3(this, x, y, z); 1025 } 1026 1027 short getShortAt(int row, int col){ 1028 return Mat_GetShort(this, row, col); 1029 } 1030 1031 short getShort3At(int x, int y, int z){ 1032 return Mat_GetShort3(this, x, y, z); 1033 } 1034 1035 int getIntAt(int row, int col){ 1036 return Mat_GetInt(this, row, col); 1037 } 1038 1039 int getInt3At(int x, int y, int z){ 1040 return Mat_GetInt3(this, x, y, z); 1041 } 1042 1043 float getFloatAt(int row, int col){ 1044 return Mat_GetFloat(this, row, col); 1045 } 1046 1047 float getFloat3At(int x, int y, int z){ 1048 return Mat_GetFloat3(this, x, y, z); 1049 } 1050 1051 double getDoubleAt(int row, int col){ 1052 return Mat_GetDouble(this, row, col); 1053 } 1054 1055 double getDouble3At(int x, int y, int z){ 1056 return Mat_GetDouble3(this, x, y, z); 1057 } 1058 1059 Mat rowRange(int startrow, int endrow){ 1060 return Mat_RowRange1(this, startrow, endrow); 1061 } 1062 1063 } 1064 1065 struct Mats { 1066 Mat* mats; 1067 int length; 1068 1069 Mat opIndex(int i){ 1070 return mats[i]; 1071 } 1072 } 1073 1074 enum: int { 1075 // MatChannels1 is a single channel Mat. 1076 MatChannels1 = 0, 1077 1078 // MatChannels2 is 2 channel Mat. 1079 MatChannels2 = 8, 1080 1081 // MatChannels3 is 3 channel Mat. 1082 MatChannels3 = 16, 1083 1084 // MatChannels4 is 4 channel Mat. 1085 MatChannels4 = 24 1086 } 1087 1088 enum: int { 1089 // CV8U is a Mat of 8-bit unsigned int 1090 CV8U = 0, 1091 1092 // CV8S is a Mat of 8-bit signed int 1093 CV8S = 1, 1094 1095 // CV16U is a Mat of 16-bit unsigned int 1096 CV16U = 2, 1097 1098 // CV16S is a Mat of 16-bit signed int 1099 CV16S = 3, 1100 1101 // CV16SC2 is a Mat of 16-bit signed int with 2 channels 1102 CV16SC2 = CV16S + MatChannels2, 1103 1104 // CV32S is a Mat of 32-bit signed int 1105 CV32S = 4, 1106 1107 // CV32F is a Mat of 32-bit float 1108 CV32F = 5, 1109 1110 // CV64F is a Mat of 64-bit float 1111 CV64F = 6, 1112 1113 // CV8UC1 is a Mat of 8-bit unsigned int with a single channel 1114 CV8UC1 = CV8U + MatChannels1, 1115 1116 // CV8UC2 is a Mat of 8-bit unsigned int with 2 channels 1117 CV8UC2 = CV8U + MatChannels2, 1118 1119 // MatTypeCV8UC3 is a Mat of 8-bit unsigned int with 3 channels 1120 CV8UC3 = CV8U + MatChannels3, 1121 1122 // MatTypeCV8UC4 is a Mat of 8-bit unsigned int with 4 channels 1123 CV8UC4 = CV8U + MatChannels4 1124 } 1125 1126 alias CV_8U = CV8U; 1127 alias CV_8S = CV8S; 1128 alias CV_16U = CV16U; 1129 alias CV_16S = CV16S; 1130 alias CV_16SC2 = CV16SC2; 1131 alias CV_32S = CV32S; 1132 alias CV_32F = CV32F; 1133 alias CV_64F = CV64F; 1134 alias CV_8UC1 = CV8UC1; 1135 alias CV_8UC2 = CV8UC2; 1136 alias CV_8UC3 = CV8UC3; 1137 alias CV_8UC4 = CV8UC4; 1138 1139 alias MatType = int; 1140 1141 extern (C) { 1142 void Close_Vec6fs(Vec6fs vec6fs); 1143 void Close_Vec4fs(Vec4fs vec4fs); 1144 void Close_Vec3fs(Vec3fs vec3fs); 1145 void Close_Vec2fs(Vec2fs vec2fs); 1146 void Close_Vec4is(Vec4is vec4is); 1147 void Close_Vec3is(Vec3is vec3is); 1148 void Close_IntVector(IntVector iv); 1149 void Close_DoubleVector(DoubleVector iv); 1150 void Close_FloatVector(FloatVector iv); 1151 1152 void Contours_Close(Contours cs); 1153 void KeyPoints_Close(KeyPoints ks); 1154 void Rects_Close(Rects rs); 1155 void Mats_Close(Mats mats); 1156 void Point_Close(Point p); 1157 void Points_Close(Points ps); 1158 void DMatches_Close(DMatches ds); 1159 void MultiDMatches_Close(MultiDMatches mds); 1160 } 1161 1162 private extern (C) { 1163 1164 Mat Mat_New(); 1165 Mat Mat_NewWithSize(int rows, int cols, int type); 1166 Mat Mat_NewFromScalar(const Scalar ar, int type); 1167 Mat Mat_NewWithSizeFromScalar(const Scalar ar, int rows, int cols, int type); 1168 Mat Mat_NewFromBytes(int rows, int cols, int type, ByteArray buf); 1169 Mat Mat_FromPtr(Mat m, int rows, int cols, int type, int prows, int pcols); 1170 Mat Mat_FromArrayPtr(int rows, int cols, int type, void* data); 1171 Mat Mat_FromFloatVector(FloatVector vec); 1172 Mat Mat_FromIntVector(IntVector vec); 1173 Mat Mat_HeaderFromRow(Mat src, int y); 1174 Mat Mat_HeaderFromCol(Mat src, int x); 1175 Mat Mat_RowRange1(Mat src, int startrow, int endrow); 1176 Mat Mat_FromRanges(Mat src, Range rowRange, Range colRange); 1177 Mat Mat_FromMultiRanges(Mat src, RangeVector rngs); 1178 Mat Mat_FromContour(Contour points); 1179 ubyte* Mat_RowPtr(Mat m, int i); 1180 ubyte* Mat_RowPtr2(Mat m, int row, int col); 1181 void* Mat_RowPtr3(Mat m, int i0, int i1, int i2); 1182 int Mat_CV_MAKETYPE(int depth, int cn); 1183 1184 int Mat_Rows(Mat m); 1185 int Mat_Cols(Mat m); 1186 int Mat_Type(Mat m); 1187 int Mat_Channels(Mat m); 1188 int Mat_Step(Mat m); 1189 int Mat_Dims(Mat m); 1190 int Mat_SizeFromInd(Mat m, int i); 1191 bool Mat_IsContinuous(Mat src); 1192 bool Mat_IsSubmatrix(Mat src); 1193 void Mat_LocateROI(Mat src, Size* wholeSize, Point* ofs); 1194 1195 char* _type2str(int type); 1196 1197 ByteArray Mat_DataPtr(Mat m); 1198 int Mat_FlatLength(Mat src); 1199 void* Mat_DataPtrNoCast(Mat src); 1200 Scalar Mat_ColorAt(Mat src, int row, int col); 1201 1202 Mat Mat_Reshape(Mat m, int cn, int rows); 1203 1204 void Mat_Close(Mat m); 1205 int Mat_Empty(Mat m); 1206 Mat Mat_Clone(Mat m); 1207 void Mat_CopyTo(Mat m, Mat dst); 1208 void Mat_CopyToWithMask(Mat m, Mat dst, Mat mask); 1209 void Mat_ConvertTo(Mat m, Mat dst, int type); 1210 void Mat_convertTo2(Mat m, Mat dst, int rtype, double alpha, double beta); 1211 1212 int Mat_Total(Mat m); 1213 Scalar Mat_Mean(Mat m); 1214 Mat Mat_Sqrt(Mat m); 1215 1216 void Mat_SetColorAt(Mat src, Scalar color, int row, int col); 1217 void Mat_SetTo(Mat m, Scalar value); 1218 void Mat_SetToWithMask(Mat m, Scalar value, Mat mask); 1219 void Mat_SetUChar(Mat m, int row, int col, uint8_t val); 1220 void Mat_SetUChar3(Mat m, int x, int y, int z, uint8_t val); 1221 void Mat_SetSChar(Mat m, int row, int col, int8_t val); 1222 void Mat_SetSChar3(Mat m, int x, int y, int z, int8_t val); 1223 void Mat_SetShort(Mat m, int row, int col, int16_t val); 1224 void Mat_SetShort3(Mat m, int x, int y, int z, int16_t val); 1225 void Mat_SetInt(Mat m, int row, int col, int32_t val); 1226 void Mat_SetInt3(Mat m, int x, int y, int z, int32_t val); 1227 void Mat_SetFloat(Mat m, int row, int col, float val); 1228 void Mat_SetFloat3(Mat m, int x, int y, int z, float val); 1229 void Mat_SetDouble(Mat m, int row, int col, double val); 1230 void Mat_SetDouble3(Mat m, int x, int y, int z, double val); 1231 1232 uint8_t Mat_GetUChar(Mat m, int row, int col); 1233 uint8_t Mat_GetUChar3(Mat m, int x, int y, int z); 1234 int8_t Mat_GetSChar(Mat m, int row, int col); 1235 int8_t Mat_GetSChar3(Mat m, int x, int y, int z); 1236 int16_t Mat_GetShort(Mat m, int row, int col); 1237 int16_t Mat_GetShort3(Mat m, int x, int y, int z); 1238 int32_t Mat_GetInt(Mat m, int row, int col); 1239 int32_t Mat_GetInt3(Mat m, int x, int y, int z); 1240 float Mat_GetFloat(Mat m, int row, int col); 1241 float Mat_GetFloat3(Mat m, int x, int y, int z); 1242 double Mat_GetDouble(Mat m, int row, int col); 1243 double Mat_GetDouble3(Mat m, int x, int y, int z); 1244 1245 Mat Mat_Region(Mat m, Rect r); 1246 void Mat_PatchNaNs(Mat m); 1247 1248 void Mat_MultiplyInt(Mat m, int val); 1249 void Mat_DivideInt(Mat m, int val); 1250 void Mat_AddDouble(Mat m, double val); 1251 void Mat_SubtractDouble(Mat m, double val); 1252 void Mat_AddInt(Mat m, int val); 1253 void Mat_SubtractInt(Mat m, int val); 1254 void Mat_AddScalar(Mat m, Scalar s); 1255 1256 Mat Mat_EQInt(Mat m, int a); 1257 Mat Mat_GTInt(Mat m, int a); 1258 Mat Mat_GEInt(Mat m, int a); 1259 Mat Mat_LTInt(Mat m, int a); 1260 Mat Mat_LEInt(Mat m, int a); 1261 Mat Mat_NEInt(Mat m, int a); 1262 1263 Mat Mat_EQDouble(Mat m, double a); 1264 Mat Mat_GTDouble(Mat m, double a); 1265 Mat Mat_GEDouble(Mat m, double a); 1266 Mat Mat_LTDouble(Mat m, double a); 1267 Mat Mat_LEDouble(Mat m, double a); 1268 Mat Mat_NEDouble(Mat m, double a); 1269 1270 void Mat_AddUChar(Mat m, uint8_t val); 1271 void Mat_SubtractUChar(Mat m, uint8_t val); 1272 void Mat_MultiplyUChar(Mat m, uint8_t val); 1273 void Mat_DivideUChar(Mat m, uint8_t val); 1274 void Mat_AddFloat(Mat m, float val); 1275 void Mat_SubtractFloat(Mat m, float val); 1276 void Mat_MultiplyFloat(Mat m, float val); 1277 void Mat_MultiplyDouble(Mat m, double val); 1278 void Mat_DivideFloat(Mat m, float val); 1279 1280 void LUT(Mat src, Mat lut, Mat dst); 1281 1282 void Mat_AbsDiff(Mat src1, Mat src2, Mat dst); 1283 void Mat_Add(Mat src1, Mat src2, Mat dst); 1284 void Mat_AddWeighted(Mat src1, double alpha, Mat src2, double beta, double gamma, Mat dst); 1285 void Mat_BitwiseAnd(Mat src1, Mat src2, Mat dst); 1286 void Mat_BitwiseAndWithMask(Mat src1, Mat src2, Mat dst, Mat mask); 1287 void Mat_BitwiseNot(Mat src1, Mat dst); 1288 void Mat_BitwiseNotWithMask(Mat src1, Mat dst, Mat mask); 1289 void Mat_BitwiseOr(Mat src1, Mat src2, Mat dst); 1290 void Mat_BitwiseOrWithMask(Mat src1, Mat src2, Mat dst, Mat mask); 1291 void Mat_BitwiseXor(Mat src1, Mat src2, Mat dst); 1292 void Mat_BitwiseXorWithMask(Mat src1, Mat src2, Mat dst, Mat mask); 1293 void Mat_Compare(Mat src1, Mat src2, Mat dst, int ct); 1294 void Mat_CompareWithScalar(Mat src1, Scalar src2, Mat dst, int ct); 1295 void Mat_BatchDistance(Mat src1, Mat src2, Mat dist, int dtype, Mat nidx, int normType, int K, Mat mask, int update, bool crosscheck); 1296 int Mat_BorderInterpolate(int p, int len, int borderType); 1297 void Mat_CalcCovarMatrix(Mat samples, Mat covar, Mat mean, int flags, int ctype); 1298 void Mat_CartToPolar(Mat x, Mat y, Mat magnitude, Mat angle, bool angleInDegrees); 1299 bool Mat_CheckRange(Mat m); 1300 void Mat_CompleteSymm(Mat m, bool lowerToUpper); 1301 void Mat_ConvertScaleAbs(Mat src, Mat dst, double alpha, double beta); 1302 void Mat_CopyMakeBorder(Mat src, Mat dst, int top, int bottom, int left, int right, int borderType, Scalar value); 1303 int Mat_CountNonZero(Mat src); 1304 void Mat_DCT(Mat src, Mat dst, int flags); 1305 double Mat_Determinant(Mat m); 1306 void Mat_DFT(Mat m, Mat dst, int flags); 1307 void Mat_Divide(Mat src1, Mat src2, Mat dst); 1308 bool Mat_Eigen(Mat src, Mat eigenvalues, Mat eigenvectors); 1309 void Mat_EigenNonSymmetric(Mat src, Mat eigenvalues, Mat eigenvectors); 1310 void Mat_Exp(Mat src, Mat dst); 1311 void Mat_ExtractChannel(Mat src, Mat dst, int coi); 1312 void Mat_FindNonZero(Mat src, Mat idx); 1313 void Mat_Flip(Mat src, Mat dst, int flipCode); 1314 void Mat_Gemm(Mat src1, Mat src2, double alpha, Mat src3, double beta, Mat dst, int flags); 1315 int Mat_GetOptimalDFTSize(int vecsize); 1316 void Mat_Hconcat(Mat src1, Mat src2, Mat dst); 1317 void Mat_Vconcat(Mat src1, Mat src2, Mat dst); 1318 void Rotate(Mat src, Mat dst, int rotationCode); 1319 void Mat_Idct(Mat src, Mat dst, int flags); 1320 void Mat_Idft(Mat src, Mat dst, int flags, int nonzeroRows); 1321 void Mat_InRange(Mat src, Mat lowerb, Mat upperb, Mat dst); 1322 void Mat_InRangeWithScalar(Mat src, const Scalar lowerb, const Scalar upperb, Mat dst); 1323 void Mat_InsertChannel(Mat src, Mat dst, int coi); 1324 double Mat_Invert(Mat src, Mat dst, int flags); 1325 void Mat_Log(Mat src, Mat dst); 1326 void Mat_Magnitude(Mat x, Mat y, Mat magnitude); 1327 void Mat_Max(Mat src1, Mat src2, Mat dst); 1328 void Mat_MeanStdDev(Mat src, Mat dstMean, Mat dstStdDev); 1329 void Mat_Merge(Mats mats, Mat dst); 1330 void Mat_Merge2(Mats mats, int count, Mat dst); 1331 void Mat_Min(Mat src1, Mat src2, Mat dst); 1332 void Mat_MinMaxIdx(Mat m, double* minVal, double* maxVal, int* minIdx, int* maxIdx); 1333 void Mat_MinMaxLoc(Mat m, double* minVal, double* maxVal, Point* minLoc, Point* maxLoc); 1334 void Mat_MinMaxLoc2(Mat a, double* minVal, double* maxVal, int* minIdx, int* maxIdx); 1335 void Mat_MulSpectrums(Mat a, Mat b, Mat c, int flags); 1336 void Mat_Multiply(Mat src1, Mat src2, Mat dst); 1337 void Mat_Normalize(Mat src, Mat dst, double alpha, double beta, int typ); 1338 double Norm(Mat src1, int normType); 1339 void Mat_PerspectiveTransform(Mat src, Mat dst, Mat tm); 1340 bool Mat_Solve(Mat src1, Mat src2, Mat dst, int flags); 1341 int Mat_SolveCubic(Mat coeffs, Mat roots); 1342 double Mat_SolvePoly(Mat coeffs, Mat roots, int maxIters); 1343 void Mat_Reduce(Mat src, Mat dst, int dim, int rType, int dType); 1344 void Mat_Repeat(Mat src, int nY, int nX, Mat dst); 1345 void Mat_ScaleAdd(Mat src1, double alpha, Mat src2, Mat dst); 1346 void Mat_Sort(Mat src, Mat dst, int flags); 1347 void Mat_SortIdx(Mat src, Mat dst, int flags); 1348 void Mat_Split(Mat src, Mats* mats); 1349 Mats Mat_Split2(Mat src); 1350 void Mat_Subtract(Mat src1, Mat src2, Mat dst); 1351 Scalar Mat_Trace(Mat src); 1352 void Mat_Transform(Mat src, Mat dst, Mat tm); 1353 void Mat_Transpose(Mat src, Mat dst); 1354 void Mat_PolarToCart(Mat magnitude, Mat degree, Mat x, Mat y, bool angleInDegrees); 1355 void Mat_Pow(Mat src, double power, Mat dst); 1356 void Mat_Phase(Mat x, Mat y, Mat angle, bool angleInDegrees); 1357 Scalar Mat_Sum(Mat src1); 1358 1359 RotatedRect New_RotatedRect(Point center, Size size, double angle); 1360 1361 TermCriteria TermCriteria_New(int typ, int maxCount, double epsilon); 1362 double Get_TermCriteria_Epsilon(TermCriteria tc); 1363 int Get_TermCriteria_MaxCount(TermCriteria tc); 1364 int Get_TermCriteria_Type(TermCriteria tc); 1365 void TermCriteria_Close(TermCriteria tc); 1366 1367 int64_t GetCVTickCount(); 1368 double GetTickFrequency(); 1369 1370 Mat Mat_ZerosFromRC(int rows, int cols, int type); 1371 Mat Mat_ZerosFromSize(Size sz, int type); 1372 Mat Mat_OnesFromRC(int rows, int cols, int type); 1373 Mat Mat_OnesFromSize(Size sz, int type); 1374 1375 double Mat_Dot(Mat m1, Mat m2); 1376 Mat Mat_Diag(Mat src, int d); 1377 Mat Mat_EyeFromRC(int rows, int cols, int type); 1378 1379 bool Rect_Contains(Rect r, Point p); 1380 1381 PCA PCA_New(); 1382 PCA PCA_NewWithMaxComp(Mat data, Mat mean, int flags, int maxComponents); 1383 PCA PCA_NewWithRetVar(Mat data, Mat mean, int flags, double retainedVariance); 1384 void PCA_BackProject(PCA pca, Mat vec, Mat result); 1385 void PCA_Project(PCA pca, Mat vec, Mat result); 1386 Mat PCA_Eigenvalues(PCA pca); 1387 Mat PCA_Eigenvectors(PCA pca); 1388 Mat PCA_Mean(PCA pca); 1389 1390 double Kmeans(Mat data, int K, Mat bestLabels, 1391 TermCriteria criteria, int attempts, int flags, Mat centers); 1392 double Kmeans2(Mat data, int K, Mat bestLabels, 1393 TermCriteria criteria, int attempts, int flags, Point2fs* centers); 1394 void Mat_Fill_Random(uint64_t state, Mat mat, int distType, Scalar a, Scalar b, bool saturateRange); 1395 void Mat_RandShuffle(uint64_t state, Mat dst, double iterFactor); 1396 1397 Range Range_New(); 1398 Range Range_NewWithParams(int _start, int _end); 1399 Range Range_All(); 1400 bool Range_Empty(Range rng); 1401 int Range_Size(Range rng); 1402 int Range_GetStart(Range rng); 1403 int Range_GetEnd(Range rng); 1404 } 1405 1406 1407 Mat newMat(){ 1408 return Mat_New(); 1409 } 1410 1411 Mat newMatWithSize( int rows, int cols, int mt ){ 1412 return Mat_NewWithSize(rows, cols, mt); 1413 } 1414 1415 Mat newMatFromScalar( const Scalar ar, int type){ 1416 return Mat_NewFromScalar(ar, type); 1417 } 1418 1419 Mat newMatWithSizeFromScalar(const Scalar ar, int rows, int cols, int type){ 1420 return Mat_NewWithSizeFromScalar(ar, rows, cols, type); 1421 } 1422 1423 Mat newMatFromBytes(int rows, int cols, int type, ByteArray buf){ 1424 return Mat_NewFromBytes(rows, cols, type, buf); 1425 } 1426 1427 Mat newMatFromPtr(Mat m, int rows, int cols, int type, int prows, int pcols){ 1428 return Mat_FromPtr(m, rows, cols, type, prows, pcols); 1429 } 1430 1431 Mat newMatFromArrayPtr(int rows, int cols, int type, void* data){ 1432 return Mat_FromArrayPtr(rows, cols, type, data); 1433 } 1434 1435 Mat newMatFromContour(Point[] pts){ 1436 return Mat_FromContour(Contour(pts.ptr, pts.length.to!int)); 1437 } 1438 1439 Mat zeros(int rows, int cols, int type){ 1440 return Mat_ZerosFromRC(rows, cols, type); 1441 } 1442 1443 Mat zeros(Size sz, int type){ 1444 return Mat_ZerosFromSize(sz, type); 1445 } 1446 1447 Mat ones(int rows, int cols, int type){ 1448 return Mat_OnesFromRC(rows, cols, type); 1449 } 1450 Mat ones(Size sz, int type){ 1451 return Mat_OnesFromSize(sz, type); 1452 } 1453 1454 int CV_MAKETYPE(int depth, int cn){ 1455 return Mat_CV_MAKETYPE(depth, cn); 1456 } 1457 1458 Size getSize(Mat m){ 1459 return Size(m.rows, m.cols); 1460 } 1461 1462 Mat reshape(Mat m, int cn, int rows){ 1463 return Mat_Reshape( m, cn, rows); 1464 } 1465 1466 void Destroy(Mat m){ 1467 Mat_Close(m); 1468 } 1469 1470 bool isEmpty(Mat m){ 1471 return Mat_Empty(m) == 0 ? false: true; 1472 } 1473 1474 alias empty = isEmpty; 1475 1476 Mat clone(Mat m){ 1477 return Mat_Clone(m); 1478 } 1479 1480 void copyTo(Mat m, Mat dst){ 1481 Mat_CopyTo(m, dst); 1482 } 1483 1484 void copyToWithMask(Mat m, Mat dst, Mat mask){ 1485 Mat_CopyToWithMask(m, dst, mask); 1486 } 1487 1488 void convertTo(Mat m, Mat dst, int type){ 1489 Mat_ConvertTo(m, dst, type); 1490 } 1491 1492 void convertTo(Mat m, Mat dst, int rtype, double alpha = 1, double beta = 0 ){ 1493 Mat_convertTo2(m, dst, rtype, alpha, beta); 1494 } 1495 1496 void setTo(Mat m, Scalar s){ 1497 Mat_SetTo(m, s); 1498 } 1499 1500 void setTo(Mat m, Scalar s, Mat mask){ 1501 Mat_SetToWithMask(m, s, mask); 1502 } 1503 1504 void patchNaNs(Mat m){ 1505 Mat_PatchNaNs(m); 1506 } 1507 1508 Mat matFromRect(Mat m, Rect r){ 1509 return Mat_Region(m, r); 1510 } 1511 1512 alias subImageFromROI = matFromRect; 1513 1514 void addUChar(Mat m, ubyte val){ 1515 Mat_AddUChar(m, val); 1516 } 1517 1518 void subtractUChar(Mat m, ubyte val){ 1519 Mat_SubtractUChar(m, val); 1520 } 1521 1522 void multiplyUChar(Mat m, ubyte val){ 1523 Mat_MultiplyUChar(m, val); 1524 } 1525 1526 void divideUChar(Mat m, ubyte val){ 1527 Mat_DivideUChar(m, val); 1528 } 1529 1530 void addFloat(Mat m, float val){ 1531 Mat_AddFloat(m, val); 1532 } 1533 1534 void subtractFloat(Mat m, float val){ 1535 Mat_SubtractFloat(m, val); 1536 } 1537 1538 void multiplyFloat(Mat m, float val){ 1539 multiplyFloat(m, val); 1540 } 1541 1542 void multiplyDouble(Mat m, double val){ 1543 Mat_MultiplyDouble(m, val); 1544 } 1545 1546 void divideFloat(Mat m, float val){ 1547 Mat_DivideFloat(m, val); 1548 } 1549 1550 void multiplyInt(Mat m, int val){ 1551 Mat_MultiplyInt(m, val); 1552 } 1553 1554 void divideInt(Mat m, int val){ 1555 Mat_DivideInt(m, val); 1556 } 1557 1558 void addDouble(Mat m, double val){ 1559 Mat_AddDouble(m, val); 1560 } 1561 1562 void subtractDouble(Mat m, double val){ 1563 Mat_SubtractDouble(m, val); 1564 } 1565 1566 void addInt(Mat m, int val){ 1567 Mat_AddInt(m, val); 1568 } 1569 1570 void subtractInt(Mat m, int val){ 1571 Mat_SubtractInt(m, val); 1572 } 1573 1574 1575 void performLUT(Mat src, Mat lut, Mat dst){ 1576 LUT(src, lut, dst); 1577 } 1578 1579 void absDiff(Mat src1, Mat src2, Mat dst){ 1580 Mat_AbsDiff(src1, src2, dst); 1581 } 1582 1583 void add(Mat src1, Mat src2, Mat dst){ 1584 Mat_Add(src1, src2, dst); 1585 } 1586 1587 void addScalar(Mat m, Scalar s){ 1588 Mat_AddScalar(m, s); 1589 } 1590 1591 void addWeighted(Mat src1, double alpha, Mat src2, double beta, double gamma, Mat dst){ 1592 Mat_AddWeighted(src1, alpha, src2, beta, gamma, dst); 1593 } 1594 1595 void bitwiseAnd(Mat src1, Mat src2, Mat dst){ 1596 Mat_BitwiseAnd(src1, src2, dst); 1597 } 1598 1599 void bitwiseAndWithMask(Mat src1, Mat src2, Mat dst, Mat mask){ 1600 Mat_BitwiseAndWithMask(src1, src2, dst, mask); 1601 } 1602 1603 void bitwiseNot(Mat src1, Mat dst){ 1604 Mat_BitwiseNot(src1, dst); 1605 } 1606 1607 void bitwiseNotWithMask(Mat src1, Mat dst, Mat mask){ 1608 Mat_BitwiseNotWithMask(src1, dst, mask); 1609 } 1610 1611 void bitwiseOr(Mat src1, Mat src2, Mat dst){ 1612 Mat_BitwiseOr(src1, src2, dst); 1613 } 1614 1615 void bitwiseOrWithMask(Mat src1, Mat src2, Mat dst, Mat mask){ 1616 Mat_BitwiseOrWithMask(src1, src2, dst, mask); 1617 } 1618 1619 void bitwiseXor(Mat src1, Mat src2, Mat dst){ 1620 Mat_BitwiseXor(src1, src2, dst); 1621 } 1622 1623 void bitwiseXorWithMask(Mat src1, Mat src2, Mat dst, Mat mask){ 1624 Mat_BitwiseXorWithMask(src1, src2, dst, mask); 1625 } 1626 1627 enum: int { 1628 // enum cv::CmpTypes 1629 CMP_EQ, 1630 CMP_GT, 1631 CMP_GE, 1632 CMP_LT, 1633 CMP_LE, 1634 CMP_NE, 1635 } 1636 1637 void compare(Mat src1, Mat src2, Mat dst, int ct){ 1638 Mat_Compare(src1, src2, dst, ct); 1639 } 1640 1641 void compare(Mat src1, Scalar src2, Mat dst, int ct){ 1642 Mat_CompareWithScalar(src1, src2, dst, ct); 1643 } 1644 1645 void batchDistance(Mat src1, Mat src2, Mat dist, int dtype, Mat nidx, int normType, int K, Mat mask, int update, bool crosscheck){ 1646 Mat_BatchDistance(src1, src2, dist, dtype, nidx, normType, K, mask, update, crosscheck); 1647 } 1648 1649 enum: int { 1650 // CovarScrambled indicates to scramble the results. 1651 CovarScrambled = 0, 1652 1653 // CovarNormal indicates to use normal covariation. 1654 CovarNormal = 1, 1655 1656 // CovarUseAvg indicates to use average covariation. 1657 CovarUseAvg = 2, 1658 1659 // CovarScale indicates to use scaled covariation. 1660 CovarScale = 4, 1661 1662 // CovarRows indicates to use covariation on rows. 1663 CovarRows = 8, 1664 1665 // CovarCols indicates to use covariation on columns. 1666 CovarCols = 16, 1667 } 1668 alias CovarFlags = int; 1669 1670 int borderInterpolate(int p, int len, CovarFlags borderType){ 1671 return Mat_BorderInterpolate(p, len, borderType); 1672 } 1673 1674 void calcCovarMatrix(Mat samples, Mat covar, Mat mean, CovarFlags flags, int ctype){ 1675 Mat_CalcCovarMatrix(samples, covar, mean, flags, ctype); 1676 } 1677 1678 void cartToPolar(Mat x, Mat y, Mat magnitude, Mat angle, bool angleInDegrees){ 1679 Mat_CartToPolar(x, y, magnitude, angle, angleInDegrees); 1680 } 1681 1682 bool checkRange(Mat m){ 1683 return Mat_CheckRange(m); 1684 } 1685 1686 void completeSymm(Mat m, bool lowerToUpper){ 1687 Mat_CompleteSymm(m, lowerToUpper); 1688 } 1689 1690 void convertScaleAbs(Mat src, Mat dst, double alpha = 1, double beta = 0){ 1691 Mat_ConvertScaleAbs(src, dst, alpha, beta); 1692 } 1693 1694 void copyMakeBorder(Mat src, Mat dst, int top, int bottom, int left, int right, CovarFlags borderType, Scalar value){ 1695 Mat_CopyMakeBorder(src, dst, top, bottom, left, right, borderType, value); 1696 } 1697 1698 enum: int { 1699 // DftForward performs forward 1D or 2D dft or dct. 1700 DftForward = 0, 1701 1702 // DftInverse performs an inverse 1D or 2D transform. 1703 DftInverse = 1, 1704 1705 // DftScale scales the result: divide it by the number of array elements. Normally, it is combined with DFT_INVERSE. 1706 DftScale = 2, 1707 1708 // DftRows performs a forward or inverse transform of every individual row of the input matrix. 1709 DftRows = 4, 1710 1711 // DftComplexOutput performs a forward transformation of 1D or 2D real array; the result, though being a complex array, has complex-conjugate symmetry 1712 DftComplexOutput = 16, 1713 1714 // DftRealOutput performs an inverse transformation of a 1D or 2D complex array; the result is normally a complex array of the same size, 1715 // however, if the input array has conjugate-complex symmetry (for example, it is a result of forward transformation with DFT_COMPLEX_OUTPUT flag), 1716 // the output is a real array. 1717 DftRealOutput = 32, 1718 1719 // DftComplexInput specifies that input is complex input. If this flag is set, the input must have 2 channels. 1720 DftComplexInput = 64, 1721 1722 // DctInverse performs an inverse 1D or 2D dct transform. 1723 DctInverse = DftInverse, 1724 1725 // DctRows performs a forward or inverse dct transform of every individual row of the input matrix. 1726 DctRows = DftRows 1727 } 1728 1729 alias DftFlags = int; 1730 1731 int countNonZero(Mat src){ 1732 return Mat_CountNonZero(src); 1733 } 1734 1735 void DCT(Mat src, Mat dst, int flags){ 1736 Mat_DCT(src, dst, flags); 1737 } 1738 1739 double determinant(Mat m){ 1740 return Mat_Determinant(m); 1741 } 1742 1743 void DFT(Mat m, Mat dst, DftFlags flags){ 1744 Mat_DFT(m, dst, flags); 1745 } 1746 1747 void divide(Mat src1, Mat src2, Mat dst){ 1748 Mat_Divide(src1, src2, dst); 1749 } 1750 1751 bool eigen(Mat src, Mat eigenvalues, Mat eigenvectors){ 1752 return Mat_Eigen(src, eigenvalues, eigenvectors); 1753 } 1754 1755 void eigenNonSymmetric(Mat src, Mat eigenvalues, Mat eigenvectors){ 1756 Mat_EigenNonSymmetric(src, eigenvalues, eigenvectors); 1757 } 1758 1759 void matExp(Mat src, Mat dst){ 1760 Mat_Exp(src, dst); 1761 } 1762 1763 void extractChannel(Mat src, Mat dst, int coi){ 1764 Mat_ExtractChannel(src, dst, coi); 1765 } 1766 1767 void findNonZero(Mat src, Mat idx){ 1768 Mat_FindNonZero(src, idx); 1769 } 1770 1771 void flip(Mat src, Mat dst, int flipCode){ 1772 Mat_Flip(src, dst, flipCode); 1773 } 1774 1775 void gemm(Mat src1, Mat src2, double alpha, Mat src3, double beta, Mat dst, int flags){ 1776 Mat_Gemm(src1, src2, alpha, src3, beta, dst, flags); 1777 } 1778 1779 int getOptimalDFTSize(int vecsize){ 1780 return Mat_GetOptimalDFTSize(vecsize); 1781 } 1782 1783 void hconcat(Mat src1, Mat src2, Mat dst){ 1784 Mat_Hconcat(src1, src2, dst); 1785 } 1786 1787 void vconcat(Mat src1, Mat src2, Mat dst){ 1788 Mat_Vconcat(src1, src2, dst); 1789 } 1790 1791 void rotate(Mat src, Mat dst, int rotationCode){ 1792 Rotate(src, dst, rotationCode); 1793 } 1794 1795 void idct(Mat src, Mat dst, int flags){ 1796 Mat_Idct(src, dst, flags); 1797 } 1798 1799 void idft(Mat src, Mat dst, int flags, int nonzeroRows){ 1800 Mat_Idft(src, dst, flags, nonzeroRows); 1801 } 1802 1803 void inRange(Mat src, Mat lowerb, Mat upperb, Mat dst){ 1804 Mat_InRange(src, lowerb, upperb, dst); 1805 } 1806 1807 void inRange(Mat src, const Scalar lowerb, const Scalar upperb, Mat dst){ 1808 Mat_InRangeWithScalar(src, lowerb, upperb, dst); 1809 } 1810 1811 void insertChannel(Mat src, Mat dst, int coi){ 1812 Mat_InsertChannel(src, dst, coi); 1813 } 1814 1815 double invert(Mat src, Mat dst, int flags){ 1816 return Mat_Invert(src, dst, flags); 1817 } 1818 1819 void matLog(Mat src, Mat dst){ 1820 Mat_Log(src, dst); 1821 } 1822 1823 void magnitude(Mat x, Mat y, Mat magnitude){ 1824 Mat_Magnitude(x, y, magnitude); 1825 } 1826 1827 void matMax(Mat src1, Mat src2, Mat dst){ 1828 Mat_Max(src1, src2, dst); 1829 } 1830 1831 void meanStdDev(Mat src, Mat dstMean, Mat dstStdDev){ 1832 Mat_MeanStdDev(src, dstMean, dstStdDev); 1833 } 1834 1835 void merge(Mats mats, Mat dst){ 1836 Mat_Merge(mats, dst); 1837 } 1838 1839 void merge(Mat[] mats, Mat dst){ 1840 Mat_Merge(Mats(mats.ptr, cast(int)mats.length), dst); 1841 } 1842 1843 void matMin(Mat src1, Mat src2, Mat dst){ 1844 Mat_Min(src1, src2, dst); 1845 } 1846 1847 void minMaxIdx(Mat m, double* minVal, double* maxVal, int* minIdx, int* maxIdx){ 1848 Mat_MinMaxIdx(m, minVal, maxVal, minIdx, maxIdx); 1849 } 1850 1851 void minMaxLoc(Mat m, double* minVal, double* maxVal, Point* minLoc, Point* maxLoc){ 1852 Mat_MinMaxLoc(m, minVal, maxVal, minLoc, maxLoc); 1853 } 1854 1855 void minMaxLoc(Mat a, double* minVal, double* maxVal, int* minIdx, int* maxIdx){ 1856 Mat_MinMaxLoc2(a, minVal, maxVal, minIdx, maxIdx); 1857 } 1858 1859 void mulSpectrums(Mat a, Mat b, Mat c, int flags){ 1860 Mat_MulSpectrums(a, b, c, flags); 1861 } 1862 1863 void multiply(Mat src1, Mat src2, Mat dst){ 1864 Mat_Multiply(src1, src2, dst); 1865 } 1866 1867 void subtract(Mat src1, Mat src2, Mat dst){ 1868 Mat_Subtract(src1, src2, dst); 1869 } 1870 1871 enum: int {// cv::NormTypes 1872 NORM_INF = 1, 1873 NORM_L1 = 2, 1874 NORM_L2 = 4, 1875 NORM_L2SQR = 5, 1876 NORM_HAMMING = 6, 1877 NORM_HAMMING2 = 7, 1878 NORM_TYPE_MASK = 7, 1879 NORM_RELATIVE = 8, 1880 NORM_MINMAX = 32 1881 } 1882 1883 void normalize(Mat src, Mat dst, double alpha, double beta, int typ){ 1884 Mat_Normalize(src, dst, alpha, beta, typ); 1885 } 1886 1887 double norm(Mat src1, int normType){ 1888 return Norm(src1, normType); 1889 } 1890 1891 void perspectiveTransform(Mat src, Mat dst, Mat tm){ 1892 Mat_PerspectiveTransform(src, dst, tm); 1893 } 1894 1895 void perspectiveTransform(Point2f[] src, ref Point2f[] dst, Mat tm){ 1896 1897 Mat srcmat = zeros(src.length.to!int, 1, CV_MAKETYPE(CV_32F, 2)); 1898 foreach(int i; 0..src.length.to!int){ 1899 srcmat.set!float(i, 0, src[i].x); 1900 srcmat.set!float(i, 1, src[i].y); 1901 } 1902 1903 Mat dstmat = zeros(src.length.to!int, 1, CV_MAKETYPE(CV_32F, 2)); 1904 1905 Mat_PerspectiveTransform(srcmat, dstmat, tm); 1906 1907 dst.length = dstmat.rows.to!size_t; 1908 foreach(int i; 0..dstmat.rows){ 1909 float xx = dstmat.at!float(i, 0); 1910 float yy = dstmat.at!float(i, 1); 1911 dst[i] = Point2f(xx, yy); 1912 } 1913 1914 Destroy(srcmat); 1915 Destroy(dstmat); 1916 } 1917 1918 bool solve(Mat src1, Mat src2, Mat dst, int flags){ 1919 return Mat_Solve(src1, src2, dst, flags); 1920 } 1921 1922 int solveCubic(Mat coeffs, Mat roots){ 1923 return Mat_SolveCubic(coeffs, roots); 1924 } 1925 1926 double solvePoly(Mat coeffs, Mat roots, int maxIters){ 1927 return Mat_SolvePoly(coeffs, roots, maxIters); 1928 } 1929 1930 void reduce(Mat src, Mat dst, int dim, int rType, int dType){ 1931 Mat_Reduce(src, dst, dim, rType, dType); 1932 } 1933 1934 void repeat(Mat src, int nY, int nX, Mat dst){ 1935 Mat_Repeat(src, nY, nX, dst); 1936 } 1937 1938 void scaleAdd(Mat src1, double alpha, Mat src2, Mat dst){ 1939 Mat_ScaleAdd(src1, alpha, src2, dst); 1940 } 1941 1942 void matSort(Mat src, Mat dst, int flags){ 1943 Mat_Sort(src, dst, flags); 1944 } 1945 1946 void matSortIdx(Mat src, Mat dst, int flags){ 1947 Mat_SortIdx(src, dst, flags); 1948 } 1949 1950 void matSplit(Mat src, Mats* mats){ 1951 Mats _mats = Mat_Split2(src); 1952 mats = &_mats; 1953 } 1954 1955 void matSplit(Mat src, ref Mat[] _mats){ 1956 Mats mats = Mat_Split2(src); 1957 _mats = mats.mats[0..mats.length]; 1958 } 1959 1960 alias split = matSplit; 1961 1962 void matSubtract(Mat src1, Mat src2, Mat dst){ 1963 Mat_Subtract(src1, src2, dst); 1964 } 1965 1966 Scalar matTrace(Mat src){ 1967 return Mat_Trace(src); 1968 } 1969 1970 void transform(Mat src, Mat dst, Mat tm){ 1971 Mat_Transform(src, dst, tm); 1972 } 1973 1974 void transpose(Mat src, Mat dst){ 1975 Mat_Transpose(src, dst); 1976 } 1977 1978 void polarToCart(Mat magnitude, Mat degree, Mat x, Mat y, bool angleInDegrees){ 1979 Mat_PolarToCart(magnitude, degree, x, y, angleInDegrees); 1980 } 1981 1982 void matPow(Mat src, double power, Mat dst){ 1983 Mat_Pow(src, power, dst); 1984 } 1985 1986 void phase(Mat x, Mat y, Mat angle, bool angleInDegrees){ 1987 Mat_Phase(x, y, angle, angleInDegrees); 1988 } 1989 1990 Scalar matSum(Mat src1){ 1991 return Mat_Sum(src1); 1992 } 1993 1994 struct TermCriteria { 1995 void* p; 1996 1997 enum: int { 1998 COUNT =1, 1999 MAX_ITER =COUNT, 2000 EPS =2 2001 } 2002 2003 static TermCriteria opCall(int typ, int maxCount, double epsilon){ 2004 return TermCriteria_New(typ, maxCount, epsilon); 2005 } 2006 2007 double epsilon(){ 2008 return Get_TermCriteria_Epsilon(this); 2009 } 2010 2011 int maxCount(){ 2012 return Get_TermCriteria_MaxCount(this); 2013 } 2014 2015 int type(){ 2016 return Get_TermCriteria_Type(this); 2017 } 2018 } 2019 2020 TermCriteria newTermCriteria(int typ, int maxCount, double epsilon){ 2021 return TermCriteria_New(typ, maxCount, epsilon); 2022 } 2023 2024 void Destroy(TermCriteria tc){ 2025 TermCriteria_Close(tc); 2026 } 2027 2028 int64_t getCVTickCount(){ 2029 return GetCVTickCount(); 2030 } 2031 2032 double getTickFrequency(){ 2033 return GetTickFrequency(); 2034 } 2035 2036 double dot(Mat m1, Mat m2){ 2037 return Mat_Dot(m1, m2); 2038 } 2039 2040 Mat diag(Mat src, int d = 0){ 2041 return Mat_Diag(src, d); 2042 } 2043 2044 Mat eye(int rows, int cols, int type){ 2045 return Mat_EyeFromRC(rows, cols, type); 2046 } 2047 2048 Mat eye(Size sz, int type){ 2049 return Mat_EyeFromRC(sz.height, sz.width, type); 2050 } 2051 2052 struct PCA { 2053 void* p; 2054 2055 static int DATA_AS_ROW = 0; 2056 static int DATA_AS_COL = 1; 2057 static int USE_AVG = 2; 2058 2059 static PCA opCall(){ 2060 return PCA_New(); 2061 } 2062 2063 static PCA opCall(Mat data, Mat mean, int flags, int maxComponents = 0){ 2064 return PCA_NewWithMaxComp(data, mean, flags, maxComponents); 2065 } 2066 2067 static PCA opCall(Mat data, Mat mean, int flags, double retainedVariance){ 2068 return PCA_NewWithRetVar(data, mean, flags, retainedVariance); 2069 } 2070 2071 void backProject(Mat vec, Mat result){ 2072 PCA_BackProject(this, vec, result); 2073 } 2074 2075 void project(Mat vec, Mat result){ 2076 PCA_Project(this, vec, result); 2077 } 2078 2079 Mat eigenvalues(){ 2080 return PCA_Eigenvalues(this); 2081 } 2082 2083 Mat eigenvectors(){ 2084 return PCA_Eigenvectors(this); 2085 } 2086 2087 Mat mean(){ 2088 return PCA_Mean(this); 2089 } 2090 } 2091 2092 enum: int { // cv::KmeansFlags 2093 KMEANS_RANDOM_CENTERS = 0, 2094 KMEANS_PP_CENTERS = 2, 2095 KMEANS_USE_INITIAL_LABELS = 1 2096 } 2097 2098 double kmeans(Mat data, int K, Mat bestLabels, 2099 TermCriteria criteria, int attempts, int flags, Mat centers = Mat()){ 2100 return Kmeans(data, K, bestLabels, criteria, attempts, flags, centers); 2101 } 2102 2103 double kmeans(Mat data, int K, Mat bestLabels, 2104 TermCriteria criteria, int attempts, int flags, ref Point2f[] centers){ 2105 Point2fs _centers; 2106 double ret = Kmeans2(data, K, bestLabels, criteria, attempts, flags, &_centers); 2107 centers = _centers.points[0.._centers.length.to!int].dup; 2108 free(_centers.points); 2109 return ret; 2110 } 2111 2112 enum { // 2113 RNG_UNIFORM = 0, 2114 RNG_NORMAL = 1 2115 } 2116 2117 void fillRandom(uint64_t state, Mat mat, int distType, Scalar a, Scalar b, bool saturateRange = false){ 2118 Mat_Fill_Random(state, mat, distType, a, b, saturateRange); 2119 } 2120 2121 void randShuffle(uint64_t state, Mat dst, double iterFactor=1.0){ 2122 Mat_RandShuffle(state, dst, iterFactor); 2123 } 2124 2125 struct Range { 2126 void* p; 2127 2128 static Range opCall(){ 2129 return Range_New(); 2130 } 2131 2132 static Range opCall(int _start, int _end){ 2133 return Range_NewWithParams(_start, _end); 2134 } 2135 2136 static Range all(){ 2137 return Range_All(); 2138 } 2139 2140 bool empty(){ 2141 return Range_Empty(this); 2142 } 2143 2144 int size(){ 2145 return Range_Size(this); 2146 } 2147 2148 int start(){ 2149 return Range_GetStart(this); 2150 } 2151 2152 int end(){ 2153 return Range_GetEnd(this); 2154 } 2155 } 2156 2157 struct RangeVector { 2158 Range* ranges; 2159 int length; 2160 }