⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 warp.cpp

📁 MPEG-4编解码的实现(包括MPEG4视音频编解码)
💻 CPP
字号:
/*************************************************************************

This software module was originally developed by 

	Ming-Chieh Lee (mingcl@microsoft.com), Microsoft Corporation
	Wei-ge Chen (wchen@microsoft.com), Microsoft Corporation
	Bruce Lin (blin@microsoft.com), Microsoft Corporation
	Chuang Gu (chuanggu@microsoft.com), Microsoft Corporation
	(date: March, 1996)

and also edited by

    Yuichiro Nakaya (Hitachi, Ltd.)
    Yoshinori Suzuki (Hitachi, Ltd.)

in the course of development of the MPEG-4 Video (ISO/IEC 14496-2). 
This software module is an implementation of a part of one or more MPEG-4 Video tools 
as specified by the MPEG-4 Video. 
ISO/IEC gives users of the MPEG-4 Video free license to this software module or modifications 
thereof for use in hardware or software products claiming conformance to the MPEG-4 Video. 
Those intending to use this software module in hardware or software products are advised that its use may infringe existing patents. 
The original developer of this software module and his/her company, 
the subsequent editors and their companies, 
and ISO/IEC have no liability for use of this software module or modifications thereof in an implementation. 
Copyright is not released for non MPEG-4 Video conforming products. 
Microsoft retains full right to use the code for his/her own purpose, 
assign or donate the code to a third party and to inhibit third parties from using the code for non <MPEG standard> conforming products. 
This copyright notice must be included in all copies or derivative works. 

Copyright (c) 1996, 1997.

Module Name:

	warp.cpp

Abstract:

	Geometry transformation:
		2D Affine
		2D Perspective

Revision History:
	Jan. 13, 1999: Code for disallowing zero demoninators in perspective
                       warping added by Hitachi, Ltd.

*************************************************************************/

#include <math.h>
#include "basic.hpp"
#include "svd.h"
#include "warp.hpp"

#ifdef __MFC_
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif

#define new DEBUG_NEW				   
#endif // __MFC_


CVector2D CMatrix2x2D::apply (const CVector2D& v) const
{
 	return CVector2D (
		m_value [0] [0] * v.x + m_value [0] [1] * v.y, 
		m_value [1] [0] * v.x + m_value [1] [1] * v.y 
	); 
}


CMatrix2x2D::CMatrix2x2D (Double d)
{
	m_value [0] [0] = d; 
	m_value [1] [1] = d; 
	m_value [0] [1] = 0; 
	m_value [1] [0] = 0; 
}

CMatrix2x2D::CMatrix2x2D (Double d00, Double d01, Double d10, Double d11)
{
	m_value [0] [0] = d00; 
	m_value [1] [1] = d11; 
	m_value [0] [1] = d01; 
	m_value [1] [0] = d10; 
}

CMatrix2x2D::CMatrix2x2D (const CVector2D& v0, const CVector2D& v1, Bool fAsColumns)
{
	m_value [0] [0] = v0.x; 
	m_value [1] [0] = v0.y; 
	m_value [0] [1] = v1.x; 
	m_value [1] [1] = v1.y; 

	if (!fAsColumns) transpose (); 
}

CMatrix2x2D::CMatrix2x2D (const CVector2D v [2])
{
	*this = CMatrix2x2D (v [0], v [1]); 
}


CMatrix2x2D CMatrix2x2D::operator * (const CMatrix2x2D& x) const 
{
	CMatrix2x2D r; 
	r.m_value [0] [0] = m_value [0] [0] * x.m_value [0] [0] + m_value [0] [1] * x.m_value [1] [0]; 
	r.m_value [1] [0] = m_value [1] [0] * x.m_value [0] [0] + m_value [1] [1] * x.m_value [1] [0]; 
	r.m_value [0] [1] = m_value [0] [0] * x.m_value [0] [1] + m_value [0] [1] * x.m_value [1] [1]; 
	r.m_value [1] [1] = m_value [1] [0] * x.m_value [0] [1] + m_value [1] [1] * x.m_value [1] [1]; 
	return r; 
}

CMatrix2x2D::CMatrix2x2D (const CVector2D& s0, const CVector2D& s1, const CVector2D& d0, const CVector2D& d1) 
{
	*this = CMatrix2x2D (d0, d1) * CMatrix2x2D (s0, s1).inverse (); 
}

