//*************************************************************************
TEST (EssentialMatrixFactor, testData) {
    CHECK(readOK);

    // Check E matrix
    Matrix expected(3, 3);
    expected << 0, 0, 0, 0, 0, -0.1, 0.1, 0, 0;
    Matrix aEb_matrix = skewSymmetric(c1Tc2.x(), c1Tc2.y(), c1Tc2.z())
                        * c1Rc2.matrix();
    EXPECT(assert_equal(expected, aEb_matrix, 1e-8));

    // Check some projections
    EXPECT(assert_equal(Point2(0, 0), pA(0), 1e-8));
    EXPECT(assert_equal(Point2(0, 0.1), pB(0), 1e-8));
    EXPECT(assert_equal(Point2(0, -1), pA(4), 1e-8));
    EXPECT(assert_equal(Point2(-1, 0.2), pB(4), 1e-8));

    // Check homogeneous version
    EXPECT(assert_equal(Vector3(-1, 0.2, 1), vB(4), 1e-8));

    // Check epipolar constraint
    for (size_t i = 0; i < 5; i++)
        EXPECT_DOUBLES_EQUAL(0, vA(i).transpose() * aEb_matrix * vB(i), 1e-8);

    // Check epipolar constraint
    for (size_t i = 0; i < 5; i++)
        EXPECT_DOUBLES_EQUAL(0, trueE.error(vA(i), vB(i)), 1e-7);
}
Esempio n. 2
0
void XSQUARE_MATRIX::Invert_LUD(void)
{ // Invert the matrix using LU decomposition
	Perform_LU_Decomposition();
	if (m_lpdValues && m_bLU_Initialized)
	{
		if (g_lpvX == NULL || g_uiX_Size < m_uiN)
		{
			if (g_lpvX)
				delete [] g_lpvX;
			g_lpvX = new XVECTOR[m_uiN];
			g_uiX_Size = m_uiN;
		}
		XVECTOR	vB(m_uiN);
        XVECTOR	vY(m_uiN);
		for (unsigned int uiI = 0; uiI < m_uiN; uiI++)
			vB.Set(uiI,0.0);
		for (unsigned int uiI = 0; uiI < m_uiN; uiI++)
		{
			if (uiI != 0)
				vB.Set(uiI - 1,0.0);
			vB.Set(uiI,1.0);
			vY = Forward_Substituion(vB);
			g_lpvX[uiI] = Back_Substituion(m_lpdU_Values,vY);
		}
		// Inverse found (stored in the array of X vectors)
		// no refill matrix
		for (unsigned int uiI = 0; uiI < m_uiN; uiI++)
			Set(uiI, g_lpvX[uiI]);
		m_bLU_Initialized = false;
		// Get LU decomposition of inverted matrix
		Perform_LU_Decomposition();
	}
}
Esempio n. 3
0
File: test.cpp Progetto: 8l/kalmar
runall_result TestOnDevice()
{
	runall_result result;
    Log() << "Testing constructor that takes individual co-ordinates on Device" << std::endl;

    accelerator_view av = require_device().get_default_view();

    /* vA, vB, vC, vD hold the components of each index. vE, holds all the rank values */
    vector<int> vA(1), vB(2), vC(3), vD(3);
    array<int, 1> A(extent<1>(1), av), B(extent<1>(2), av), C(extent<1>(3), av), D(extent<1>(3), av);

    extent<1> ex(1);
    parallel_for_each(ex, [&](index<1> idx) __GPU {
        kernel(A, B, C, D);
    });
bool vectorTest12() {
    int size = 10;
    Vector vA(size, 10);
    Vector vB(size * 2, 30);

    vA.concat(vB);

    bool thrown = false;
    try {
        vA.getValue(vA.getSize() + vB.getSize() + 1);
    } catch (const std::out_of_range& e) {
        thrown = true;
    }

    return vA.getValue(size - 1) == 10 && vA.getValue(size + 1) == 30 && vA.getValue((size * 2) - 1) == 30 && thrown;
};
Esempio n. 5
0
runall_result CopyConstructWithIndexOnDevice()
{
	runall_result result;
    Log() << "Testing copy construct index as parallel_for_each parameter (from another index)" << std::endl;   

    accelerator_view av = require_device().default_view;

    index<RANK> idxparam(0, 1, 2);

    vector<int> vA(RANK), vB(1), vC(RANK), vD(1);
    array<int, 1> A(extent<1>(RANK), av), B(extent<1>(1), av), C(extent<1>(RANK), av), D(extent<1>(1), av);

    extent<1> ex(1);
    parallel_for_each(ex, [&, idxparam](index<1> idx) __GPU {
        kernel(A, B, C, D, idxparam);
    });
//*************************************************************************
TEST (EssentialMatrixFactor, minimization) {
    // Here we want to optimize directly on essential matrix constraints
    // Yi Ma's algorithm (Ma01ijcv) is a bit cumbersome to implement,
    // but GTSAM does the equivalent anyway, provided we give the right
    // factors. In this case, the factors are the constraints.

    // We start with a factor graph and add constraints to it
    // Noise sigma is 1cm, assuming metric measurements
    NonlinearFactorGraph graph;
    for (size_t i = 0; i < 5; i++)
        graph.add(EssentialMatrixFactor(1, pA(i), pB(i), model1));

    // Check error at ground truth
    Values truth;
    truth.insert(1, trueE);
    EXPECT_DOUBLES_EQUAL(0, graph.error(truth), 1e-8);

    // Check error at initial estimate
    Values initial;
    EssentialMatrix initialE = trueE.retract(
                                   (Vector(5) << 0.1, -0.1, 0.1, 0.1, -0.1).finished());
    initial.insert(1, initialE);
#if defined(GTSAM_ROT3_EXPMAP) || defined(GTSAM_USE_QUATERNIONS)
    EXPECT_DOUBLES_EQUAL(643.26, graph.error(initial), 1e-2);
#else
    EXPECT_DOUBLES_EQUAL(639.84, graph.error(initial), 1e-2);
#endif

    // Optimize
    LevenbergMarquardtParams parameters;
    LevenbergMarquardtOptimizer optimizer(graph, initial, parameters);
    Values result = optimizer.optimize();

    // Check result
    EssentialMatrix actual = result.at<EssentialMatrix>(1);
    EXPECT(assert_equal(trueE, actual, 1e-1));

    // Check error at result
    EXPECT_DOUBLES_EQUAL(0, graph.error(result), 1e-4);

    // Check errors individually
    for (size_t i = 0; i < 5; i++)
        EXPECT_DOUBLES_EQUAL(0, actual.error(vA(i), vB(i)), 1e-6);

}
Esempio n. 7
0
// To draw regular tetrahedron 
// Four points : A(0, 1, 0), B(0, -1/3, 2¡Ì2/3), C(-¡Ì6/3, -1/3, -¡Ì2/3), D(¡Ì6/3, -1/3, -¡Ì2/3)
void cf_drawRTetrahedron() {
	double sqrt2= sqrt(2.0);
	double sqrt6 = sqrt(6.0);
	double l = 2;

	CP_Vector3D vA(0, l, 0);
	CP_Vector3D vB(0, -l/3, 2*l*sqrt2/3);
	CP_Vector3D vC(-l*sqrt6/3, -l/3, -l*sqrt2/3);
	CP_Vector3D vD(l*sqrt6/3, -l/3, -l*sqrt2/3);

	// Face ABC
	glColor3f(1.0, 0.0, 0.0); // Red
	glBegin(GL_POLYGON);
	glVertex3d(vA.m_x, vA.m_y, vA.m_z);
	glVertex3d(vB.m_x, vB.m_y, vB.m_z);
	glVertex3d(vC.m_x, vC.m_y, vC.m_z);
	glEnd();

	// Face ACD
	glColor3f(0.0, 0.0, 1.0); // Blue
	glBegin(GL_POLYGON);
	glVertex3d(vA.m_x, vA.m_y, vA.m_z);
	glVertex3d(vC.m_x, vC.m_y, vC.m_z);
	glVertex3d(vD.m_x, vD.m_y, vD.m_z);
	glEnd();

	// Face ADB
	glColor3f(0.0, 1.0, 0.0); // Green
	glBegin(GL_POLYGON);
	glVertex3d(vA.m_x, vA.m_y, vA.m_z);
	glVertex3d(vD.m_x, vD.m_y, vD.m_z);
	glVertex3d(vB.m_x, vB.m_y, vB.m_z);
	glEnd();

	// Face CBD
	glColor3f(1.0, 0.0, 1.0); // 
	glBegin(GL_POLYGON);
	glVertex3d(vC.m_x, vC.m_y, vC.m_z);
	glVertex3d(vB.m_x, vB.m_y, vB.m_z);
	glVertex3d(vD.m_x, vD.m_y, vD.m_z);
	glEnd();
}
//*************************************************************************
TEST (EssentialMatrixFactor, extraMinimization) {
    // Additional test with camera moving in positive X direction

    NonlinearFactorGraph graph;
    for (size_t i = 0; i < 5; i++)
        graph.add(EssentialMatrixFactor(1, pA(i), pB(i), model1, K));

    // Check error at ground truth
    Values truth;
    truth.insert(1, trueE);
    EXPECT_DOUBLES_EQUAL(0, graph.error(truth), 1e-8);

    // Check error at initial estimate
    Values initial;
    EssentialMatrix initialE = trueE.retract(
                                   (Vector(5) << 0.1, -0.1, 0.1, 0.1, -0.1).finished());
    initial.insert(1, initialE);

#if defined(GTSAM_ROT3_EXPMAP) || defined(GTSAM_USE_QUATERNIONS)
    EXPECT_DOUBLES_EQUAL(643.26, graph.error(initial), 1e-2);
#else
    EXPECT_DOUBLES_EQUAL(639.84, graph.error(initial), 1e-2);
#endif

    // Optimize
    LevenbergMarquardtParams parameters;
    LevenbergMarquardtOptimizer optimizer(graph, initial, parameters);
    Values result = optimizer.optimize();

    // Check result
    EssentialMatrix actual = result.at<EssentialMatrix>(1);
    EXPECT(assert_equal(trueE, actual, 1e-1));

    // Check error at result
    EXPECT_DOUBLES_EQUAL(0, graph.error(result), 1e-4);

    // Check errors individually
    for (size_t i = 0; i < 5; i++)
        EXPECT_DOUBLES_EQUAL(0, actual.error(vA(i), vB(i)), 1e-6);

}
Esempio n. 9
0
void _3dsLoader::generateNormals(Mesh *mesh) const
{
	if(mesh->m_numOfVerts > 2)
	{
		mesh->m_pNormals = new Point3[mesh->m_numOfVerts];

		for(int i=0; i<mesh->m_numOfFaces; ++i)
		{
			size_t iA = mesh->m_pFaces[i].vertIndex[0];
			size_t iB = mesh->m_pFaces[i].vertIndex[1];
			size_t iC = mesh->m_pFaces[i].vertIndex[2];

			Point3 A = mesh->m_pVerts[iA];
			Point3 B = mesh->m_pVerts[iB];
			Point3 C = mesh->m_pVerts[iC];

			vec3 vA(A.x, A.y, A.z);
			vec3 vB(B.x, B.y, B.z);
			vec3 vC(C.x, C.y, C.z);

			vec3 AC = vA - vC;
			vec3 BC = vB - vC;
			vec3 norm = AC.cross(BC).getNormal();

			mesh->m_pNormals[iA].x = -norm.x;
			mesh->m_pNormals[iA].y = -norm.y;
			mesh->m_pNormals[iA].z = -norm.z;

			mesh->m_pNormals[iB].x = -norm.x;
			mesh->m_pNormals[iB].y = -norm.y;
			mesh->m_pNormals[iB].z = -norm.z;

			mesh->m_pNormals[iC].x = -norm.x;
			mesh->m_pNormals[iC].y = -norm.y;
			mesh->m_pNormals[iC].z = -norm.z;
		}
	}
}
Esempio n. 10
0
void CPatch::Calculate (ubyte nChnlNo) {
	uvar16_32	nDimX = *(m_pImg->m_pnDimX),
			nDimY = *(m_pImg->m_pnDimY);
	uvar32_64	nValue, j;
	uvar32_64	dwConPtr;
	ubyte		nAlpha;
	rtbyte		rValue;
	rtbyte		rPI = 3.1415926535897932384626433832795,
			rRotAngle = rPI / 32.0;
	rtbyte		rDiamMin, rDiamMax, rDiamSum2,
			rX, rY, rXX, rYY,
			rTopX, rTopY, rBottomX, rBottomY,
			rFeretY, rAngle;
	rtbyte		prFactors[3];
	CVector<rtbyte> vA, vB, vC;
	CChannel* pChnl = &(m_pImg->Channels[nChnlNo]);

	// #### TODO: Put geometric scaling factors here
	prFactors[0] = theApp.GeomScales[aimActive].GetCoefX ();
	prFactors[1] = theApp.GeomScales[aimActive].GetCoefY ();
	prFactors[2] = pow ( prFactors[0] * prFactors[0] + prFactors[1] * prFactors[1], 0.5 );
	m_rArea = m_nArea * prFactors[0] * prFactors[1];
	m_rPerimX = m_nPerimX * prFactors[0];
	m_rPerimY = m_nPerimY * prFactors[1];
	m_rPerimXY = m_nPerimXY * prFactors[0] * prFactors[1];
	m_rPerim = m_rPerimX + m_rPerimY + m_rPerimXY;
	m_rGravCntX = m_pntGravCnt.x * prFactors[0];
	m_rGravCntY = m_pntGravCnt.y * prFactors[1];

	// #### TODO: Allocate memory for m_prDistrib

	// Determining densitometric parameters
	m_rSum = m_rSum2 = m_rMax = 0;
	m_rMin = 1e100; // #### TODO: Place max real value here
	m_prDistrib = (rtbyte*)aimMemoryCommit (m_pImg->m_pDoc->m_nBPP, "CPatch::Measure", "m_prDistrib");
	for (uvar32_64 n = 0 ; n < m_pImg->m_pDoc->m_nBPP ; ++n)
		m_prDistrib[n] = 0;
	for (uvar32_64 dwCntPtr = 0 ; dwCntPtr < m_dwCntLen ; ++dwCntPtr) {
		nValue = pChnl->GetPixel (m_pdwContent[dwCntPtr], false);
		rValue = pChnl->GetPixel (m_pdwContent[dwCntPtr], true);
		m_rSum += rValue;
		m_rSum2 += rValue * rValue;
		m_rMin = (rValue < m_rMin) ? rValue : m_rMin;
		m_rMax = (rValue > m_rMax) ? rValue : m_rMax;
		++m_prDistrib[nValue];
	}
	m_rMean = m_rSum / m_dwCntLen;
	if (m_dwCntLen != 1)
		m_rStdDev = pow ((m_rSum2 * m_dwCntLen - m_rSum * m_rSum) / (m_dwCntLen * (m_dwCntLen - 1)), 0.5);
	else
		m_rStdDev = 0.;
	for (n = 0 ; n < m_pImg->m_pDoc->m_nBPP ; ++n)
		m_prDistrib[n] /= rtbyte (m_dwCntLen);

	// Rotating
	m_prFeretsX[0] = m_pntApex.x * prFactors[0];
	m_prFeretsY[0] = m_pntApex.y * prFactors[1];
	m_prDiameters[0] = (m_rectPatch.bottom - m_rectPatch.top) * prFactors[0];
	m_nDiamMin = m_nDiamMax = 0;
	m_rDiamMean = rDiamMin = rDiamMax = m_prDiameters[0];
	rDiamSum2 = m_prDiameters[0] * m_prDiameters[0];
	for (ubyte rot = 1; rot < 64; ++rot) {
		rTopX = rTopY = rFeretY = 0x7FFFFFFF;
		rBottomX = rBottomY = -0x7FFFFFFF;
		for (dwConPtr = 0; dwConPtr < m_dwConLen; ++dwConPtr) {
			rXX = SRCOFFSET_TO_COORDX (m_pdwContour[dwConPtr]) - m_pntGravCnt.x;
			rYY = SRCOFFSET_TO_COORDY (m_pdwContour[dwConPtr]) - m_pntGravCnt.y;
			rX = rXX * cosl (rRotAngle * rot) - rYY * sinl (rRotAngle * rot);
			rY = rXX * sinl (rRotAngle * rot) + rYY * cosl (rRotAngle * rot);
			if (rX < rTopX) rTopX = rX;
			if (rY < rTopY) rTopY = rY;
			if (rX > rBottomX) rBottomX = rX;
			if (rY > rBottomY) rBottomY = rY;
			if (rY < rFeretY) {
				rFeretY = rY;
				m_prFeretsX[rot] = SRCOFFSET_TO_COORDX (m_pdwContour[dwConPtr]);
				m_prFeretsY[rot] = SRCOFFSET_TO_COORDY (m_pdwContour[dwConPtr]);
				if (m_prFeretsX[rot] - m_pntGravCnt.x < 0) m_prFeretsX[rot] -= .5;
				if (m_prFeretsX[rot] - m_pntGravCnt.x > 0) m_prFeretsX[rot] += .5;
				if (m_prFeretsY[rot] - m_pntGravCnt.y < 0) m_prFeretsY[rot] -= .5;
				if (m_prFeretsY[rot] - m_pntGravCnt.y > 0) m_prFeretsY[rot] += .5;
			}
		}
		if (rot >= 32)
			continue;
		nAlpha = (rot <= 16) ? rot : (32 - rot);
		rAngle = rRotAngle * nAlpha;
		m_prDiameters[rot] = rBottomX - rTopX + sinl (rAngle) + cosl (rAngle);
		m_prDiameters[rot] *= pow (prFactors[1]*sinl(rAngle) * prFactors[1]*sinl(rAngle) + prFactors[0]*cosl(rAngle) * prFactors[0]*cosl(rAngle), 0.5);
		m_prAngles[rot] = rot * rRotAngle * 180.0 / rPI;
		m_rDiamMean += m_prDiameters[rot];
		rDiamSum2 += m_prDiameters[rot] * m_prDiameters[rot];
		if (rDiamMin > m_prDiameters[rot]) {
			rDiamMin = m_prDiameters[rot];
			m_nDiamMin = rot;
		}
		if (rDiamMax < m_prDiameters[rot]) {
			rDiamMax = m_prDiameters[rot];
			m_nDiamMax = rot;
		}
	}
	m_rDiamSigma = pow ((32.0*rDiamSum2 - m_rDiamMean*m_rDiamMean) / 992.0, 0.5);
	m_rDiamMean /= 32.0;
	
	// Calculating circumscribed shape parameters
	m_rCscArea = m_rCscPerim = 0.0;
	for (rot = 0 ; rot < 64 ; ++rot) {
		j = (rot == 63) ? 0 : rot + 1;
		vA(1) = (m_prFeretsX[j] - m_prFeretsX[rot]) * prFactors[0];
		vA(2) = (m_prFeretsY[j] - m_prFeretsY[rot]) * prFactors[1];
		vB(1) = (m_prFeretsX[rot] - m_pntGravCnt.x) * prFactors[0];
		vB(2) = (m_prFeretsY[rot] - m_pntGravCnt.y) * prFactors[1];
		vC(1) = (m_prFeretsX[j] - m_pntGravCnt.x) * prFactors[0];
		vC(2) = (m_prFeretsY[j] - m_pntGravCnt.y) * prFactors[1];
		rtbyte rp = ( vA.Module() + vB.Module() + vC.Module() ) / 2;
		m_rCscArea += pow ( rp*(rp-vA.Module())*(rp-vB.Module())*(rp-vC.Module()), 0.5 );
		m_rCscPerim += vA.Module ( );
	}

	aimMemoryRelease (m_prDistrib, "CPatch::Measure", "m_prDistrib");
/*
	int		rot;
	ubyte		bAlpha;
	uvar16_32	wX, wY;
	uvar32_64	i, j, c;
	uvar32_64	dwSumX, dwSumY,
			dwSumGreyX, dwSumGreyY, dwSumGrey;
	uvar32_64	dwMskPtr,
			dwCntPtr,
			dwConPtr,
			dwSrcPtr,
			dwSrcLen = m_pDoc->GetDimX () * m_pDoc->GetDimY ();
	rtbyte		rPlane,
			rX, rY, rXX, rYY, rFeretY,
			rDimMin, rDimMax, rDiamSum2,
			rAngle,
			rPI,
			rRotAngle;
	rtbyte		lrTop[2], lrBottom[2];
	rtbyte		lrFactors[4];
	CVector<rtbyte> vA, vB, vC;

	// #### TODO: Put geometric scaling factors here
	lrFactors[0] = 1; //wieConfig.m_cfgGeomScales[wieConfig.m_cfgGeomScale].m_scaleFactorX;
	lrFactors[1] = 1; //wieConfig.m_cfgGeomScales[wieConfig.m_cfgGeomScale].m_scaleFactorY;
	lrFactors[2] = pow ( lrFactors[0] * lrFactors[0] + lrFactors[1] * lrFactors[1], 0.5 );

	// Determing statistics and bounding rectangle
	dwSumX = dwSumY = 0;
	dwSumGrey = dwSumGreyX = dwSumGreyY = 0;
	m_lwApex[0] = m_lwApex[1] = 0xFFFF;
	m_lwTop[0] = m_lwTop[1] = 0xFFFF;
	m_lwBottom[0] = m_lwBottom[1] = 0x0000;
	for (j = 0 ; j < 4 ; ++j) {
		m_lrSum[j] = m_lrSum2[j] = 0;
		m_lrMin[j] = 0xFF;
		m_lrMax[j] = 0;
		m_ldwCount[j] = m_dwCntLen;
		for (c = 0 ; c < 256 ; ++c)
			m_llrDistrib[j][c] = 0;
	}
	for (dwCntPtr = 0 ; dwCntPtr < m_dwCntLen ; ++dwCntPtr) {
		// #### TODO: Put dens transform function here
		rPlane = (MEANCOLOR (m_pdwPixels[m_pdwContent[dwCntPtr]]));
		m_lrSum[0] += rPlane;
		m_lrSum2[0] += rPlane * rPlane;
		m_lrMin[0] = (rPlane < m_lrMin[0]) ? rPlane : m_lrMin[0];
		m_lrMax[0] = (rPlane > m_lrMax[0]) ? rPlane : m_lrMax[0];
		++m_llrDistrib[0][MEANCOLOR (m_pdwPixels[m_pdwContent[dwCntPtr]])];
		wX = SRCOFFSET_TO_COORDX (m_pdwContent[dwCntPtr]);
		wY = SRCOFFSET_TO_COORDY (m_pdwContent[dwCntPtr]);
		dwSumX += wX;
		dwSumY += wY;
		dwSumGreyX += wX * SUMCOLOR (m_pdwPixels[m_pdwContent[dwCntPtr]]);
		dwSumGreyY += wY * SUMCOLOR (m_pdwPixels[m_pdwContent[dwCntPtr]]);
		dwSumGrey += SUMCOLOR (m_pdwPixels[m_pdwContent[dwCntPtr]]);
		for (j = 1 ; j < 4 ; ++j) {
			// #### TODO: Put dens transform function here
			rPlane = ((BYTE) GET_COLOR (m_pdwPixels[m_pdwContent[dwCntPtr]], j - 1));
			m_lrSum[j] += rPlane;
			m_lrSum2[j] += rPlane * rPlane;
			m_lrMin[j] = (rPlane < m_lrMin[j]) ? rPlane : m_lrMin[j];
			m_lrMax[j] = (rPlane > m_lrMax[j]) ? rPlane : m_lrMax[j];
			++m_llrDistrib[j][(BYTE) GET_COLOR (m_pdwPixels[m_pdwContent[dwCntPtr]], j - 1)];
		}
		if (wX < m_lwTop[0]) m_lwTop[0] = wX;
		if (wY < m_lwTop[1]) m_lwTop[1] = wY;
		if (wX > m_lwBottom[0]) m_lwBottom[0] = wX;
		if (wY > m_lwBottom[1]) m_lwBottom[1] = wY;
		if (m_pdwContent[dwCntPtr] < COORD_TO_SRCOFFSET (m_lwApex[0], m_lwApex[1])) {
			m_lwApex[0] = wX; m_lwApex[1] = wY;
		}
	}
	// Determing mean and deviance parameters
	for (j = 0 ; j < 4 ; ++j) {
		m_lrMean[j] = m_lrSum[j] / m_ldwCount[j];
		if (m_ldwCount[j] != 1)
			m_lrStdDev[j] = pow ( ((m_lrSum2[j] * m_ldwCount[j]) - (m_lrSum[j] * m_lrSum[j])) / (m_ldwCount[j] * (m_ldwCount[j] - 1)), 0.5);
		else
			m_lrStdDev[j] = 0.0;
		for (c = 0 ; c < 256 ; ++c)
			m_llrDistrib[j][c] /= rtbyte (m_dwCntLen);
	}
	m_lrCntGravity[0] = rtbyte (dwSumX) / rtbyte (m_dwCntLen);
	m_lrCntGravity[1] = rtbyte (dwSumY) / rtbyte (m_dwCntLen);
	m_lrGryGravity[0] = rtbyte (dwSumGreyX) / rtbyte (dwSumGrey);
	m_lrGryGravity[1] = rtbyte (dwSumGreyY) / rtbyte (dwSumGrey);

	// Creation of the Mask
	m_wDimX = m_lwBottom[0] - m_lwTop[0] + 1;
	m_wDimY = m_lwBottom[1] - m_lwTop[1] + 1;
	m_dwMskLen = m_wDimX * m_wDimY;
	if (!(m_pbMask = (ubyte*)aimMemoryCommit (m_dwMskLen, "CPatch::Set", "m_pbMask")) )
		throw (CaImAPIException(0));
	for (dwCntPtr = 0 ; dwCntPtr < m_dwCntLen ; ++dwCntPtr)
		m_pbMask[COORD_TO_MSKOFFSET (SRCOFFSET_TO_COORDX (m_pdwContent[dwCntPtr]) - m_lwTop[0],
		                             SRCOFFSET_TO_COORDY ( m_pdwContent[dwCntPtr] ) - m_lwTop[1] )] = 1;
	m_dwConLen = 0;
	for (wX = 0 ; wX < m_wDimX ; ++wX)
		for (wY = 0 ; wY < m_wDimY ; ++wY) {
			if (m_pbMask[COORD_TO_MSKOFFSET (wX, wY)] != 1)
				continue;
			if (wX == 0 || wY == 0 || wX == m_wDimX - 1 || wY == m_wDimY - 1) {
				m_pbMask[COORD_TO_MSKOFFSET (wX, wY)] = 2;
				++m_dwConLen;
			}
			else if (m_pbMask[COORD_TO_MSKOFFSET (wX - 1, wY)] == 0 ||
			         m_pbMask[COORD_TO_MSKOFFSET (wX + 1, wY)] == 0 ||
			         m_pbMask[COORD_TO_MSKOFFSET (wX, wY - 1)] == 0 ||
			         m_pbMask[COORD_TO_MSKOFFSET (wX, wY + 1)] == 0 ) {
				m_pbMask[COORD_TO_MSKOFFSET (wX, wY)] = 2;
				++m_dwConLen;
			}
		}

	if (!( m_pdwContour = (uvar32_64*)aimMemoryCommit (m_dwConLen * 4, "CPatch::Set", "m_pdwContour")))
		throw (CaImAPIException(0));
	for (dwMskPtr = dwConPtr = 0 ; dwMskPtr < m_dwMskLen ; ++dwMskPtr)
		if (m_pbMask[dwMskPtr] == 2)
			m_pdwContour[dwConPtr++] = COORD_TO_SRCOFFSET (MSKOFFSET_TO_COORDX (dwMskPtr) + m_lwTop[0],
			                                               MSKOFFSET_TO_COORDY ( dwMskPtr ) + m_lwTop[1] );

	// Calculating CntGravity, Perimeter, Area
	m_rPerimX = m_rPerimY = m_rPerimXY = 0;
	for (dwMskPtr = 0 ; dwMskPtr < m_dwMskLen ; ++dwMskPtr)
		if (m_pbMask[dwMskPtr] == 2)
			CalculatePerimeter (MSKOFFSET_TO_COORDX (dwMskPtr), MSKOFFSET_TO_COORDY (dwMskPtr));
	m_rArea = m_dwCntLen * lrFactors[0] * lrFactors[1];
	m_rPerim = m_rPerimX * lrFactors[0] + m_rPerimY * lrFactors[1] + m_rPerimXY * lrFactors[2];

	// Rotating
	m_llrFerets[0][0] = m_lwApex[0];
	m_llrFerets[0][1] = m_lwApex[1];
	m_lrDiameters[0] = (m_lwBottom[0] - m_lwTop[0] + 1.0)*lrFactors[0];					// !!!
	m_rDiamMean = m_lrDiameters[0];
	rDiamSum2 = m_lrDiameters[0] * m_lrDiameters[0];
	rDimMin = m_lrDiameters[0];
	rDimMax = m_lrDiameters[0];
	m_lrAngles[0] = 0.0;
	m_bDiamMaxNo = m_bDiamMinNo = 0;
	for (rot = 1 ; rot < 64 ; ++rot) {
		lrTop[0] = lrTop[1] = rFeretY = 0x7FFFFFFF;
		lrBottom[0] = lrBottom[1] = -0x7FFFFFFF;
		for (dwConPtr = 0 ; dwConPtr < m_dwConLen ; ++dwConPtr) {
			rXX = SRCOFFSET_TO_COORDX (m_pdwContour[dwConPtr]) - m_lrCntGravity[0];
			rYY = SRCOFFSET_TO_COORDY (m_pdwContour[dwConPtr]) - m_lrCntGravity[1];
			rX = rXX * cosl (rRotAngle * rot) - rYY * sinl (rRotAngle * rot);
			rY = rXX * sinl (rRotAngle * rot) + rYY * cosl (rRotAngle * rot);
			if (rX < lrTop[0]) lrTop[0] = rX;
			if (rY < lrTop[1]) lrTop[1] = rY;
			if (rX > lrBottom[0]) lrBottom[0] = rX;
			if (rY > lrBottom[1]) lrBottom[1] = rY;
			if (rY < rFeretY) {
				rFeretY = rY;
				m_llrFerets[rot][0] = SRCOFFSET_TO_COORDX (m_pdwContour[dwConPtr]);
				m_llrFerets[rot][1] = SRCOFFSET_TO_COORDY (m_pdwContour[dwConPtr]);
				if (m_llrFerets[rot][0] - m_lrCntGravity[0] < 0) m_llrFerets[rot][0] -= .5;
				if (m_llrFerets[rot][0] - m_lrCntGravity[0] > 0) m_llrFerets[rot][0] += .5;
				if (m_llrFerets[rot][1] - m_lrCntGravity[1] < 0) m_llrFerets[rot][1] -= .5;
				if (m_llrFerets[rot][1] - m_lrCntGravity[1] > 0) m_llrFerets[rot][1] += .5;
			}
		}
		if (rot >= 32)
			continue;
		bAlpha = (rot <= 16) ? rot : (32 - rot);
		rAngle = rRotAngle * bAlpha;
		m_lrDiameters[rot] = lrBottom[0] - lrTop[0] + sinl (rAngle) + cosl (rAngle);
		m_lrDiameters[rot] *= pow (lrFactors[1]*sinl(rAngle) * lrFactors[1]*sinl(rAngle) + lrFactors[0]*cosl(rAngle) * lrFactors[0]*cosl(rAngle), 0.5);
		m_lrAngles[rot] = rot * rRotAngle * 180.0 / rPI;
		m_rDiamMean += m_lrDiameters[rot];
		rDiamSum2 += m_lrDiameters[rot] * m_lrDiameters[rot];
		if (rDimMin > m_lrDiameters[rot]) {
			rDimMin = m_lrDiameters[rot];
			m_bDiamMinNo = (BYTE)rot;
		}
		if (rDimMax < m_lrDiameters[rot]) {
			rDimMax = m_lrDiameters[rot];
			m_bDiamMaxNo  = (BYTE)rot;
		}
	}
	m_rDiamSigma = pow ((32.0*rDiamSum2 - m_rDiamMean*m_rDiamMean) / 992.0, 0.5);
	m_rDiamMean /= 32.0;
	m_rCscArea = m_rCscPerim = 0.0;
	for (i = 0 ; i < 64 ; ++i) {
		j = (i == 63) ? 0 : i + 1;
		vA(1) = (m_llrFerets[j][0] - m_llrFerets[i][0]) * lrFactors[0];
		vA(2) = (m_llrFerets[j][1] - m_llrFerets[i][1]) * lrFactors[1];
		vB(1) = (m_llrFerets[i][0] - m_lrCntGravity[0]) * lrFactors[0];
		vB(2) = (m_llrFerets[i][1] - m_lrCntGravity[1]) * lrFactors[1];
		vC(1) = (m_llrFerets[j][0] - m_lrCntGravity[0]) * lrFactors[0];
		vC(2) = (m_llrFerets[j][1] - m_lrCntGravity[1]) * lrFactors[1];
		rtbyte rp = ( vA.Module() + vB.Module() + vC.Module() ) / 2;
		m_rCscArea += pow ( rp*(rp-vA.Module())*(rp-vB.Module())*(rp-vC.Module()), 0.5 );
		m_rCscPerim += vA.Module ( );
	}

	dwSumX = 0;
	dwSumY = 0;
	for (dwConPtr = 0 ; dwConPtr < m_dwConLen ; ++dwConPtr) {
		dwSumX += SRCOFFSET_TO_COORDX (m_pdwContour[dwConPtr]);
		dwSumY += SRCOFFSET_TO_COORDY (m_pdwContour[dwConPtr]);
	}
	m_lrConGravity[0] = rtbyte (dwSumX) / rtbyte (m_dwConLen);
	m_lrConGravity[1] = rtbyte (dwSumY) / rtbyte (m_dwConLen);
	rX = (m_lrCntGravity[0] - m_lrConGravity[0]) * lrFactors[0];
	rY = (m_lrCntGravity[1] - m_lrConGravity[1]) * lrFactors[1];
	m_rCntConDist = pow (rX*rX + rY*rY, 0.5);
	m_rAngleContAxis = atan2 (rY, rX);
	rX = (m_lrCntGravity[0] - m_lrGryGravity[0]) * lrFactors[0];
	rY = (m_lrCntGravity[1] - m_lrGryGravity[1]) * lrFactors[1];
	m_rCntGryDist = pow (rX*rX + rY*rY, 0.5);
	m_rAngleGreyAxis = atan2 (rY, rX);

	m_dwFragments = 0;*/
}