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 + -
显示快捷键?