CMatrix2x2D::CMatrix2x2D (const CVector2D source [2], const CVector2D dest [2])
{
	*this = CMatrix2x2D (source [0], source [1], dest [0], dest [1]); 
}

CMatrix2x2D CMatrix2x2D::inverse () const
{
	Double det = determinant (); 
	if (det == 0) // ill conditioned -- make this a better test
	{
		return CMatrix2x2D ((Double) 0); 
	}

	CMatrix2x2D r; 
	Double detInv = (Double) 1.0 / det; 
	r.m_value [0] [0] = m_value [1] [1] * detInv; 
	r.m_value [1] [1] = m_value [0] [0] * detInv; 
	r.m_value [0] [1] = - m_value [0] [1] * detInv; 
	r.m_value [1] [0] = - m_value [1] [0] * detInv; 
	return r; 
}

Void CMatrix2x2D::transpose ()
{
	Double tmp = m_value [0] [1]; 
	m_value [0] [1] = m_value [1] [0]; 
	m_value [1] [0] = tmp; 
}


CAffine2D::CAffine2D (const CSiteD& source, const CSiteD& dest) : 
	m_mtx(1.), m_stdSrc (source), m_stdDst (dest)
{
	// thats all folks
}


CAffine2D::CAffine2D (const CSiteD& s0, const CSiteD& s1, const CSiteD& d0, const CSiteD& d1) : 
	m_mtx(s1 - s0, (s1 - s0).rot90 (), d1 - d0, (d1 - d0).rot90 ()),
	m_stdSrc (s0), 
	m_stdDst (d0)
{
}


CAffine2D::CAffine2D (
	const CSiteD& s, const CVector2D& sv0, const CVector2D& sv1, 
	const CSiteD& d, const CVector2D& dv0, const CVector2D& dv1) : 
	m_mtx(sv0, sv1, dv0, dv1), m_stdSrc (s), m_stdDst (d)
{
}


CAffine2D::CAffine2D (const CSiteD source [3], const CSiteD dest [3]) : 
	m_mtx (
		source [1] - source [0], 
		source [2] - source [0], 
		dest [1] - dest [0], 
		dest [2] - dest [0]
	),
	m_stdSrc (source [0]), 
	m_stdDst (dest [0])

{
}

CAffine2D::CAffine2D (const CoordD params [6]) :
	m_mtx (CVector2D (params [0], params [3]), CVector2D (params [1], params [4])),
	m_stdSrc (0, 0),
	m_stdDst (params [2], params [5])
{
}



CAffine2D CAffine2D::inverse () const
{
	CAffine2D affInv; 
	affInv.m_mtx= m_mtx.inverse (); 
	affInv.m_stdSrc = m_stdDst; 
	affInv.m_stdDst = m_stdSrc; 
	return affInv; 
}

CAffine2D CAffine2D::setOrigin (const CSiteD& std) const
{
 	CAffine2D r;
	CVector2D vec;
	r.m_mtx = m_mtx;
	vec = m_mtx.apply (std - m_stdDst);
	r.m_stdDst.x = std.x - vec.x;
	r.m_stdDst.y = std.y - vec.y;
	r.m_stdSrc = m_stdSrc;
	return r;
}


Void CAffine2D::getParams (CoordD params [6]) const
{
	params [0] = m_mtx.element (0, 0);
	params [1] = m_mtx.element (0, 1);
	params [3] = m_mtx.element (1, 0);
	params [4] = m_mtx.element (1, 1);
	params [2] = m_stdDst.x - params [0] * m_stdSrc.x - params [1] * m_stdSrc.y;
	params [5] = m_stdDst.y - params [3] * m_stdSrc.x - params [4] * m_stdSrc.y;

}


CPerspective2D::~CPerspective2D ()
{
	delete [] m_rgCoeff;
}

CPerspective2D::CPerspective2D ()
{
	m_rgCoeff = NULL;
}

