00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef MATRIX_H
00024 #define MATRIX_H
00025
00026 #include <math.h>
00027 #include <stdio.h>
00028 #include <string.h>
00029 #include <stdlib.h>
00030 #include <iostream>
00031 #include <fstream>
00032 #include <string>
00033 #include <queue>
00034 #include <stack>
00035 #include <vector>
00036 #include <algorithm>
00037 #ifdef GNU_COMPILER
00038 #include <strstream>
00039 #else
00040 #include <sstream>
00041 #endif
00042
00043 #ifndef PI
00044 #define PI 3.1415926536
00045 #endif
00046
00047 #ifndef round
00048 #define round(x) floor(x + 0.5)
00049 #endif
00050
00051 #define MAXF(a,b,c,d) MAX(MAX(a,b),MAX(c,d))
00052 #define MINF(a,b,c,d) MIN(MIN(a,b),MIN(c,d))
00053 #ifndef MIN
00054 #define MIN(a,b) (a < b ? a : b)
00055 #define MAX(a,b) (a > b ? a : b)
00056 #endif
00057
00058 namespace motld {
00059
00061 struct ObjectBox
00062 {
00064 float x;
00066 float y;
00068 float width;
00070 float height;
00072 int objectId;
00073 };
00074
00076 class Matrix {
00077 public:
00079 inline Matrix();
00081 inline Matrix(const int width, const int height);
00083 Matrix(const Matrix& copyFrom);
00085 Matrix(const int width, const int height, const float value);
00087 virtual ~Matrix();
00088
00090 void copyFromCharArray(unsigned char * source);
00092 void copyFromFloatArray(float * source, int srcwidth, int width, int height);
00094 void copyFromFloatArray(const float * const source, int srcwidth, int srcheight, int x, int y, int width, int height);
00096 void fromRGB(const Matrix& rMatrix, const Matrix& gMatrix, const Matrix& bMatrix);
00098 void fromRGB(unsigned char * source);
00100 void derivativeX(Matrix& result) const;
00102 void derivativeY(Matrix& result) const;
00104 void scharrDerivativeX(Matrix& result) const;
00106 void scharrDerivativeY(Matrix& result) const;
00108 void sobelDerivativeX(Matrix& result) const;
00110 void sobelDerivativeY(Matrix& result) const;
00112 void gaussianSmooth(const float sigma, const int filterSize = 0);
00114 void writeToPGM(const char *filename) const;
00116 Matrix getRectSubPix(float centerx, float centery, int width, int height) const;
00117
00119 void setSize(int width, int height);
00121 void halfSizeImage(Matrix& result) const;
00123 void downsample(int newWidth, int newHeight);
00125 void downsampleBilinear(int newWidth, int newHeight);
00127 void upsample(int newWidth, int newHeight);
00129 void upsampleBilinear(int newWidth, int newHeight);
00131 void rescale(int newWidth, int newHeight);
00132
00134 void fill(const float value);
00136 void cut(Matrix& result,const int x1, const int y1, const int x2, const int y2);
00138 void clip(float aMin, float aMax);
00140 void inv3();
00141
00142
00144 void drawLine(int x1, int y1, int x2, int y2, float value = 255);
00146 void drawCross(int x, int y, int value = 255, int crossSize = 1);
00148 void drawBox(ObjectBox b, int value = 255);
00150 void drawDashedBox(ObjectBox b, int value = 255, int dashLength = 3, bool dotted = false);
00152 void drawPatch(const Matrix & b, int x, int y, float avg = 0);
00154 void drawHistogram(const float * histogram, int x, int y, int value = 255, int nbins = 7, int psize = 15);
00156 void drawNumber(int x, int y, int n, int value = 255);
00157
00159 inline float& operator()(const int ax, const int ay) const;
00161 inline Matrix& operator=(const float value);
00163 Matrix& operator=(const Matrix& copyFrom);
00165 Matrix& operator+=(const float value);
00167 Matrix& operator*=(const float value);
00168
00170 float avg() const;
00172 float norm2() const;
00174 inline int xSize() const;
00176 inline int ySize() const;
00178 inline int size() const;
00180 inline float* data() const;
00181
00183 Matrix affineWarp(const Matrix & t, const ObjectBox & b, const bool & preservear) const;
00185 static Matrix createWarpMatrix(const float& angle, const float& scale);
00187 float* createSummedAreaTable() const;
00189 float** createSummedAreaTable2() const;
00190
00191 protected:
00192 int ivWidth, ivHeight;
00193 float *ivData;
00194 };
00195
00197 Matrix operator*(const Matrix& m1, const Matrix& m2);
00199 std::ostream& operator<<(std::ostream& aStream, const Matrix& aMatrix);
00200
00202 void writePPM(const char* filename, const Matrix& rMatrix, const Matrix& gMatrix, const Matrix& bMatrix);
00203
00204
00205
00206
00207
00208
00209 inline Matrix::Matrix()
00210 {
00211
00212
00213 ivData = NULL;
00214 ivWidth = ivHeight = 0;
00215 }
00216
00217 inline Matrix::Matrix(const int width, const int height)
00218 : ivWidth(width), ivHeight(height)
00219 {
00220 ivData = new float[width*height];
00221 }
00222
00223 Matrix::Matrix(const Matrix& copyFrom)
00224 : ivWidth(copyFrom.ivWidth), ivHeight(copyFrom.ivHeight)
00225 {
00226 if (copyFrom.ivData == 0) ivData = 0;
00227 else {
00228 int wholeSize = ivWidth*ivHeight;
00229 ivData = new float[wholeSize];
00230 memcpy(ivData, copyFrom.ivData, wholeSize * sizeof(float));
00231
00232
00233 }
00234 }
00235
00236 Matrix::Matrix(const int width, const int height, const float value)
00237 : ivWidth(width), ivHeight(height)
00238 {
00239 ivData = new float[width*height];
00240 fill(value);
00241 }
00242
00243 Matrix::~Matrix()
00244 {
00245 delete [] ivData;
00246 }
00247
00248 void Matrix::copyFromCharArray(unsigned char * source)
00249 {
00250 delete [] ivData;
00251 int wholeSize = ivWidth*ivHeight;
00252 ivData = new float[wholeSize];
00253 for (register int i = 0; i < wholeSize; ++i)
00254 ivData[i] = (float)source[i];
00255 }
00256
00257 void Matrix::copyFromFloatArray(const float * const source, int srcwidth, int srcheight,
00258 int x, int y, int width, int height)
00259 {
00260 delete [] ivData;
00261 ivWidth = width; ivHeight = height;
00262 ivData = new float[width*height];
00263 #pragma omp parallel for
00264 for (int dy = 0; dy < height; ++dy)
00265 memcpy(ivData + dy * width, source + (y + dy) * srcwidth + x, width * sizeof(float));
00266 }
00267
00268 void Matrix::copyFromFloatArray(float * source, int srcwidth, int width, int height)
00269 {
00270 delete [] ivData;
00271 ivWidth = width; ivHeight = height;
00272 ivData = new float[width*height];
00273 for (int dy = 0; dy < height; ++dy)
00274 memcpy(ivData + dy * width, source + dy * srcwidth, width * sizeof(float));
00275 }
00276
00277 void Matrix::fromRGB(const Matrix& rMatrix, const Matrix& gMatrix, const Matrix& bMatrix)
00278 {
00279
00280 int wholeSize = ivWidth*ivHeight;
00281
00282 float * rData = rMatrix.data();
00283 float * gData = gMatrix.data();
00284 float * bData = bMatrix.data();
00285 for (int i = 0; i < wholeSize; ++i)
00286 ivData[i] = (rData[i] + gData[i] + bData[i]) * (1.0/3.0);
00287 }
00288
00289 void Matrix::fromRGB(unsigned char * source)
00290 {
00291
00292 int wholeSize = ivWidth*ivHeight;
00293
00294 unsigned char * green = source + wholeSize;
00295 unsigned char * blue = green + wholeSize;
00296 for (int i = 0; i < wholeSize; ++i)
00297 ivData[i] = ((float)source[i] + (float)green[i] + (float)blue[i]) * (1.0/3.0);
00298 }
00299
00300 void Matrix::derivativeX(Matrix& result) const
00301 {
00302 result.setSize(ivWidth, ivHeight);
00303 for(int y = 0; y < ivHeight; ++y)
00304 {
00305 result(0,y) = ivData[1 + y*ivWidth] - ivData[y*ivWidth];
00306 for(int x = 1; x < ivWidth-1; ++x)
00307 result(x,y) = (ivData[x+1 +y*ivWidth] - ivData[x-1 +y*ivWidth]);
00308 result(ivWidth-1,y) = ivData[ivWidth-1 + y*ivWidth] - ivData[ivWidth-2 + y*ivWidth];
00309 }
00310 }
00311
00312 void Matrix::derivativeY(Matrix& result) const
00313 {
00314 result.setSize(ivWidth, ivHeight);
00315 for(int x = 0; x < ivWidth; ++x)
00316 {
00317 result(x,0) = ivData[x + ivWidth] - ivData[x];
00318 result(x,ivHeight-1) = ivData[x + (ivHeight-1)*ivWidth] - ivData[x + (ivHeight-2)*ivWidth];
00319 }
00320 for(int y = 1; y < ivHeight-1; ++y)
00321 for(int x = 0; x < ivWidth; ++x)
00322 result(x,y) = (ivData[x + (y+1)*ivWidth] - ivData[x + (y-1)*ivWidth]);
00323 }
00324
00326 void Matrix::scharrDerivativeX(Matrix& result) const
00327 {
00328 if(ivWidth * ivHeight == 0)return;
00329 Matrix tmp;
00330 this->derivativeX(tmp);
00331 result.setSize(ivWidth, ivHeight);
00332
00333 for(int x=0; x<ivWidth; ++x)
00334 {
00335 result(x,0) = 13 * tmp(x,0) + 3 * tmp(x,1);
00336 result(x,ivHeight-1) = 13 * tmp(x,ivHeight-1) + 3 * tmp(x,ivHeight-2);
00337 }
00338 for(int y = 1; y < ivHeight-1; ++y)
00339 for(int x = 0; x < ivWidth; ++x)
00340 result(x,y) = 3 * (tmp(x,y-1) + tmp(x,y+1)) + 10 * tmp(x,y);
00341
00342 }
00343
00345 void Matrix::scharrDerivativeY(Matrix& result) const
00346 {
00347 if(ivWidth * ivHeight == 0)return;
00348 Matrix tmp;
00349 this->derivativeY(tmp);
00350 result.setSize(ivWidth, ivHeight);
00351 for(int y = 0; y < ivHeight; ++y)
00352 {
00353 result(0,y) = 13 * tmp(0,y) + 3 * tmp(1,y);
00354 for(int x = 1; x < ivWidth-1; ++x)
00355 result(x,y) = 3 * (tmp(x-1,y) + tmp(x+1,y)) + 10 * tmp(x,y);
00356 result(ivWidth-1,y) = 13 * tmp(ivWidth-1,y) + 3 * tmp(ivWidth-2,y);
00357 }
00358 }
00359
00361 void Matrix::sobelDerivativeX(Matrix& result) const
00362 {
00363 if(ivWidth * ivHeight == 0)return;
00364 Matrix tmp;
00365 this->derivativeX(tmp);
00366 result.setSize(ivWidth, ivHeight);
00367
00368 for(int x=0; x<ivWidth; ++x)
00369 {
00370 result(x,0) = 3 * tmp(x,0) + 1 * tmp(x,1);
00371 result(x,ivHeight-1) = 3 * tmp(x,ivHeight-1) + 1 * tmp(x,ivHeight-2);
00372 for(int y = 1; y < ivHeight-1; ++y)
00373 result(x,y) = 1 * (tmp(x,y-1) + tmp(x,y+1)) + 2 * tmp(x,y);
00374 }
00375 }
00376
00378 void Matrix::sobelDerivativeY(Matrix& result) const
00379 {
00380 if(ivWidth * ivHeight == 0)return;
00381 Matrix tmp;
00382 this->derivativeY(tmp);
00383 result.setSize(ivWidth, ivHeight);
00384 for(int y=0; y<ivHeight; ++y)
00385 {
00386 result(0,y) = 3 * tmp(0,y) + 1 * tmp(1,y);
00387 result(ivWidth-1,y) = 3 * tmp(ivWidth-1,y) + 1 * tmp(ivWidth-2,y);
00388 for(int x = 1; x < ivWidth-1; ++x)
00389 result(x,y) = 1 * (tmp(x-1,y) + tmp(x+1,y)) + 2 * tmp(x,y);
00390 }
00391 }
00392
00393 void Matrix::gaussianSmooth(const float sigma, const int filterSize)
00394 {
00395 Matrix temp(ivWidth, ivHeight, 0);
00396 int fSize = filterSize > 0 ? filterSize : (sigma*6 + 1);
00397
00398 if (!(fSize%2))
00399 fSize++;
00400
00401 float* weights = new float[fSize];
00402 float sumWeights = 0;
00403 for (int i = 0; i < fSize; i++)
00404 {
00405 float x = (i - (fSize>>1));
00406 weights[i] = 1.0 / (sqrt(2*PI) * sigma) * exp(-x*x / (2*sigma*sigma));
00407 sumWeights += weights[i];
00408 }
00409
00410 for (int i = 0; i < fSize; i++)
00411 weights[i] *= 1.0 / sumWeights;
00412
00413
00414 for (int x = 0; x < ivWidth; x++)
00415 for (int i = 0; i < fSize; i++)
00416 {
00417 int xtemp = x + i - (fSize>>1);
00418 xtemp = xtemp < 0 ? 0 : (xtemp >= ivWidth ? ivWidth-1 : xtemp);
00419 for (int y = 0; y < ivHeight; y++)
00420 temp(x,y) += ivData[xtemp + y*ivWidth] * weights[i];
00421 }
00422
00423 fill(0);
00424 for (int y = 0; y < ivHeight; y++)
00425 for (int i = 0; i < fSize; i++)
00426 {
00427 int ytemp = y + i - (fSize>>1);
00428 ytemp = ytemp < 0 ? 0 : (ytemp >= ivHeight ? ivHeight-1 : ytemp);
00429 for (int x = 0; x < ivWidth; x++)
00430 ivData[x + y*ivWidth] += temp(x, ytemp) * weights[i];
00431 }
00432 delete [] weights;
00433 }
00434
00436
00437 void Matrix::halfSizeImage(Matrix& result) const
00438 {
00439
00440 Matrix temp((ivWidth+1)>>1, ivHeight);
00441 for (int y = 0; y < ivHeight; ++y)
00442 {
00443 temp(0,y) = 0.75 * ivData[0 + y*ivWidth] + 0.25 * ivData[1 + y*ivWidth];
00444 if (ivWidth%2)
00445 temp(ivWidth>>1,y) = 0.75 * ivData[ivWidth-1 + y*ivWidth] + 0.25 * ivData[ivWidth-2 + y*ivWidth];
00446 for (int x = 1; x < (ivWidth>>1); ++x)
00447 temp(x,y) = 0.5 * ivData[(x<<1) + y*ivWidth] + 0.25 * (ivData[(x<<1)-1 + y*ivWidth] + ivData[(x<<1)+1 + y*ivWidth]);
00448 }
00449
00450 result.setSize((ivWidth+1)>>1, (ivHeight+1)>>1);
00451 for (int x = 0; x < result.ivWidth; ++x)
00452 {
00453 result(x,0) = 0.75 * temp(x,0) + 0.25 * temp(x,1);
00454 if (ivHeight%2)
00455 result(x,ivHeight>>1) = 0.75 * temp(x,ivHeight-1) + 0.25 * temp(x,ivHeight-2);
00456 for (int y = 1; y < (ivHeight>>1); ++y)
00457 result(x,y) = 0.5 * temp(x,y<<1) + 0.25 * (temp(x,(y<<1)-1) + temp(x,(y<<1)+1));
00458 }
00459 }
00460
00461 void Matrix::writeToPGM(const char *filename) const
00462 {
00463 FILE *aStream;
00464 aStream = fopen(filename,"wb");
00465
00466 char line[60];
00467 sprintf(line,"P5\n%d %d\n255\n",ivWidth,ivHeight);
00468 fwrite(line,strlen(line),1,aStream);
00469
00470 for (int i = 0; i < ivWidth*ivHeight; i++) {
00471 char dummy = (char)ivData[i];
00472 fwrite(&dummy,1,1,aStream);
00473 }
00474 fclose(aStream);
00475 }
00476
00477 Matrix Matrix::getRectSubPix(float centerx, float centery, int width, int height) const
00478 {
00479 Matrix result(width, height);
00480 float cx = centerx - (width-1)*0.5f, cy = centery - (height-1)*0.5f;
00481 int srcx = floor(cx), srcy = floor(cy);
00482 float a = cx - srcx, b = cy - srcy,
00483 a11 = (1.f-a)*(1.f-b),
00484 a12 = a*(1.f-b),
00485 a21 = (1.f-a)*b,
00486 a22 = a*b;
00487 if(srcx >= 0 && srcy >= 0 && srcx+width < ivWidth && srcy+height < ivHeight)
00488 {
00489 for(int y=0; y<height; ++y)
00490 {
00491 for(int x=0; x<width; ++x)
00492 {
00493 result(x,y) = a11*operator()(srcx+x,srcy+y)
00494 + a12*operator()(srcx+x+1,srcy+y)
00495 + a21*operator()(srcx+x,srcy+y+1)
00496 + a22*operator()(srcx+x+1,srcy+y+1);
00497 }
00498 }
00499 }else{
00500 float avgValue = this->avg();
00501 for(int y=0; y<height; ++y)
00502 {
00503 for(int x=0; x<width; ++x)
00504 {
00505 if(srcx+x<0 || srcx+x+1>=ivWidth || srcy+y<0 || srcy+y+1>=ivHeight)
00506 result(x,y) = avgValue;
00507 else
00508 result(x,y) = a11*operator()(srcx+x,srcy+y)
00509 + a12*operator()(srcx+x+1,srcy+y)
00510 + a21*operator()(srcx+x,srcy+y+1)
00511 + a22*operator()(srcx+x+1,srcy+y+1);
00512
00513
00514
00515
00516
00517
00518 }
00519 }
00520 }
00521 return result;
00522 }
00523
00524 void Matrix::setSize(int width, int height)
00525 {
00526 if (ivWidth == width && ivHeight == height)
00527 return;
00528 if (ivData != 0)
00529 delete[] ivData;
00530 ivData = new float[width*height];
00531 ivWidth = width;
00532 ivHeight = height;
00533 }
00534
00535 void Matrix::downsample(int newWidth, int newHeight)
00536 {
00537
00538 int aIntermedSize = newWidth*ivHeight;
00539 float* aIntermedData = new float[aIntermedSize];
00540 if (newWidth < ivWidth) {
00541 for (int i = 0; i < aIntermedSize; i++)
00542 aIntermedData[i] = 0.0;
00543 float factor = ((float)ivWidth)/newWidth;
00544 for (int y = 0; y < ivHeight; y++) {
00545 int aFineOffset = y*ivWidth;
00546 int aCoarseOffset = y*newWidth;
00547 int i = aFineOffset;
00548 int j = aCoarseOffset;
00549 int aLastI = aFineOffset+ivWidth;
00550 int aLastJ = aCoarseOffset+newWidth;
00551 float rest = factor;
00552 float part = 1.0;
00553 do {
00554 if (rest > 1.0) {
00555 aIntermedData[j] += part*ivData[i];
00556 rest -= part;
00557 part = 1.0;
00558 i++;
00559 if (rest <= 0.0) {
00560 rest = factor;
00561 j++;
00562 }
00563 }
00564 else {
00565 aIntermedData[j] += rest*ivData[i];
00566 part = 1.0-rest;
00567 rest = factor;
00568 j++;
00569 }
00570 }
00571 while (i < aLastI && j < aLastJ);
00572 }
00573 }
00574 else {
00575 float* aTemp = aIntermedData;
00576 aIntermedData = ivData;
00577 ivData = aTemp;
00578 }
00579
00580 delete[] ivData;
00581 int aDataSize = newWidth*newHeight;
00582 ivData = new float[aDataSize];
00583 if (newHeight < ivHeight) {
00584 for (int i = 0; i < aDataSize; i++)
00585 ivData[i] = 0.0;
00586 float factor = ((float)ivHeight)/newHeight;
00587 for (int x = 0; x < newWidth; x++) {
00588 int i = x;
00589 int j = x;
00590 int aLastI = ivHeight*newWidth+x;
00591 int aLastJ = newHeight*newWidth+x;
00592 float rest = factor;
00593 float part = 1.0;
00594 do {
00595 if (rest > 1.0) {
00596 ivData[j] += part*aIntermedData[i];
00597 rest -= part;
00598 part = 1.0;
00599 i += newWidth;
00600 if (rest <= 0.0) {
00601 rest = factor;
00602 j += newWidth;
00603 }
00604 }
00605 else {
00606 ivData[j] += rest*aIntermedData[i];
00607 part = 1.0-rest;
00608 rest = factor;
00609 j += newWidth;
00610 }
00611 }
00612 while (i < aLastI && j < aLastJ);
00613 }
00614 }
00615 else {
00616 float* aTemp = ivData;
00617 ivData = aIntermedData;
00618 aIntermedData = aTemp;
00619 }
00620
00621 float aNormalization = ((float)aDataSize)/size();
00622 for (int i = 0; i < aDataSize; i++)
00623 ivData[i] *= aNormalization;
00624
00625 ivWidth = newWidth;
00626 ivHeight = newHeight;
00627 delete[] aIntermedData;
00628 }
00629
00630 void Matrix::downsampleBilinear(int newWidth, int newHeight)
00631 {
00632 int newSize = newWidth*newHeight;
00633 float* newData = new float[newSize];
00634 float factorX = ((float)ivWidth)/newWidth;
00635 float factorY = ((float)ivHeight)/newHeight;
00636 for (int y = 0; y < newHeight; y++)
00637 for (int x = 0; x < newWidth; x++) {
00638 float ax = (x+0.5)*factorX-0.5;
00639 float ay = (y+0.5)*factorY-0.5;
00640 if (ax < 0) ax = 0.0;
00641 if (ay < 0) ay = 0.0;
00642 int x1 = (int)ax;
00643 int y1 = (int)ay;
00644 int x2 = x1+1;
00645 int y2 = y1+1;
00646 float alphaX = ax-x1;
00647 float alphaY = ay-y1;
00648 if (x1 < 0) x1 = 0;
00649 if (y1 < 0) y1 = 0;
00650 if (x2 >= ivWidth) x2 = ivWidth-1;
00651 if (y2 >= ivHeight) y2 = ivHeight-1;
00652 float a = (1.0-alphaX)*ivData[x1+y1*ivWidth]+alphaX*ivData[x2+y1*ivWidth];
00653 float b = (1.0-alphaX)*ivData[x1+y2*ivWidth]+alphaX*ivData[x2+y2*ivWidth];
00654 newData[x+y*newWidth] = (1.0-alphaY)*a+alphaY*b;
00655 }
00656 delete[] ivData;
00657 ivData = newData;
00658 ivWidth = newWidth;
00659 ivHeight = newHeight;
00660 }
00661
00662 void Matrix::upsample(int newWidth, int newHeight)
00663 {
00664
00665 int aIntermedSize = newWidth*ivHeight;
00666 float* aIntermedData = new float[aIntermedSize];
00667 if (newWidth > ivWidth) {
00668 for (int i = 0; i < aIntermedSize; i++)
00669 aIntermedData[i] = 0.0;
00670 float factor = ((float)newWidth)/ivWidth;
00671 for (int y = 0; y < ivHeight; y++) {
00672 int aFineOffset = y*newWidth;
00673 int aCoarseOffset = y*ivWidth;
00674 int i = aCoarseOffset;
00675 int j = aFineOffset;
00676 int aLastI = aCoarseOffset+ivWidth;
00677 int aLastJ = aFineOffset+newWidth;
00678 float rest = factor;
00679 float part = 1.0;
00680 do {
00681 if (rest > 1.0) {
00682 aIntermedData[j] += part*ivData[i];
00683 rest -= part;
00684 part = 1.0;
00685 j++;
00686 if (rest <= 0.0) {
00687 rest = factor;
00688 i++;
00689 }
00690 }
00691 else {
00692 aIntermedData[j] += rest*ivData[i];
00693 part = 1.0-rest;
00694 rest = factor;
00695 i++;
00696 }
00697 }
00698 while (i < aLastI && j < aLastJ);
00699 }
00700 }
00701 else {
00702 float* aTemp = aIntermedData;
00703 aIntermedData = ivData;
00704 ivData = aTemp;
00705 }
00706
00707 delete[] ivData;
00708 int aDataSize = newWidth*newHeight;
00709 ivData = new float[aDataSize];
00710 if (newHeight > ivHeight) {
00711 for (int i = 0; i < aDataSize; i++)
00712 ivData[i] = 0.0;
00713 float factor = ((float)newHeight)/ivHeight;
00714 for (int x = 0; x < newWidth; x++) {
00715 int i = x;
00716 int j = x;
00717 int aLastI = ivHeight*newWidth;
00718 int aLastJ = newHeight*newWidth;
00719 float rest = factor;
00720 float part = 1.0;
00721 do {
00722 if (rest > 1.0) {
00723 ivData[j] += part*aIntermedData[i];
00724 rest -= part;
00725 part = 1.0;
00726 j += newWidth;
00727 if (rest <= 0.0) {
00728 rest = factor;
00729 i += newWidth;
00730 }
00731 }
00732 else {
00733 ivData[j] += rest*aIntermedData[i];
00734 part = 1.0-rest;
00735 rest = factor;
00736 i += newWidth;
00737 }
00738 }
00739 while (i < aLastI && j < aLastJ);
00740 }
00741 }
00742 else {
00743 float* aTemp = ivData;
00744 ivData = aIntermedData;
00745 aIntermedData = aTemp;
00746 }
00747
00748 ivWidth = newWidth;
00749 ivHeight = newHeight;
00750 delete[] aIntermedData;
00751 }
00752
00753 void Matrix::upsampleBilinear(int newWidth, int newHeight)
00754 {
00755 int newSize = newWidth*newHeight;
00756 float* newData = new float[newSize];
00757 float factorX = (float)(ivWidth)/(newWidth);
00758 float factorY = (float)(ivHeight)/(newHeight);
00759 for (int y = 0; y < newHeight; y++)
00760 for (int x = 0; x < newWidth; x++) {
00761 float ax = (x+0.5)*factorX-0.5;
00762 float ay = (y+0.5)*factorY-0.5;
00763 if (ax < 0) ax = 0.0;
00764 if (ay < 0) ay = 0.0;
00765 int x1 = (int)ax;
00766 int y1 = (int)ay;
00767 int x2 = x1+1;
00768 int y2 = y1+1;
00769 float alphaX = ax-x1;
00770 float alphaY = ay-y1;
00771 if (x1 < 0) x1 = 0;
00772 if (y1 < 0) y1 = 0;
00773 if (x2 >= ivWidth) x2 = ivWidth-1;
00774 if (y2 >= ivHeight) y2 = ivHeight-1;
00775 float a = (1.0-alphaX)*ivData[x1+y1*ivWidth]+alphaX*ivData[x2+y1*ivWidth];
00776 float b = (1.0-alphaX)*ivData[x1+y2*ivWidth]+alphaX*ivData[x2+y2*ivWidth];
00777 newData[x+y*newWidth] = (1.0-alphaY)*a+alphaY*b;
00778 }
00779 delete[] ivData;
00780 ivData = newData;
00781 ivWidth = newWidth;
00782 ivHeight = newHeight;
00783 }
00784
00785 void Matrix::rescale(int newWidth, int newHeight)
00786 {
00787 if (ivWidth >= newWidth) {
00788 if (ivHeight >= newHeight)
00789 downsample(newWidth,newHeight);
00790 else {
00791 downsample(newWidth,ivHeight);
00792 upsample(newWidth,newHeight);
00793 }
00794 }
00795 else {
00796 if (ivHeight >= newHeight) {
00797 downsample(ivWidth,newHeight);
00798 upsample(newWidth,newHeight);
00799 }
00800 else
00801 upsample(newWidth,newHeight);
00802 }
00803 }
00804
00805 void Matrix::fill(const float value)
00806 {
00807 int wholeSize = ivWidth*ivHeight;
00808 for (register int i = 0; i < wholeSize; i++)
00809 ivData[i] = value;
00810 }
00811
00812 void Matrix::cut(Matrix& result,const int x1, const int y1, const int x2, const int y2)
00813 {
00814 result.ivWidth = x2-x1+1;
00815 result.ivHeight = y2-y1+1;
00816 delete[] result.ivData;
00817 result.ivData = new float[result.ivWidth*result.ivHeight];
00818 for (int y = y1; y <= y2; y++)
00819 for (int x = x1; x <= x2; x++)
00820 result(x-x1,y-y1) = operator()(x,y);
00821 }
00822
00823 void Matrix::clip(float aMin, float aMax)
00824 {
00825 int aSize = size();
00826 for (int i = 0; i < aSize; i++)
00827 if (ivData[i] < aMin)
00828 ivData[i] = aMin;
00829 else if (ivData[i] > aMax)
00830 ivData[i] = aMax;
00831 }
00832
00833 void Matrix::inv3()
00834 {
00835 if (ivWidth != ivHeight || ivWidth != 3) {
00836 std::cerr << "cannot invert non 3x3 matrices!" << std::endl;
00837 return;
00838 }
00839
00840 float a,b,c,d,e,f,g,h,k;
00841 a = ivData[0]; b = ivData[3]; c = ivData[6];
00842 d = ivData[1]; e = ivData[4]; f = ivData[7];
00843 g = ivData[2]; h = ivData[5]; k = ivData[8];
00844
00845 float A = e*k - f*h;
00846 float B = f*g - d*k;
00847 float C = d*h - e*g;
00848 float D = c*h - b*k;
00849 float E = a*k - c*g;
00850 float F = g*b - a*h;
00851 float G = b*f - c*e;
00852 float H = c*d - a*f;
00853 float K = a*e - b*d;
00854
00855 float det = a*A + b*B + c*C;
00856
00857 ivData[0] = A/det; ivData[3] = D/det; ivData[6] = G/det;
00858 ivData[1] = B/det; ivData[4] = E/det; ivData[7] = H/det;
00859 ivData[2] = C/det; ivData[5] = F/det; ivData[8] = K/det;
00860
00861 }
00862
00863 void Matrix::drawLine(int x1, int y1, int x2, int y2, float value)
00864 {
00865
00866 if (x1 == x2)
00867 {
00868 if (x1 < 0 || x1 >= ivWidth)
00869 return;
00870 int x = x1;
00871 if (y1 < y2)
00872 {
00873 for (int y = y1; y <= y2; y++)
00874 if (y >= 0 && y < ivHeight)
00875 ivData[y*ivWidth + x] = value;
00876 } else {
00877 for (int y = y1; y >= y2; y--)
00878 if (y >= 0 && y < ivHeight)
00879 ivData[y*ivWidth + x] = value;
00880 }
00881 return;
00882 }
00883
00884 if (y1 == y2)
00885 {
00886 if (y1 < 0 || y1 >= ivHeight)
00887 return;
00888 int y = y1;
00889 if (x1 < x2)
00890 {
00891 for (int x = x1; x <= x2; x++)
00892 if (x >= 0 && x < ivWidth)
00893 ivData[y*ivWidth + x] = value;
00894 } else {
00895 for (int x = x1; x >= x2; x--)
00896 if (x >= 0 && x < ivWidth)
00897 ivData[y*ivWidth + x] = value;
00898 }
00899 return;
00900 }
00901 float m = float(y1 - y2) / float(x1 - x2);
00902 float invm = 1.0/m;
00903 if (fabs(m) > 1.0)
00904 {
00905 if (y2 > y1)
00906 {
00907 for (int y = y1; y <= y2; y++)
00908 {
00909 int x = (int)(0.5 + x1 + (y-y1)*invm);
00910 if (x >= 0 && x < ivWidth && y >= 0 && y < ivHeight)
00911 ivData[y*ivWidth + x] = value;
00912 }
00913 } else {
00914 for (int y = y1; y >= y2; y--)
00915 {
00916 int x = (int)(0.5 + x1 + (y-y1)*invm);
00917 if (x >= 0 && x < ivWidth && y >= 0 && y < ivHeight)
00918 ivData[y*ivWidth + x] = value;
00919 }
00920 }
00921 } else {
00922 if (x2 > x1)
00923 {
00924 for (int x = x1; x <= x2; x++)
00925 {
00926 int y = (int)(0.5 + y1 + (x-x1)*m);
00927 if (x >= 0 && x < ivWidth && y >= 0 && y < ivHeight)
00928 ivData[y*ivWidth + x] = value;
00929 }
00930 } else {
00931 for (int x = x1; x >= x2; x--)
00932 {
00933 int y = (int)(0.5 + y1 + (x-x1)*m);
00934 if (x >= 0 && x < ivWidth && y >= 0 && y < ivHeight)
00935 ivData[y*ivWidth + x] = value;
00936 }
00937 }
00938 }
00939 }
00940
00941 void Matrix::drawCross(int x, int y, int value, int crossSize)
00942 {
00943 if(x > crossSize && y > crossSize && x < ivWidth-crossSize && y < ivHeight-crossSize)
00944 for (int dx = -crossSize; dx <= crossSize; ++dx)
00945 {
00946 int oy = (y+dx)*ivWidth;
00947 ivData[oy+x+dx] = value;
00948 ivData[oy+x-dx] = value;
00949 }
00950 }
00951
00952 void Matrix::drawBox(ObjectBox b, int value)
00953 {
00954 int x1 = round(b.x), x2 = round(b.x + b.width),
00955 y1 = round(b.y), y2 = round(b.y + b.height);
00956 if(x2 < 0 || y2 < 0 || x1 >= ivWidth || y1 >= ivHeight)
00957 return;
00958 if(y1 >= 0)
00959 for(int i = y1 * ivWidth + std::max(0, x1);
00960 i < y1 * ivWidth + std::min(ivWidth, x2); ++i)
00961 ivData[i] = value;
00962 if(y2 < ivHeight)
00963 for(int i = y2 * ivWidth + std::max(0, x1);
00964 i < y2 * ivWidth + std::min(ivWidth, x2); ++i)
00965 ivData[i] = value;
00966 if(x1 >= 0)
00967 for(int i = std::max(0, y1) * ivWidth + x1;
00968 i < std::min(ivHeight, y2) * ivWidth + x1; i += ivWidth)
00969 ivData[i] = value;
00970 if(x2 < ivWidth)
00971 for(int i = std::max(0, y1) * ivWidth + x2;
00972 i < std::min(ivHeight, y2) * ivWidth + x2; i += ivWidth)
00973 ivData[i] = value;
00974 }
00975
00976 void Matrix::drawDashedBox(ObjectBox b, int value, int dashLength, bool dotted)
00977 {
00978 int x1 = round(b.x), x2 = round(b.x + b.width),
00979 y1 = round(b.y), y2 = round(b.y + b.height);
00980 if(x2 < 0 || y2 < 0 || x1 >= ivWidth || y1 >= ivHeight)
00981 return;
00982 for (int dx = 0; dx < b.width; ++dx)
00983 {
00984 int i1 = y1 * ivWidth + x1 + dx;
00985 int i2 = y2 * ivWidth + x1 + dx;
00986 if (0 <= i1 && i1 < ivWidth * ivHeight && ((dx%dashLength)>0)^dotted)
00987 ivData[i1] = value;
00988 if (0 <= i2 && i2 < ivWidth * ivHeight && ((dx%dashLength)>0)^dotted)
00989 ivData[i2] = value;
00990 }
00991 for (int dy = 0; dy < b.height; ++dy)
00992 {
00993 int i1 = (y1 + dy) * ivWidth + x1;
00994 int i2 = (y1 + dy) * ivWidth + x2;
00995 if (0 <= i1 && i1 < ivWidth * ivHeight && ((dy%dashLength)>0)^dotted)
00996 ivData[i1] = value;
00997 if (0 <= i2 && i2 < ivWidth * ivHeight && ((dy%dashLength)>0)^dotted)
00998 ivData[i2] = value;
00999 }
01000 }
01001
01002 void Matrix::drawPatch(const Matrix& b, int x, int y, float avg)
01003 {
01004 for (int dx = 0; dx < b.ivWidth; ++dx)
01005 for (int dy = 0; dy < b.ivHeight; ++ dy)
01006 (*this)(x+dx,y+dy) = b(dx,dy) + avg;
01007 }
01008
01009 void Matrix::drawHistogram(const float * histogram, int x, int y, int value, int nbins, int psize)
01010 {
01011 int binwidth = nbins > (psize>>1) ? 1 : 2;
01012 if(histogram == NULL)
01013 return;
01014 for (int n = 0; n < nbins; ++n)
01015 {
01016 int binheight = std::min(psize, std::max(0, (int)round(histogram[n] * psize)));
01017 for(int ix = 0; ix < binwidth; ++ix)
01018 for(int iy = 0; iy < binheight; ++iy)
01019 (*this)(x+ix+n*binwidth, y+psize-1-iy) = value;
01020 }
01021 }
01022
01023 void Matrix::drawNumber(int x, int y, int n, int value)
01024 {
01025 bool chars[10][4*7] = {
01026 {0,1,1,0, 1,0,0,1, 1,0,0,1, 1,0,0,1, 1,0,0,1, 1,0,0,1, 0,1,1,0},
01027 {0,1,1,0, 0,0,1,0, 0,0,1,0, 0,0,1,0, 0,0,1,0, 0,0,1,0, 0,1,1,1},
01028 {0,1,1,0, 1,0,0,1, 0,0,0,1, 0,0,1,0, 0,1,0,0, 1,0,0,0, 1,1,1,1},
01029 {0,1,1,0, 1,0,0,1, 0,0,0,1, 0,1,1,0, 0,0,0,1, 1,0,0,1, 1,1,1,0},
01030 {0,0,1,0, 0,1,1,0, 1,0,1,0, 1,0,1,0, 1,1,1,1, 0,0,1,0, 0,0,1,0},
01031 {1,1,1,1, 1,0,0,0, 1,0,0,0, 1,1,1,0, 0,0,0,1, 0,0,0,1, 1,1,1,0},
01032 {0,1,1,1, 1,1,0,0, 1,0,0,0, 1,1,1,0, 1,0,0,1, 1,0,0,1, 0,1,1,0},
01033 {1,1,1,1, 0,0,0,1, 0,0,0,1, 0,0,1,0, 0,0,1,0, 0,1,0,0, 0,1,0,0},
01034 {0,1,1,0, 1,0,0,1, 1,0,0,1, 0,1,1,0, 1,0,0,1, 1,0,0,1, 0,1,1,0},
01035 {0,1,1,0, 1,0,0,1, 1,0,0,1, 0,1,1,1, 0,0,0,1, 0,0,1,1, 1,1,1,0}};
01036 int a = abs(n), tx = -4;
01037 do {
01038
01039 int c = a%10;
01040 for (int i = 0; i < 4*7; i++)
01041 if (chars[c][i])
01042 {
01043 int tmpx = x + tx + (i%4), tmpy = y + (i>>2);
01044 if (tmpx >= 0 && tmpy >= 0 && tmpx < ivWidth && tmpy < ivHeight)
01045 (*this)(tmpx, tmpy) = value;
01046 }
01047 tx -= 5;
01048 a = a/10;
01049 } while(a > 0);
01050 if (n < 0)
01051
01052 for (int i = 1; i < 4; i++){
01053 int tmpx = x + tx + i, tmpy = y + 3;
01054 if (tmpx >= 0 && tmpy >= 0 && tmpx < ivWidth && tmpy < ivHeight)
01055 (*this)(tmpx, tmpy) = value;
01056 }
01057 }
01058
01059 inline float& Matrix::operator()(const int ax, const int ay) const
01060 {
01061 #ifdef _DEBUG
01062 if (ax >= ivWidth || ay >= ivHeight || ax < 0 || ay < 0){
01063 std::cerr << "Exception EMatrixRangeOverflow: x = " << ax << ", y = " << ay << std::endl;
01064 return 0;
01065 }
01066 #endif
01067 return ivData[ivWidth*ay+ax];
01068 }
01069
01070 inline Matrix& Matrix::operator=(const float value)
01071 {
01072 fill(value);
01073 return *this;
01074 }
01075
01076 Matrix& Matrix::operator=(const Matrix& copyFrom)
01077 {
01078 if (this != ©From) {
01079 if (ivData != 0) delete[] ivData;
01080 ivWidth = copyFrom.ivWidth;
01081 ivHeight = copyFrom.ivHeight;
01082 if (copyFrom.ivData == 0) ivData = 0;
01083 else {
01084 int wholeSize = ivWidth*ivHeight;
01085 ivData = new float[wholeSize];
01086 memcpy(ivData, copyFrom.ivData, wholeSize * sizeof(float));
01087
01088
01089 }
01090 }
01091 return *this;
01092 }
01093
01094 Matrix& Matrix::operator+=(const float value)
01095 {
01096 int wholeSize = ivWidth*ivHeight;
01097 for (int i = 0; i < wholeSize; i++)
01098 ivData[i] += value;
01099 return *this;
01100 }
01101
01102 Matrix& Matrix::operator*=(const float value)
01103 {
01104 int wholeSize = ivWidth*ivHeight;
01105 for (int i = 0; i < wholeSize; i++)
01106 ivData[i] *= value;
01107 return *this;
01108 }
01109
01110 float Matrix::avg() const
01111 {
01112 float aAvg = 0;
01113 int aSize = ivWidth*ivHeight;
01114 for (int i = 0; i < aSize; i++)
01115 aAvg += ivData[i];
01116 return aAvg/aSize;
01117 }
01118
01119 float Matrix::norm2() const
01120 {
01121 double sqSum = 0;
01122 int aSize = ivWidth*ivHeight;
01123 for (int i = 0; i < aSize; i++)
01124 sqSum += ivData[i]*ivData[i];
01125 return sqSum;
01126 }
01127
01128 inline int Matrix::xSize() const {
01129 return ivWidth;
01130 }
01131
01132 inline int Matrix::ySize() const {
01133 return ivHeight;
01134 }
01135
01136 inline int Matrix::size() const {
01137 return ivWidth*ivHeight;
01138 }
01139
01140 inline float* Matrix::data() const {
01141 return ivData;
01142 }
01143
01144 Matrix operator*(const Matrix& m1, const Matrix& m2) {
01145 if (m1.xSize() != m2.ySize()){
01146 std::cerr << "cannot multiply incompatible matrices!" << std::endl;
01147 return Matrix();
01148 }
01149
01150 Matrix result(m2.xSize(),m1.ySize(),0);
01151 for (int y = 0; y < result.ySize(); y++)
01152 for (int x = 0; x < result.xSize(); x++)
01153 for (int i = 0; i < m1.xSize(); i++)
01154 result(x,y) += m1(i,y)*m2(x,i);
01155 return result;
01156 }
01157
01158 void writePPM(const char* filename, const Matrix& rMatrix, const Matrix& gMatrix, const Matrix& bMatrix)
01159 {
01160 FILE* outimage = fopen(filename, "wb");
01161 int width = rMatrix.xSize(), height = rMatrix.ySize();
01162 fprintf(outimage, "P6 \n");
01163 fprintf(outimage, "%d %d \n255\n", width, height);
01164 for (int y = 0; y < height; y++)
01165 for (int x = 0; x < width; x++)
01166 {
01167 unsigned char tmp = (unsigned char)rMatrix(x,y);
01168 fwrite (&tmp, sizeof(unsigned char), 1, outimage);
01169 tmp = (unsigned char)gMatrix(x,y);
01170 fwrite (&tmp, sizeof(unsigned char), 1, outimage);
01171 tmp = (unsigned char)bMatrix(x,y);
01172 fwrite (&tmp, sizeof(unsigned char), 1, outimage);
01173 }
01174 fclose(outimage);
01175 }
01176
01177
01178
01179
01180
01181 inline float* Matrix::createSummedAreaTable() const
01182 {
01183 int width = ivWidth + 1;
01184 int height = ivHeight + 1;
01185
01186 float* sat = new float[width*height];
01187
01188 for (int x = 0; x < width; ++x)
01189 sat[x] = 0;
01190
01191 int n = 0;
01192 for (int y = 1; y < height; ++y)
01193 {
01194 int yoffset = y * width;
01195 sat[yoffset] = 0;
01196 for (int x = 1; x < width; ++x, ++n)
01197 {
01198 int offset = yoffset + x;
01199 sat[offset] = ivData[n] + sat[offset-1] + sat[offset-width] - sat[offset-width-1];
01200 }
01201 }
01202
01203 return sat;
01204 }
01205
01206 inline float** Matrix::createSummedAreaTable2() const
01207 {
01208 int width = ivWidth + 1;
01209 int height = ivHeight + 1;
01210
01211 float* sat = new float[width*height];
01212 float* sat2 = new float[width*height];
01213
01214 for (int x = 0; x < width; ++x)
01215 sat[x] = sat2[x] = 0;
01216
01217 int n = 0;
01218 for (int y = 1; y < height; ++y)
01219 {
01220 int yoffset = y * width;
01221 sat[yoffset] = sat2[yoffset] = 0;
01222 for (int x = 1; x < width; ++x, ++n)
01223 {
01224 int offset = yoffset + x;
01225 sat[offset] = ivData[n] + sat[offset-1] + sat[offset-width] - sat[offset-width-1];
01226 sat2[offset] = ivData[n]*ivData[n] + sat2[offset-1] + sat2[offset-width] - sat2[offset-width-1];
01227 }
01228 }
01229
01230 float** result = new float*[2];
01231 result[0] = sat;
01232 result[1] = sat2;
01233 return result;
01234 }
01235
01236 inline double summedTableArea(float* sat, int width, int x1, int y1, int x2, int y2)
01237 {
01238 ++width; ++x2; ++y2;
01239 return sat[y2*width+x2] - sat[y1*width+x2] - sat[y2*width+x1] + sat[y1*width+x1];
01240 }
01241
01242 inline double summedTableArea(const float * const sat, int * indices)
01243 {
01244 return sat[indices[0]] - sat[indices[1]] - sat[indices[2]] + sat[indices[3]];
01245 }
01246
01247 inline int* getSATIndices(int width, int x1, int y1, int x2, int y2)
01248 {
01249 ++width; ++x2; ++y2;
01250 int* result = new int[4];
01251 result[0] = y2*width+x2;
01252 result[1] = y1*width+x2;
01253 result[2] = y2*width+x1;
01254 result[3] = y1*width+x1;
01255 return result;
01256 }
01257
01258 inline void getSATIndices(int * array, int width, int x1, int y1, int x2, int y2)
01259 {
01260 ++width; ++x2; ++y2;
01261 array[0] = y2*width+x2;
01262 array[1] = y1*width+x2;
01263 array[2] = y2*width+x1;
01264 array[3] = y1*width+x1;
01265 }
01266
01267 inline int* getSATIndices(int width, int boxw, int boxh)
01268 {
01269 return getSATIndices(width,0,0,boxw-1,boxh-1);
01270 }
01271
01272
01273
01274
01275
01276 inline Matrix Matrix::affineWarp(const Matrix& t, const ObjectBox& b, const bool& preservear) const
01277 {
01278 float widthHalf = b.width / 2;
01279 float heightHalf = b.height / 2;
01280
01281
01282 Matrix ost(3,3);
01283 ost.ivData[0] = 1; ost.ivData[1] = 0; ost.ivData[2] = b.x + widthHalf - 0.5;
01284 ost.ivData[3] = 0; ost.ivData[4] = 1; ost.ivData[5] = b.y + heightHalf - 0.5;
01285 ost.ivData[6] = 0; ost.ivData[7] = 0; ost.ivData[8] = 1;
01286
01287 Matrix ostinv = ost;
01288 ostinv.ivData[2] = - ostinv.ivData[2];
01289 ostinv.ivData[5] = - ostinv.ivData[5];
01290 Matrix tinv = t; tinv.inv3();
01291
01292 Matrix trans = ost * tinv * ostinv;
01293
01294 Matrix result(b.width, b.height);
01295 for (int dx = 0; dx <= b.width-1; ++dx)
01296 {
01297 for (int dy = 0; dy <= b.height-1; ++dy)
01298 {
01299 Matrix v(1,3);
01300 float x = b.x + dx;
01301 float y = b.y + dy;
01302 v.ivData[0] = x; v.ivData[1] = y; v.ivData[2] = 1;
01303 v = trans * v;
01304
01305 int x1 = MAX(0,MIN(ivWidth-1,floor(v.ivData[0]))); int x2 = MAX(0,MIN(ivWidth-1,ceil(v.ivData[0])));
01306 int y1 = MAX(0,MIN(ivHeight-1,floor(v.ivData[1]))); int y2 = MAX(0,MIN(ivHeight-1,ceil(v.ivData[1])));
01307 double dx1 = v.ivData[0] - x1; double dy1 = v.ivData[1] - y1;
01308
01309 result(dx, dy) =
01310 (1-dx1) * ((1-dy1) * (*this)(x1, y1) + dy1 * (*this)(x1,y2))
01311 + dx1 * ((1-dy1) * (*this)(x2, y1) + dy1 * (*this)(x2,y2));
01312 }
01313 }
01314 return result;
01315 }
01316
01317 inline Matrix Matrix::createWarpMatrix(const float& angle, const float& scale)
01318 {
01319 Matrix scm(3,3);
01320 scm(0, 0) = scale; scm(1, 0) = 0; scm(2, 0) = 0;
01321 scm(0, 1) = 0; scm(1, 1) = scale; scm(2, 1) = 0;
01322 scm(0, 2) = 0; scm(1, 2) = 0; scm(2, 2) = 1;
01323 Matrix anm(3,3);
01324 float ca = cos(angle); float sa = sin(angle);
01325 anm(0, 0) = ca; anm(1, 0) = sa; anm(2, 0) = 0;
01326 anm(0, 1) = -sa; anm(1, 1) = ca; anm(2, 1) = 0;
01327 anm(0, 2) = 0; anm(1, 2) = 0; anm(2, 2) = 1;
01328 Matrix wm = anm * scm;
01329 return wm;
01330 }
01331
01332
01333
01334
01335
01336 inline float rectangleOverlap( float minx1, float miny1,
01337 float maxx1, float maxy1, float minx2, float miny2,
01338 float maxx2, float maxy2 )
01339 {
01340 if (minx1 > maxx2 || maxx1 < minx2 || miny1 > maxy2 || maxy1 < miny2)
01341 {
01342 return 0.0f;
01343 }
01344 else
01345 {
01346 float dx = MIN(maxx2, maxx1)-MAX(minx2, minx1);
01347 float dy = MIN(maxy2, maxy1)-MAX(miny2, miny1);
01348 float area1 = (maxx1-minx1)*(maxy1-miny1);
01349 float area2 = (maxx2-minx2)*(maxy2-miny2);
01350 float avgarea = 0.5 * (area1+area2);
01351 float overlaparea = dx*dy;
01352 return overlaparea/avgarea;
01353 }
01354 }
01355
01356 inline float rectangleOverlap(const ObjectBox& a, const ObjectBox& b)
01357 {
01358 return rectangleOverlap(a.x, a.y, a.x+a.width, a.y+a.height,
01359 b.x, b.y, b.x+b.width, b.y+b.height );
01360 }
01361
01362 }
01363
01364 #endif