matrix.cpp
来自「在人脸检测的基础之上,对嘴部的运动表情进行分析,进行语音模拟.」· C++ 代码 · 共 598 行
CPP
598 行
// Matrix.cpp: implementation of the Matrix class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "windows.h"
#include "stdio.h"
#include "FnMatrix.h"
#include "Matrix.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
//------------ MEMBERS OF CLASS matrix-----------------
matrix::matrix()
{
ysize = 0;
xsize = 0;
numbands = 1;
elem = NULL;
rowptr = NULL;
}
//---------------------------------------------------------
matrix::matrix(const matrix& a)
{
ysize = 0;
xsize = 0;
elem = NULL;
rowptr = NULL;
numbands = 1;
*this = a;
}
//-------------------------------------------------------------
matrix::matrix(int k, int l, int n)
{
// k = number of rows, l = number of columns,
// n = number of bands
ASSERT( n > 0 && k >= 0 && l >= 0 );
numbands = n;
ysize = k;
xsize = l;
if( ysize == 0)
{
xsize = 0;
elem = NULL;
rowptr = NULL;
}
else if( xsize == 0)
{
ysize = 0;
elem = NULL;
rowptr = NULL;
}
else
{
rowptr = new double* [ysize*numbands];
elem = new double [ysize*xsize*numbands];
ASSERT(elem != NULL && rowptr != NULL);
int i;
for(i = 0; i < ysize*numbands; i++)
rowptr[i]= elem + i*xsize;
for(i = 0; i < ysize*xsize*numbands; i++)
{
elem[i] = 0.0;
}
}
}
//-------------------------------------------------------------
matrix::~matrix()
{
if ((ysize !=0) && (xsize!=0))
{
delete[] elem;
delete[] rowptr;
}
}
//-------------------------------------------------------------
double& matrix::operator()(int k, int l, int n)
{
ASSERT( k >= 0 && k < ysize && l >= 0 && l < xsize && n >= 0);
return(*(rowptr[n*ysize+k]+l));
}
//-------------------------------------------------------------
double& matrix::operator()(int k)
{
ASSERT( xsize == 1 && ysize > 0 || ysize == 1 && xsize > 0);
return(*(elem+k));
}
//-------------------------------------------------------------
double* matrix::operator[](int k)
{
ASSERT( k >= 0 && k < ysize*numbands);
return rowptr[k];
}
//-------------------------------------------------------------
matrix& matrix::operator=(const matrix& a)
{
int i;
if ((ysize != a.ysize) || (xsize != a.xsize) || (numbands != a.numbands))
{
if( ysize !=0)
{
delete[] elem;
delete[] rowptr;
}
ysize=a.ysize;
xsize=a.xsize;
numbands = a.numbands;
if( ysize == 0)
{
elem = NULL;
rowptr = NULL;
}
else
{
rowptr=new double* [ysize*numbands];
elem=new double [ysize*xsize*numbands];
ASSERT(elem != NULL && rowptr != NULL);
}
}
if (ysize !=0)
{
register double *t1, *t2;
for(i=0; i < ysize * numbands ;i++)
{
rowptr[i] = elem + i*xsize;
}
for(i = 0, t1 = elem, t2 = a.elem; i < ysize*xsize*numbands; i++)
{
*t1++ = *t2++;
}
}
return *this;
}
//-------------------------------------------------------------
matrix& matrix::operator += (const matrix& y)
{
ASSERT((ysize == y.ysize) && (xsize == y.xsize) && (numbands == y.numbands));
for (int i=0; i < ysize*xsize*numbands; i++)
elem[i] += y.elem[i];
return *this;
}
//-------------------------------------------------------------
matrix& matrix::operator -= (const matrix& y)
{
ASSERT((ysize == y.ysize) && (xsize == y.xsize) && (numbands == y.numbands));
for (int i=0; i < ysize*xsize*numbands; i++)
elem[i] -= y.elem[i];
return *this;
}
//-------------------------------------------------------------
matrix& matrix::operator += (double a)
{
ASSERT( ysize > 0 );
for (int i=0; i < ysize * xsize * numbands; i++)
elem[i] += a;
return *this;
}
//-------------------------------------------------------------
matrix& matrix::operator -= (double a)
{
ASSERT( ysize > 0 );
for (int i=0; i < ysize * xsize * numbands; i++)
elem[i] -= a;
return *this;
}
//-------------------------------------------------------------
matrix& matrix::operator *= (double a)
{
for (int i=0; i < ysize * xsize * numbands; i++)
elem[i] *= a;
return *this;
}
//-------------------------------------------------------------
matrix& matrix::operator /= (double a)
{
ASSERT( a != 0.0);
for (int i=0; i < ysize*xsize*numbands; i++)
elem[i] /= a;
return *this;
}
//-------------------------------------------------------------
void matrix::pstr(const matrix& a, int k)
//paste a vector a to k'th row
//vector may be smaller or longer than row size
{
ASSERT( a.xsize == 1 || a.ysize == 1 );
ASSERT( k < ysize);
ASSERT( numbands == 1);
int i, len=(a.ysize > a.xsize) ? a.ysize : a.xsize;
if (len > xsize) len=xsize;
register double *t1, *t2;
for(i=0,t1=rowptr[k],t2=a.elem;i<len;i++)
*t1++=*t2++;
}
//-------------------------------------------------------------
void matrix::pstc(const matrix& a, int k)
//paste a vector to k'th column
//vector may be smaller or longer than column size
{
ASSERT( a.xsize == 1 || a.ysize == 1);
ASSERT( k < xsize);
ASSERT( numbands == 1);
int len=(a.ysize > a.xsize) ? a.ysize : a.xsize;
if (len > ysize) len=ysize;
register double *t1, *t2;
int i;
for(i=0,t1=elem+k,t2=a.elem;i<len;i++,t1+=xsize) *t1=*t2++;
}
//-------------------------------------------------------------
void matrix::resize(int y, int x, int n)
{
// if n = 0 fills the new pixels with 0
// if n = 1 fills the new pixel by repeating the boundary value
int i, j, empty;
matrix temp;
ASSERT( n == 0 || n == 1);
if ((ysize != y) || (xsize != x))
{
if( y == 0)
{
delete[] elem;
delete[] rowptr;
elem = NULL;
rowptr = NULL;
xsize = 0;
ysize = 0;
numbands = 1;
}
else
{
if (ysize != 0)
{
empty = 0;
temp = zeros(ysize, xsize, numbands);
for (j = 0; j < ysize * numbands; ++j)
for (i = 0; i < xsize; ++i)
temp.rowptr[j][i] = rowptr[j][i];
delete[] elem;
delete[] rowptr;
}
else
empty = 1;
ysize = y;
xsize = x;
rowptr = new double* [ysize * numbands];
elem = new double [ysize * xsize * numbands];
ASSERT(elem != NULL && rowptr != NULL);
for(j = 0; j < ysize * numbands; j++)
rowptr[j]= elem + j * xsize;
if (!empty)
{
int xsi = (temp.xsize < xsize ) ? temp.xsize : xsize;
int ysi = (temp.ysize < ysize ) ? temp.ysize : ysize;
for ( int u = 0; u < numbands; u++)
{
int offset_new = u * ysize;
int offset_old = u * temp.ysize;
for ( j = 0; j < ysi; ++j)
for ( i = 0; i < xsi; ++i)
rowptr[j + offset_new][i] = temp.rowptr[j + offset_old][i];
if ( n == 0) // fill new places w齮h 0
{
for ( j = ysi; j < ysize; ++j)
for ( i = 0; i < xsize; ++i)
rowptr[j + offset_new][i] = 0.0;
for ( j = 0; j < ysi; ++j)
for ( i = xsi; i < xsize; ++i)
rowptr[j + offset_new][i] = 0.0;
}
else if ( n == 1) // fill new places by repeating boundary values
{
for ( j = 0; j < ysi; ++j)
for ( i = xsi; i < xsize; ++i)
rowptr[j + offset_new][i] = rowptr[j + offset_new][xsi - 1];
for ( j = ysi; j < ysize; ++j)
for ( i = 0; i < xsize; ++i)
rowptr[j + offset_new][i] = rowptr[ysi - 1 + offset_new][i];
} // else
} // for numbands..
} // if (!empty)
else // the old matrix was empty
{
for(j=0; j < xsize*ysize*numbands;j++)
elem[j]= 0.0;
}
} // else
} // if
}// resize
//-------------------------------------------------------------
void matrix::display( CString& message)
{
message = "";
CString text;
for(int u = 0; u < numbands; u++)
{
for(int p = 0; p < ysize; p++)
{
for (int q = 0; q < xsize; q++)
{
text.Format("%10g\t", rowptr[u*ysize + p][q]);
message += text;
}
text.Format("\n");
message += text;
}
text.Format("\n");
message += text;
}
}
//-------------------------------------------------------------
void matrix::display(char *fname)
{
ASSERT( numbands == 1);
CFile myFile;
myFile.Open(fname, CFile::modeWrite | CFile::modeCreate );
CString text;
CString textline;
int length;
for(int p=0; p < ysize; p++)
{
textline = "";
for (int q=0; q < xsize; q++)
{
text.Format("%g ", elem[p*xsize+q]);
textline += text;
}
text.Format("\r\n");
textline += text;
length = textline.GetLength();
myFile.Write((LPCTSTR)textline, length);
}
myFile.Close();
}
//-------------------------------------------------------------
void matrix::displayRGB(char *fname)
{
ASSERT( numbands == 3);
CFile myFile;
myFile.Open(fname, CFile::modeWrite | CFile::modeCreate );
CString text;
CString textline;
int length;
int skip = ysize * xsize;
for(int p = 0; p < ysize; p++)
{
textline = "";
for (int q = 0; q < xsize; q++)
{
text.Format("%g ", elem[p*xsize+q] );
textline += text;
}
text.Format("\r\n");
textline += text;
length = textline.GetLength();
myFile.Write((LPCTSTR)textline, length);
}
myFile.Close();
}
//-------------------------------------------------------------
void matrix::decimate(int factor)
{
ASSERT( factor > 0);
int i, j;
int newxsize,newysize;
newxsize = (int) xsize/factor;
newysize = (int) ysize/factor;
matrix a(newysize, newxsize, numbands);
for ( int u = 0; u < numbands; ++u)
{
int offset = u * ysize;
for (i = 0; i < newysize; i++)
{
for (j = 0; j < newxsize; j++)
{
a(i,j,u) = rowptr[factor*i + offset][factor*j];
}
}
}
delete[] elem;
delete[] rowptr;
xsize = newxsize;
ysize = newysize;
elem = new double [ysize * xsize * numbands];
rowptr = new double* [ysize * numbands];
for (i = 0; i < ( ysize * xsize * numbands); i++)
elem[i] = a.elem[i];
for(i = 0; i < ysize * numbands; i++)
rowptr[i] = elem + i * xsize;
}
//-------------------------------------------------------------
matrix matrix::read(char *fname, int xsize, int ysize)
{
ASSERT( xsize > 0 && ysize > 0);
CFile myFile;
myFile.Open(fname, CFile::modeRead);
double* data = new double[xsize];
int length = 8*xsize;
matrix temp( ysize, xsize);
for(int j = 0; j < ysize; j++)
{
myFile.Read(data, length);
for (int i = 0; i < xsize; i++)
{
temp( j, i) = data[i];
}
}
myFile.Close();
return temp;
}
//-------------------------------------------------------------
void matrix::qdecimate(int shft)
{
ASSERT( numbands == 1);
// galiba quincunx downsampling yapiyor ...
int i,j,ii,jj;
matrix outim(ysize,xsize);
for (i=0;i<ysize;i++)
{
for (j=0;j<xsize;j++)
{
ii = ((i+j)%ysize); jj = ((-i+j+shft)%xsize);
while (jj<0)
jj = xsize+jj;
while (ii<0)
ii = ysize+ii;
// cerr<<ii<<" "<<jj<<" ";
outim(i,j) = rowptr[ii][jj];
}
}
elem= new double [ysize*xsize];
rowptr=new double* [ysize];
for (i=0;i<(ysize*xsize);i++)
elem[i]=outim.elem[i];
for(i=0;i<ysize;i++)
rowptr[i]= elem+i*xsize;
}
//-------------------------------------------------------------
void matrix::upsample(int factor)
{
int i, j, k, offset;
int newxsize, newysize;
newxsize = (int) xsize * factor;
newysize = (int) ysize * factor;
matrix a( newysize, newxsize, numbands);
for ( k = 0; k < numbands; k++)
{
offset = k * ysize;
for ( j = 0; j < ysize; j++)
{
for ( i = 0; i < xsize; i++)
{
a( factor * j, factor * i, k) = rowptr[j + offset][i];
}
}
}
delete[] elem;
delete[] rowptr;
xsize = newxsize;
ysize = newysize;
elem = new double [ysize * xsize * numbands];
rowptr = new double* [ysize * numbands];
for ( i = 0; i < ysize * xsize * numbands; i++)
elem[i] = a.elem[i];
for( i = 0; i < ysize * numbands; i++)
rowptr[i] = elem + i * xsize;
}
//-------------------------------------------------------------
void matrix::qupsample(int shft)
{
ASSERT( numbands == 1);
int i,j,ii,jj;
matrix outim(ysize,xsize);
for (i=0;i<ysize;i++)
for (j=0;j<xsize;j++) {
ii = ((i+j)%ysize); jj = ((-i+j-shft)%xsize);
while (jj<0)
jj = xsize+jj;
while (ii<0)
ii = ysize+ii;
// cerr<<ii<<" "<<jj<<" ";
outim(ii,jj) = rowptr[i][j];
}
elem= new double [ysize*xsize];
rowptr=new double* [ysize];
for (i=0;i<(ysize*xsize);i++) elem[i]=outim.elem[i];
for(i=0;i<ysize;i++) rowptr[i]= elem+i*xsize;
}
//-------------------------------------------------------------
matrix matrix::extractBand(int band)
{
matrix outmatrix(ysize, xsize, 1);
int offset = band * ysize;
for( int j = 0; j < ysize; j++)
{
for( int i = 0; i < xsize; i++)
{
outmatrix(j, i) = rowptr[j + offset][i];
}
}
return outmatrix;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?