CPerspective2D::CPerspective2D (const UInt pntNum, const CSiteD source [4], const CSiteD dest [4], const UInt accuracy) : m_rgCoeff (NULL)
{
	UInt uiScale = 1 << (accuracy + 1);
	m_x0 = source [0].x;
	m_y0 = source [0].y;
	m_rgCoeff = new Double [9];
	Double x [4], dx [4], y [4], dy [4], a[4][4];
	for (UInt k = 0; k < pntNum; k++) {
		m_rgstdSrc [k] = source [k];
		m_rgstdDst [k] = dest [k] * uiScale;
		x [k] = m_rgstdDst [k].x; 
		y [k] = m_rgstdDst [k].y;		
	}
	
	Int width = (Int) (m_rgstdSrc [1].x - m_rgstdSrc [0].x);
	Int height = (Int) (m_rgstdSrc [2].y - m_rgstdSrc [0].y);
	if (pntNum == 1) {
		a[1][1] = (Double) uiScale;
		a[2][1] = 0;
		a[3][1] = x [0];
		a[1][2] = 0;
		a[2][2] = (Double) uiScale;
		a[3][2] = y [0];
		a[1][3] = 0;
		a[2][3] = 0;
		a[3][3] = 1.0;
	} else if (pntNum == 2) {
		a[1][1] = (x [1] - x [0]) ;
		a[2][1] = (y [0] - y [1]) ;
		a[3][1] = x [0] * width;
		a[1][2] = (y [1] - y [0]) ;
		a[2][2] = (x [1] - x [0]) ;
		a[3][2] = y [0] * width;
		a[1][3] = 0;
		a[2][3] = 0;
		a[3][3] = width;
	} else if (pntNum == 3) {
		a[1][1] = (x [1] - x [0]) * height;
		a[2][1] = (x [2] - x [0]) * width;
		a[3][1] = x [0] * height * width;
		a[1][2] = (y [1] - y [0]) * height;
		a[2][2] = (y [2] - y [0]) * width;
		a[3][2] = y [0] * height * width;
		a[1][3] = 0;
		a[2][3] = 0;
		a[3][3] = height * width;	
	} else if (pntNum == 4) {
		dx [1] = x [1] - x [3]; dx [2] = x [2] - x [3]; dx [3] = x [0] - x [1] + x [3] - x [2];
		dy [1] = y [1] - y [3]; dy [2] = y [2] - y [3]; dy [3] = y [0] - y [1] + y [3] - y [2];
		if ((dx [3] == 0 && dy [3] == 0) || pntNum == 3) {
			a[1][1] = (x [1] - x [0]) * height;
			a[2][1] = (x [2] - x [0]) * width;
			a[3][1] = x [0] * height * width;
			a[1][2] = (y [1] - y [0]) * height;
			a[2][2] = (y [2] - y [0]) * width;
			a[3][2] = y [0] * height * width;
			a[1][3] = 0;
			a[2][3] = 0;
			a[3][3] = height * width;
		} else {
			Double deltaD = dx [1] * dy [2] - dx [2] * dy [1];
			a[1][3] = (dx [3] * dy [2] - dx [2] * dy [3]) * height;
			a[2][3] = (dx [1] * dy [3] - dx [3] * dy [1]) * width;
			a[1][1] = (x [1] - x [0]) * height * deltaD + a[1][3] * x [1];
			a[2][1] = (x [2] - x [0]) * width * deltaD + a[2][3] * x [2];
			a[3][1] = x [0] * height * width * deltaD;
			a[1][2] = (y [1] - y [0]) * deltaD * height + a[1][3] * y [1];
			a[2][2] = (y [2] - y [0]) * deltaD * width + a[2][3] * y [2];
			a[3][2] = y [0] * height * width * deltaD;
			a[3][3] = height * width * deltaD;
		}
	}
	m_rgCoeff [0] = a[1][1];
	m_rgCoeff [1] =	a[2][1];
	m_rgCoeff [2] =	a[3][1];
	m_rgCoeff [3] =	a[1][2];
	m_rgCoeff [4] =	a[2][2];
	m_rgCoeff [5] =	a[3][2];
	m_rgCoeff [6] =	a[1][3];
	m_rgCoeff [7] =	a[2][3];
	m_rgCoeff [8] =	a[3][3];
}

