void GLImagePane::drawEpipolarLine(ImgRGB& img) {
	assert(s_clicked_camid >= 0);
	const double* R0 = m_pSLAM->slam[s_clicked_camid].m_camPos.current()->R;
	const double* t0 = m_pSLAM->slam[s_clicked_camid].m_camPos.current()->t;
	const double* iK0 = m_pSLAM->slam[s_clicked_camid].iK.data;

	const double* R1 = m_pSLAM->slam[m_camId].m_camPos.current()->R;
	const double* t1 = m_pSLAM->slam[m_camId].m_camPos.current()->t;
	const double* iK1 = m_pSLAM->slam[m_camId].iK.data;

	double E[9], F[9];
	formEMat(R0, t0, R1, t1, E);
	getFMat(iK1, iK0, E, F);

	double l[3];
	double fx, fy;
	if (s_clicked_mappt) {
		if (!s_clicked_mappt->pFeatures[s_clicked_camid])
			return;
		fx = s_clicked_mappt->pFeatures[s_clicked_camid]->m[0];
		fy = s_clicked_mappt->pFeatures[s_clicked_camid]->m[1];
	} else {
		fx = s_clicked_featPt->x;
		fy = s_clicked_featPt->y;
	}
	computeEpipolarLine(F, fx, fy, l);
	drawLine(img, l, 255, 255, 255);
}
double _epiError2(const double invK[],
		int n2D2D,
		const double Rpre[],
		const double tpre[],
		const double umspre[],
		const double R[],
		const double t[],
		const double ums[]) {

	const double* pms1 = umspre;
	const double* pms2 = ums;
	const double* pRpre = Rpre;
	const double* ptpre = tpre;

	double s = 0;
	for (int j = 0; j < n2D2D; j++, pms1 += 2, pms2 += 2, pRpre += 9, ptpre += 3) {
		//compute the epipolar error
		double E[9], F[9];
		formEMat(R, t, pRpre, ptpre, E);
		getFMat(invK, invK, E, F);
		double err = epipolarError(F, pms2, pms1);
		s += err * err;
	}
	return s;
}
static void _epiDistSO3JacobiNum(const double invK[9],
		const double Rpre[9],
		const double Tpre[3],
		const double mpre[2],
		const double R[9],
		const double T[3],
		const double m[2],
		const double err0,
		double Jw[3]) {

	double w[3] = { 0, 0, 0 };
	double dR[9], R1[9], E[9], F[9];

	const double eps = 1e-16;
	w[0] = eps;
	getSO3ExpMap(w, dR);
	mat33AB(R, dR, R1);

	formEMat(Rpre, Tpre, R1, T, E);
	getFMat(invK, invK, E, F);

	double err = epipolarError(F, m, mpre);
	Jw[0] = (err - err0) / eps;

	w[0] = 0;
	w[1] = eps;
	getSO3ExpMap(w, dR);
	mat33AB(R, dR, R1);

	formEMat(Rpre, Tpre, R1, T, E);
	getFMat(invK, invK, E, F);

	err = epipolarError(F, m, mpre);
	Jw[1] = (err - err0) / eps;

	w[1] = 0;
	w[2] = eps;
	getSO3ExpMap(w, dR);
	mat33AB(R, dR, R1);

	formEMat(Rpre, Tpre, R1, T, E);
	getFMat(invK, invK, E, F);

	err = epipolarError(F, m, mpre);
	Jw[2] = (err - err0) / eps;
}
static void _epiDistTJacobiNum(const double invK[9],
		const double Rpre[9],
		const double Tpre[3],
		const double mpre[2],
		const double R[9],
		const double T[3],
		const double m[2],
		const double err0,
		double Jt[3]) {

	double E[9], F[9];
	const double eps = 1e-16;
	double T1[3] = { T[0] + eps, T[1], T[2] };

	formEMat(Rpre, Tpre, R, T1, E);
	getFMat(invK, invK, E, F);

	double err = epipolarError(F, m, mpre);
	Jt[0] = (err - err0) / eps;

	T1[0] = T[0];
	T1[1] = T[1] + eps;

	formEMat(Rpre, Tpre, R, T1, E);
	getFMat(invK, invK, E, F);

	err = epipolarError(F, m, mpre);
	Jt[1] = (err - err0) / eps;

	T1[1] = T[1];
	T1[2] = T[2] + eps;

	formEMat(Rpre, Tpre, R, T1, E);
	getFMat(invK, invK, E, F);

	err = epipolarError(F, m, mpre);
	Jt[2] = (err - err0) / eps;
}
Beispiel #5
0
int SingleSLAM::detectDynamicFeaturePoints(int maxLen, int minLen,
		int minOutNum, double maxEpiErr) {
	std::vector<Track2DNode*> nodes;
	getUnMappedAndDynamicTrackNodes(nodes, minLen);

	int k = 0;
	for (size_t i = 0; i < nodes.size(); i++) {
		FeaturePoint* fp = nodes[i]->pt;
		const double* R0 = fp->cam->R;
		const double* t0 = fp->cam->t;
		const double* m0 = fp->m;
		assert(fp->cam);

		int nOut = 0;
		double E[9], F[9];
		int f = 0;
		for (; fp && nOut <= minOutNum && f < maxLen; fp = fp->preFrame) {
			if (!fp->cam)
				continue;
			const double* R1 = fp->cam->R;
			const double* t1 = fp->cam->t;
			const double* m1 = fp->m;

			formEMat(R1, t1, R0, t0, E);
			getFMat(iK.data, iK.data, E, F);

			if (epipolarError(F, m0, m1) >= maxEpiErr) {
				nOut++;
			}
		}

		if (nOut > minOutNum) {
			nodes[i]->pt->type = TYPE_FEATPOINT_DYNAMIC;
			k++;
		} else if (!nodes[i]->pt->mpt) {
			nodes[i]->pt->type = TYPE_FEATPOINT_STATIC;
		}
	}
	return k;
}
double _epiError2Weighted(const double invK[],
		int n2D2D,
		const double uWs[],
		const double Rpre[],
		const double tpre[],
		const double umspre[],
		const double R[],
		const double t[],
		const double ums[]) {

	const double* pms1 = umspre;
	const double* pms2 = ums;
	const double* pRpre = Rpre;
	const double* ptpre = tpre;

	double E[9], F[9], l[3];
	formEMat(R, t, pRpre, ptpre, E);
	getFMat(invK, invK, E, F);

	double s = 0;
	for (int j = 0; j < n2D2D; j++, pms1 += 2, pms2 += 2) {
		computeEpipolarLine(F, pms1[0], pms1[1], l);

		double A = l[0];
		double B = l[1];
		double C = l[2];

		double x0 = pms2[0];
		double y0 = pms2[1];

		double lambda = (-A * x0 - B * y0 - C);
		double err2 = lambda * lambda / (A * A + B * B);

		s += err2 * uWs[j];
	}
	return s;
}
static void intraCamEpiLMStep(const double K[9], const double invK[9], const double R[9], //current parameter (rotation and translation)
		const double t[3],
		int n2D3Ds, //number of 2D-3D correspondences
		const double Ms[], //3D points
		const double ms[], //2D points
		int n2D2Ds, //number of 2D-2D correspondences
		const double uRpre[], //camera poses at former frames
		const double utpre[],
		const double umspre[], //unmapped feature points at former frames
		const double ums[], //unmapped feature points the current frames
		double param[6], //new parameter
		const double lambda // damping coefficient
) {

	double sA[36], A[36], invSA[36], sB[6], B[6], rm[2], rerr[2], eerr;
	double Jw[6], Jt[6];

	memset(sA, 0, sizeof(double) * 36);
	memset(sB, 0, sizeof(double) * 6);

	const double* pMs = Ms;
	const double* pms = ms;
	for (int i = 0; i < n2D3Ds; i++, pMs += 3, pms += 2) {
		project(K, R, t, pMs, rm);
		_perspectiveSO3JacobiNum(K, R, t, pMs, pms, rm, Jw);
		_perspectiveTJacobiNum(K, R, t, pMs, pms, rm, Jt);

		double J[12] = { Jw[0], Jw[1], Jw[2], Jt[0], Jt[1], Jt[2], Jw[3], Jw[4], Jw[5], Jt[3], Jt[4], Jt[5] };
		matATB(2, 6, 2, 6, J, J, A);
		mat66sum(sA, A, sA);

		rerr[0] = -rm[0] + pms[0];
		rerr[1] = -rm[1] + pms[1];

		matATB(2, 6, 2, 1, J, rerr, B);
		mat16sum(sB, B, sB);
	}

	const double* pms1 = umspre;
	const double* pms2 = ums;
	const double* pRpre = uRpre;
	const double* ptpre = utpre;

	for (int j = 0; j < n2D2Ds; j++, pms1 += 2, pms2 += 2, pRpre += 9, ptpre += 3) {
		//compute the epipolar error
		double E[9], F[9], Ew[3], Et[3];
		formEMat(R, t, pRpre, ptpre, E);
		getFMat(invK, invK, E, F);
		eerr = epipolarError(F, pms2, pms1);

		_epiDistSO3JacobiNum(invK, pRpre, ptpre, pms1, R, t, pms2, eerr, Ew);
		_epiDistTJacobiNum(invK, pRpre, ptpre, pms1, R, t, pms2, eerr, Et);

		double J[6] = { Ew[0], Ew[1], Ew[2], Et[0], Et[1], Et[2] };
		matATB(1, 6, 1, 6, J, J, A);
		mat66sum(sA, A, sA);

		B[0] = -J[0] * eerr;
		B[1] = -J[1] * eerr;
		B[2] = -J[2] * eerr;
		B[3] = -J[3] * eerr;
		B[4] = -J[4] * eerr;
		B[5] = -J[5] * eerr;

		mat16sum(sB, B, sB);
	}

	sA[0] += lambda;
	sA[7] += lambda;
	sA[14] += lambda;
	sA[21] += lambda;
	sA[28] += lambda;
	sA[35] += lambda;

	matInv(6, sA, invSA);
	matAB(6, 6, 6, 1, invSA, sB, param);
}