CPerspective2D::CPerspective2D (const CSiteD source [4], const CSiteD dest [4]) : m_rgCoeff (NULL)
{
	m_x0 = m_y0 = 0.0;
	UInt pts = 4;
	UInt rows = 2 * pts, cols = 8, i, j;
	for (i = 0; i < 4; i++) {
		m_rgstdSrc [i] = source [i];
		m_rgstdDst [i] = dest [i];
	}

	Double* B = new Double [rows];
	Double** A = (Double**) new Double* [rows]; 
	for (i = 0; i < rows; i++)
		A [i] =  new Double [cols] ;

	for (i = 0; i < pts; i++) {
	 	A [i] [0] = m_rgstdSrc [i].x ;
		A [i] [1] = m_rgstdSrc [i].y ;
		A [i] [2] = 1; 
		A [i] [3] = A [i] [4] = A[i] [5] =0;
	 	A [i] [6] = (-1) * (m_rgstdSrc [i].x * m_rgstdDst [i].x );
		A [i] [7] = (-1) * (m_rgstdSrc [i].y * m_rgstdDst [i].x );

		B [i] = m_rgstdDst [i].x;
	}

	for (i = pts, j = 0; i < rows; i++, j++) {
		A [i] [0] = A [i] [1] = A [i] [2] = 0;
	 	A [i] [3] = m_rgstdSrc [j].x ;
		A [i] [4] = m_rgstdSrc [j].y ;
		A [i] [5] = 1; 
	 	A [i] [6] = (-1) * (m_rgstdSrc [j].x * m_rgstdDst [j].y);
		A [i] [7] = (-1) * (m_rgstdSrc [j].y * m_rgstdDst [j].y);

		B [i] = m_rgstdDst [j].y;
	}
	m_rgCoeff = linearLS (A, B, rows, cols);

	delete [] B;
	for (i = 0; i < rows; i++)
		delete [] A [i];

	delete [] A;
}

CPerspective2D::CPerspective2D (Double* rgCoeff) : m_rgCoeff (NULL)
{
	m_rgCoeff = new Double [8];
	UInt i;
	for (i = 0; i < 8; i++) 
		m_rgCoeff [i] = rgCoeff [i];
	m_rgstdSrc [0] = CSiteD (0, 0);
	m_rgstdSrc [1] = CSiteD (176, 0);
	m_rgstdSrc [2] = CSiteD (0, 144);
	m_rgstdSrc [3] = CSiteD (176, 144);
	for (i = 0; i < 4; i++) {
		m_rgstdDst [i] = (*this * m_rgstdSrc [i]).s;
	}
}

CSiteDWFlag CPerspective2D::apply (const CSiteD& s0) const
{
	Double destX, destY, destW;
	CSiteDWFlag destST; 
	
	destX = (s0.x - m_x0) * m_rgCoeff [0] + (s0.y - m_y0) * m_rgCoeff [1] + m_rgCoeff [2];
	destY = (s0.x - m_x0 ) * m_rgCoeff [3] + (s0.y - m_y0 ) * m_rgCoeff [4] + m_rgCoeff [5]; 
	destW = (s0.x - m_x0) * m_rgCoeff [6] + (s0.y - m_y0) * m_rgCoeff [7] + m_rgCoeff [8]; 
	if (destW != 0.0) {
		destST.s.x = destX / destW; 
		destST.s.y = destY / destW; 
		destST.f = FALSE;
	} else    // destW == 0.0
		destST.f = TRUE;

	return destST;
}

CSiteWFlag CPerspective2D::apply (const CSite& s0) const
{
	Double destX, destY, destW;
	CSiteWFlag destST; 
	
	destX = (s0.x - m_x0) * m_rgCoeff [0] + (s0.y - m_y0) * m_rgCoeff [1] + m_rgCoeff [2];
	destY = (s0.x - m_x0 ) * m_rgCoeff [3] + (s0.y - m_y0 ) * m_rgCoeff [4] + m_rgCoeff [5]; 
	destW = (s0.x - m_x0) * m_rgCoeff [6] + (s0.y - m_y0) * m_rgCoeff [7] + m_rgCoeff [8];

	if (destW != 0.0) {
		if ((destX >= 0 && destW > 0) || (destX <= 0 && destW < 0)) {
			destST.s.x = (CoordI) ((destX + destW / 2) / destW);
		} else {
			if (destX > 0 && destW < 0) {
				destST.s.x = (CoordI) ((destX - (destW + 1) / 2) / destW);
			} else {
				destST.s.x = (CoordI) ((destX - (destW - 1) / 2) / destW);
			}
		}
		if ((destY >= 0 && destW > 0) || (destY <= 0 && destW < 0)) {
			destST.s.y = (CoordI) ((destY + destW / 2) / destW);
		} else {
			if (destY > 0 && destW < 0) {
				destST.s.y = (CoordI) ((destY - (destW + 1) / 2) / destW);
			} else {
				destST.s.y = (CoordI) ((destY - (destW - 1) / 2) / destW);
			}
		}
		destST.f = FALSE;
	} else    // destW == 0.0
		destST.f = TRUE;

	return destST; 
}

CPerspective2D CPerspective2D::inverse () const
{
	return CPerspective2D (m_rgstdDst, m_rgstdSrc);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -