예제 #1
0
/*
 * The main process of levenberg-marquart optimization
 */
bool intraCamLMEpiProc(const double K[9],
		const double invK[9],
		const double R0[9],
		const double t0[3],
		int n3D2D,
		const double Ms[],
		const double ms[],
		int n2D2D,
		const double Rpre[],
		const double tpre[],
		const double umspre[],
		const double ums[],
		double R_opt[9],
		double t_opt[3],
		IntraCamPoseOption* opt) {
	assert(opt);
	double param[6];

	//compute the reprojection error
	opt->npts = n3D2D;
	opt->lambda = opt->lambda0;
	opt->err0 = reprojError2(K, R0, t0, n3D2D, Ms, ms) + _epiError2(invK, n2D2D, Rpre, tpre, umspre, R0, t0, ums);
	opt->err = opt->err0;
	if (opt->verboseLM > 0)
		printf("[%d]err:%lf, lambda:%lf\n", -1, opt->err, opt->lambda);

	double R[9], t[3];
	doubleArrCopy(R, 0, R0, 9);
	doubleArrCopy(t, 0, t0, 3);

	opt->retTypeLM = 1;
	int i = 0;
	for (; i < opt->maxIterLM; i++) {
		intraCamEpiLMStep(K, invK, R, t, n3D2D, Ms, ms, n2D2D, Rpre, tpre, umspre, ums, param, opt->lambda);
		intraCamUpdatePose(R, t, param, R_opt, t_opt);
		double err = reprojError2(K, R_opt, t_opt, n3D2D, Ms, ms) + _epiError2(invK, n2D2D, Rpre, tpre, umspre, R_opt,
				t_opt, ums);
		if (opt->verboseLM > 0)
			printf("[%d]err:%lf, lambda:%lf\n", i, err, opt->lambda);
		if (fabs(err - opt->err) < opt->epsErrorChangeLM) {
			opt->retTypeLM = 0;
			break;
		}
		if (err < opt->err) {
			doubleArrCopy(R, 0, R_opt, 9);
			doubleArrCopy(t, 0, t_opt, 3);
			opt->err = err;
			opt->lambda /= 10;
		} else {
			opt->lambda *= 10;
			if (opt->lambda > 1e+4) {
				//cannot find the optimum 
				opt->retTypeLM = -1;
				break;
			}
		}
	}
	opt->nIterLM = i;
	return opt->retTypeLM >= 0;
}
bool isRegistable(MapPoint* mp, FeaturePoint* new_fp, double pixelVar) {
	if (mp->featPts.size() == 0)
		return false;

	size_t nview = mp->featPts.size();
	Mat_d Ks(nview + 1, 9), Rs(nview + 1, 9), ts(nview + 1, 3), ms(nview + 1,
			2), nms(nview + 1, 2);

	double iK[9];
	for (size_t c = 0; c < nview; c++) {
		const FeaturePoint* fp = mp->featPts[c];
		assert(fp->K && fp->cam);
		const double* K = fp->K;
		const double* R = fp->cam->R;
		const double* t = fp->cam->t;
		const double* m = fp->m;

		doubleArrCopy(Ks, c, K, 9);
		doubleArrCopy(Rs, c, R, 9);
		doubleArrCopy(ts, c, t, 3);
		doubleArrCopy(ms, c, m, 2);

		getInvK(K, iK);
		normPoint(iK, m, nms + 2 * c);
	}

	doubleArrCopy(Ks, nview, new_fp->K, 9);
	doubleArrCopy(Rs, nview, new_fp->cam->R, 9);
	doubleArrCopy(ts, nview, new_fp->cam->t, 3);
	doubleArrCopy(ms, nview, new_fp->m, 2);
	normPoint(iK, new_fp->m, nms + 2 * nview);

	double M[3], m[2];
	triangulateMultiView((int) (nview + 1), Rs, ts, nms, M);

	//check the re-projection error
	for (size_t c = 0; c < nview; c++) {
		const FeaturePoint* fp = mp->featPts[c];
		assert(fp->K && fp->cam);
		project(fp->K, fp->cam->R, fp->cam->t, M, m);
		if (dist2(m, fp->m) > pixelVar)
			return false;
	}

	project(new_fp->K, new_fp->cam->R, new_fp->cam->t, M, m);
	if (dist2(m, new_fp->m) > pixelVar)
		return false;
	return true;
}
예제 #3
0
void SingleSLAM::refineTriangulation(const FeaturePoint* fp, double M[3],
		double cov[9]) {
	double Ks[18], Rs[18], ts[6], ms[4], nms[4];

	double iK[9];
	getInvK(K.data, iK);

	const double* R0 = fp->cam->R;
	const double* t0 = fp->cam->t;

	doubleArrCopy(Ks, 0, K.data, 9);
	doubleArrCopy(Rs, 0, R0, 9);
	doubleArrCopy(ts, 0, t0, 3);
	doubleArrCopy(ms, 0, fp->m, 2);

	normPoint(iK, fp->m, nms);

	double C0[3];
	getCameraCenter(R0, t0, C0);

	const FeaturePoint* maxFp = 0;
	double maxAngle = 0;

	//search a camera pose that has the largest difference from the view direction (R0,t0)
	fp = fp->preFrame;
	while (fp && fp->cam) {
		double C[3];
		getCameraCenter(fp->cam->R, fp->cam->t, C);
		double angle = getAbsRadiansBetween(M, C0, C);
		if (angle > maxAngle) {
			maxAngle = angle;
			maxFp = fp;
		}
		fp = fp->preFrame;
	}

	if (maxFp) {
		doubleArrCopy(Ks, 1, K.data, 9);
		doubleArrCopy(Rs, 1, maxFp->cam->R, 9);
		doubleArrCopy(ts, 1, maxFp->cam->t, 3);
		doubleArrCopy(ms, 1, maxFp->m, 2);
		normPoint(iK, maxFp->m, nms + 2);
		triangulateMultiView(2, Rs, ts, nms, M);
		getTriangulateCovMat(2, Ks, Rs, ts, M, cov, Const::PIXEL_ERR_VAR);
	}
}
void updatePointUncertainty(MapPoint* mp, FeaturePoint* new_fp,
		double pixelVar) {
	if (mp->featPts.size() == 0)
		return;

	size_t nview = mp->featPts.size();
	Mat_d Ks(nview + 1, 9), Rs(nview + 1, 9), ts(nview + 1, 3), ms(nview + 1,
			2), nms(nview + 1, 2);

	double iK[9];
	for (size_t c = 0; c < nview; c++) {
		const FeaturePoint* fp = mp->featPts[c];
		assert(fp->K && fp->cam);
		const double* K = fp->K;
		const double* R = fp->cam->R;
		const double* t = fp->cam->t;
		const double* m = fp->m;

		doubleArrCopy(Ks, c, K, 9);
		doubleArrCopy(Rs, c, R, 9);
		doubleArrCopy(ts, c, t, 3);
		doubleArrCopy(ms, c, m, 2);

		getInvK(K, iK);
		normPoint(iK, m, nms + 2 * c);
	}

	doubleArrCopy(Ks, nview, new_fp->K, 9);
	doubleArrCopy(Rs, nview, new_fp->cam->R, 9);
	doubleArrCopy(ts, nview, new_fp->cam->t, 3);
	doubleArrCopy(ms, nview, new_fp->m, 2);
	normPoint(iK, new_fp->m, nms + 2 * nview);

	getTriangulateCovMat((int) (nview + 1), Ks, Rs, ts, mp->M, mp->cov,
			pixelVar);
}
예제 #5
0
int SingleSLAM::newMapPoints(std::vector<MapPoint*>& mapPts, double maxEpiErr,
		double maxNcc) {
	std::vector<FeaturePoint*> vecFeatPts;
	getUnMappedAndTrackedFeatPts(vecFeatPts, 0, Param::nMinFeatTrkLen);

	mapPts.clear();
	mapPts.reserve(4096);

	double M[3], m1[2], m2[2];

	//reconstruct 3D map points
	int numRecons = 0;
	for (size_t k = 0; k < vecFeatPts.size(); k++) {
		FeaturePoint* cur_fp = vecFeatPts[k];
		FeaturePoint* pre_fp = cur_fp;
		while (pre_fp->preFrame && pre_fp->preFrame->cam) {
			if (pre_fp->type == TYPE_FEATPOINT_DYNAMIC) {
				break;
			}
			pre_fp = pre_fp->preFrame;
		}
		if (pre_fp->type == TYPE_FEATPOINT_DYNAMIC || !pre_fp->cam)
			continue;

		normPoint(iK.data, pre_fp->m, m1);
		normPoint(iK.data, cur_fp->m, m2);

		//triangulate the two feature points to get the 3D point
		binTriangulate(pre_fp->cam->R, pre_fp->cam->t, cur_fp->cam->R,
				cur_fp->cam->t, m1, m2, M);

		if (isAtCameraBack(cur_fp->cam->R, cur_fp->cam->t, M))
			continue;

		double cov[9], org[3];
		getBinTriangulateCovMat(K.data, pre_fp->cam->R, pre_fp->cam->t, K.data,
				cur_fp->cam->R, cur_fp->cam->t, M, cov, Const::PIXEL_ERR_VAR);
		getCameraCenter(cur_fp->cam->R, cur_fp->cam->t, org);
		double s = fabs(cov[0] + cov[4] + cov[8]);
		if (dist3(org, M) < sqrt(s))
			continue;

		//check the reprojection error
		double err1 = reprojErrorSingle(K.data, pre_fp->cam->R, pre_fp->cam->t,
				M, pre_fp->m);
		double err2 = reprojErrorSingle(K.data, cur_fp->cam->R, cur_fp->cam->t,
				M, cur_fp->m);

		if (err1 < maxEpiErr && err2 < maxEpiErr) {
			//a new map point is generated
			refineTriangulation(cur_fp, M, cov);
			err1 = reprojErrorSingle(K.data, pre_fp->cam->R, pre_fp->cam->t, M,
					pre_fp->m);
			err2 = reprojErrorSingle(K.data, cur_fp->cam->R, cur_fp->cam->t, M,
					cur_fp->m);
			if (isAtCameraBack(cur_fp->cam->R, cur_fp->cam->t, M)
					|| isAtCameraBack(pre_fp->cam->R, pre_fp->cam->t, M))
				continue;
			if (err1 < maxEpiErr && err2 < maxEpiErr) {
				MapPoint* pM = new MapPoint(M[0], M[1], M[2], pre_fp->f);
				doubleArrCopy(pM->cov, 0, cov, 9);
				mapPts.push_back(pM);
				pM->lastFrame = cur_fp->f;
				for (FeaturePoint* p = cur_fp; p; p = p->preFrame)
					p->mpt = pM;

				//add the feature point
				pM->addFeature(camId, cur_fp);
				pM->setLocalStatic();

				//compute the NCC block
				pM->nccBlks[camId].computeScaled(m_lastKeyPos->imgSmall,
						m_lastKeyPos->imgScale, cur_fp->x, cur_fp->y);

				int x = max(0, min((int) cur_fp->x, m_rgb.w - 1));
				int y = max(0, min((int) cur_fp->y, m_rgb.h - 1));
				pM->setColor(m_rgb(x, y));
				numRecons++;
			}
		}
	}
	return numRecons;
}
예제 #6
0
int SingleSLAM::fastPoseUpdate3D() {
	propagateFeatureStates();
//get the feature points corresponding to the map points
	std::vector<Track2DNode*> nodes;
	int num = getStaticMappedTrackNodes(nodes);
	if (num < 5) {
		repErr(
				"[camera id:%d]intra-camera pose update failed! less than five static map points (%d)",
				camId, num);
		return -1;
	}

//choose the feature points for pose estimation
	std::vector<FeaturePoint*> featPts;
	int iChoose = chooseStaticFeatPts(featPts);
//test
	logInfo("number of chosen features :%d\n", iChoose);

	std::vector<FeaturePoint*> mappedFeatPts;
	std::vector<FeaturePoint*> unmappedFeatPts;

	mappedFeatPts.reserve(nRowBlk * nColBlk * 2);
	unmappedFeatPts.reserve(nRowBlk * nColBlk * 2);

	for (size_t i = 0; i < featPts.size(); i++) {
		if (featPts[i]->mpt)
			mappedFeatPts.push_back(featPts[i]);
		else if (featPts[i]->preFrame)
			unmappedFeatPts.push_back(featPts[i]);
	}

	//get the 2D-3D corresponding points
	int n3D2Ds = mappedFeatPts.size();
	Mat_d ms(n3D2Ds, 2), Ms(n3D2Ds, 3), repErrs(n3D2Ds, 1);
	for (int i = 0; i < n3D2Ds; i++) {
		FeaturePoint* fp = mappedFeatPts[i];
		ms.data[2 * i] = fp->x;
		ms.data[2 * i + 1] = fp->y;

		Ms.data[3 * i] = fp->mpt->x;
		Ms.data[3 * i + 1] = fp->mpt->y;
		Ms.data[3 * i + 2] = fp->mpt->z;

		repErrs.data[i] = fp->reprojErr;
	}

	//get the 2D-2D corresponding points
	int n2D2Ds = unmappedFeatPts.size();
	Mat_d ums(n2D2Ds, 2), umspre(n2D2Ds, 2), Rpre(n2D2Ds, 9), tpre(n2D2Ds, 3);
	for (int i = 0; i < n2D2Ds; i++) {
		FeaturePoint* fp = unmappedFeatPts[i];

		ums.data[2 * i] = fp->x;
		ums.data[2 * i + 1] = fp->y;

		//travel back to the frame of the first appearance
		//while (fp->preFrame) {
		fp = fp->preFrame;
		//}
		assert(fp);

		umspre.data[2 * i] = fp->x;
		umspre.data[2 * i + 1] = fp->y;

		doubleArrCopy(Rpre.data, i, fp->cam->R, 9);
		doubleArrCopy(tpre.data, i, fp->cam->t, 3);
	}

//estimate the camera pose using both 2D-2D and 3D-2D correspondences
	double R[9], t[3];
	double* cR = m_camPos.current()->R;
	double* cT = m_camPos.current()->t;

//	//test
//	logInfo("==============start of camId:%d=================\n", camId);
//	logInfo("n3D2D:%d, n2D2D:%d\n", n3D2Ds, n2D2Ds);
//
//	write(K, "/home/tsou/data/K.txt");
//	write(cR, 3, 3, "/home/tsou/data/%d_R0.txt", camId);
//	write(cT, 3, 1, "/home/tsou/data/%d_T0.txt", camId);
//	write(repErrs, "/home/tsou/data/%d_errs.txt", camId);
//	write(Ms, "/home/tsou/data/%d_Ms.txt", camId);
//	write(ms, "/home/tsou/data/%d_ms.txt", camId);
//	write(Rpre, "/home/tsou/data/%d_Rpre.txt", camId);
//	write(tpre, "/home/tsou/data/%d_tpre.txt", camId);
//	write(umspre, "/home/tsou/data/%d_umspre.txt", camId);
//	write(ums, "/home/tsou/data/%d_ums.txt", camId);
//
//	//test
//	printMat(3, 3, cR);
//	printMat(3, 1, cT);

	IntraCamPoseOption opt;
	double R_tmp[9], t_tmp[3];
	intraCamEstimate(K.data, cR, cT, n3D2Ds, repErrs.data, Ms.data, ms.data, 6,
			R_tmp, t_tmp, &opt);

	if (getCameraDistance(R_tmp, t_tmp, Rpre.data, tpre.data) > 1000) {
		opt.verboseLM = 1;
		intraCamEstimateEpi(K.data, R_tmp, t_tmp, n3D2Ds, repErrs.data, Ms.data,
				ms.data, n2D2Ds, 0, Rpre.data, tpre.data, umspre.data, ums.data,
				6, R, t, &opt);
	} else {
		doubleArrCopy(R, 0, R_tmp, 9);
		doubleArrCopy(t, 0, t_tmp, 3);
	}

//	printMat(3, 3, cR);
//	printMat(3, 1, cT);
//	printMat(3, 3, R);
//	printMat(3, 1, cT);
//	logInfo("==============end of camId:%d=================\n", camId);
//	intraCamEstimate(K.data,cR,cT,n3D2Ds, repErrs.data,Ms.data,ms.data,6.0,R,t,&opt);
//	find outliers

	int numOut = 0;
	double rm[2], var[4], ivar[4];
	for (int i = 0; i < num; i++) {
		double* pM = nodes[i]->pt->mpt->M;
		double* pCov = nodes[i]->pt->mpt->cov;
		project(K, R, t, pM, rm);
		getProjectionCovMat(K, R, t, pM, pCov, var, Const::PIXEL_ERR_VAR);
		mat22Inv(var, ivar);
		double err = mahaDist2(rm, nodes[i]->pt->m, ivar);
		if (err < 1) { //inlier
			nodes[i]->pt->reprojErr = err;
			seqTriangulate(K, R, t, nodes[i]->pt->m, pM, pCov,
					Const::PIXEL_ERR_VAR);
			project(K, R, t, pM, rm);
			getProjectionCovMat(K, R, t, pM, pCov, var, Const::PIXEL_ERR_VAR);
			mat22Inv(var, ivar);
			err = mahaDist2(rm, nodes[i]->pt->m, ivar);
			if (err >= 1) {
				nodes[i]->pt->mpt->setFalse();
			}
		} else {
			//outliers
			numOut++;
			double repErr = dist2(rm, nodes[i]->pt->m);
			nodes[i]->pt->reprojErr = repErr;
			nodes[i]->pt->mpt->setUncertain();
		}
	}
	CamPoseItem* camPos = m_camPos.add(currentFrame(), camId, R, t);
	updateCamParamForFeatPts(K, camPos);

	return num;
}
예제 #7
0
bool intraCamCovEstimate(const double K[9],
		const double R0[9],
		const double t0[3],
		int npts,
		const double prevErrs[],
		const double covs[],
		const double Ms[],
		const double ms[],
		const double tau,
		double R_opt[9],
		double t_opt[3],
		IntraCamPoseOption* opt) {

	if (opt->verboseRW)
		printf("=============start of intra-camera pose estimation ===========\n");

	double* Ws = new double[npts];
	for (int i = 0; i < npts; i++) {
		if (prevErrs == 0)
			Ws[i] = 1.0;
		else {
			double e = fabs(prevErrs[i]);
			if (e >= tau) {
				Ws[i] = 0;
			} else {
				e /= tau;
				e = 1 - e * e;
				Ws[i] = e * e;
			}
		}
	}

	double R[9], t[3];
	doubleArrCopy(R, 0, R0, 9);
	doubleArrCopy(t, 0, t0, 3);

	bool ret = true;
	int k = 0;
	opt->errRW = -1;
	for (; k < opt->maxIterRW; k++) {
		if (!intraCamCovWeightedLMProc(K, R, t, npts, covs, Ws, Ms, ms, R_opt, t_opt, opt)) {
			ret = false;
			goto returnPoint;
		}
		opt->lambda0 = opt->lambda;
		if (opt->errRW < 0)
			opt->errRW = opt->err;
		else {
			if (fabs(opt->err - opt->errRW) < opt->epsErrorChangeRW) {
				ret = true;
				goto returnPoint;
			} else
				opt->errRW = opt->err;
		}

		if (opt->verboseRW) {
			printf(">>rw:[%d]:err:%lf\n", k, opt->errRW);
		}

		doubleArrCopy(R, 0, R_opt, 9);
		doubleArrCopy(t, 0, t_opt, 3);

		//compute the new weights
		for (int i = 0; i < npts; i++) {
			double rm[2];
			project(K, R, t, Ms + 3 * i, rm);
			double dx = rm[0] - ms[2 * i];
			double dy = rm[1] - ms[2 * i + 1];
			double e = sqrt(dx * dx + dy * dy);
			if (e >= tau)
				Ws[i] = 0;
			else {
				e /= tau;
				e = 1 - e * e;
				Ws[i] = e * e;
			}
		}
	}
	returnPoint: opt->nIterRW = k;
	delete[] Ws;

	if (opt->verboseRW)
		printf("-------------end of intra-camera pose estimation ---------\n");
	return ret;
}
예제 #8
0
bool intraCamCovWeightedLMProc(const double K[9],
		const double R0[9],
		const double t0[3],
		int npts,
		const double covs[],
		const double Ws[],
		const double Ms[],
		const double ms[],
		double R_opt[9],
		double t_opt[3],
		IntraCamPoseOption* opt) {
	assert(opt);
	double param[6];

	//compute the reprojection error
	opt->npts = npts;
	opt->lambda = opt->lambda0;
	opt->err0 = reprojError2CovWeighted(K, R0, t0, npts, covs, Ws, Ms, ms);
	opt->err = opt->err0;
	if (opt->verboseLM > 0)
		printf("[%d]err:%lf, lambda:%lf, (%lf %lf %lf %lf %lf %lf)\n", -1, opt->err, opt->lambda, param[0], param[1],
				param[2], param[3], param[4], param[5]);

	double R[9], t[3], R_tmp[9], t_tmp[3];
	doubleArrCopy(R, 0, R0, 9);
	doubleArrCopy(t, 0, t0, 3);

	opt->retTypeLM = 1;
	int i = 0;
	double err = opt->err0;
	for (; i < opt->maxIterLM; i++) {
		intraCamCovWeightedLMStep(K, R, t, npts, covs, Ws, Ms, ms, param, opt->lambda);
		intraCamUpdatePose(R, t, param, R_opt, t_opt);

		if (param[0] * param[0] + param[1] * param[1] + param[2] * param[2] + param[3] * param[3] + param[4] * param[4]
				+ param[5] * param[5] < opt->epsParamChangeLM) {
			doubleArrCopy(R, 0, R_opt, 9);
			doubleArrCopy(t, 0, t_opt, 3);
			opt->retTypeLM = 0;
			break;
		}

		err = reprojError2CovWeighted(K, R_opt, t_opt, npts, covs, Ws, Ms, ms);
		if (opt->verboseLM > 0)
			printf("[%d]err:%lf, lambda:%lf, (%lf %lf %lf %lf %lf %lf)\n", i, err, opt->lambda, param[0], param[1],
					param[2], param[3], param[4], param[5]);
		if (fabs(err - opt->err) < opt->epsErrorChangeLM) {
			opt->retTypeLM = 0;
			break;
		}
		if (err <= opt->err) {
			doubleArrCopy(R, 0, R_opt, 9);
			doubleArrCopy(t, 0, t_opt, 3);
			doubleArrCopy(R_tmp, 0, R_opt, 9);
			doubleArrCopy(t_tmp, 0, t_opt, 3);
			opt->err = err;
			opt->lambda /= 10;
		} else {
			opt->lambda *= 10;
			if (opt->lambda > 1e+18) {
				//cannot find the optimum 
				opt->retTypeLM = -1;
				break;
			}
		}
	}
	if (opt->retTypeLM == -1) {
		doubleArrCopy(R_opt, 0, R_tmp, 9);
		doubleArrCopy(t_opt, 0, t_tmp, 3);
	}
	opt->err = err;
	opt->nIterLM = i;
	if (opt->verboseLM)
		opt->printLM();
	return opt->retTypeLM >= 0;
}
예제 #9
0
bool intraCamEstimateEpi(const double K[9],
		const double R0[9],
		const double t0[3],
		int n3D2Ds,
		const double preRepErrs[],
		const double Ms[],
		const double ms[],

		int n2D2Ds,
		const double preEpiErrs[],
		const double Rpre[],
		const double tpre[],
		const double umspre[],
		const double ums[],

		const double tau,
		double R_opt[9],
		double t_opt[3],
		IntraCamPoseOption* opt) {

	double invK[9];
	mat33Inv(K, invK);

	if (opt->verboseRW)
		printf("=============start of intra-camera pose estimation ===========\n");

	double* Ws = new double[n3D2Ds];
	for (int i = 0; i < n3D2Ds; i++) {
		if (preRepErrs == 0)
			Ws[i] = 1.0;
		else {
			double e = fabs(preRepErrs[i]);
			if (e >= tau) {
				Ws[i] = 0;
			} else {
				e /= tau;
				e = 1 - e * e;
				Ws[i] = e * e;
			}
		}
	}
	double* uWs = new double[n2D2Ds];
	for (int j = 0; j < n2D2Ds; j++) {
		if (preEpiErrs == 0) {
			uWs[j] = 1.0;
		} else {
			double e = fabs(preEpiErrs[j]);
			if (e >= tau) {
				uWs[j] = 0;
			} else {
				e /= tau;
				e = 1 - e * e;
				uWs[j] = e * e;
			}
		}
	}

	double R[9], t[3];
	doubleArrCopy(R, 0, R0, 9);
	doubleArrCopy(t, 0, t0, 3);

	bool ret = true;
	int k = 0;
	opt->errRW = -1;
	for (; k < opt->maxIterRW; k++) {
		intraCamLMEpiWeightedProc(K, invK, R, t, n3D2Ds, Ws, Ms, ms, n2D2Ds, Rpre, tpre, uWs, umspre, ums, R_opt,
				t_opt, opt);

		opt->lambda0 = opt->lambda;
		if (opt->errRW < 0)
			opt->errRW = opt->err;
		else {
			if (fabs(opt->err - opt->errRW) < opt->epsErrorChangeRW) {
				ret = true;
				goto returnPoint;
			} else
				opt->errRW = opt->err;
		}
		if (opt->verboseRW) {
			printf(">> rw:[%d]:err:%lf\n", k, opt->errRW);
		}

		doubleArrCopy(R, 0, R_opt, 9);
		doubleArrCopy(t, 0, t_opt, 3);

		//compute the new weights
		for (int i = 0; i < n3D2Ds; i++) {
			double rm[2];
			project(K, R, t, Ms + 3 * i, rm);
			double dx = rm[0] - ms[2 * i];
			double dy = rm[1] - ms[2 * i + 1];
			double e = sqrt(dx * dx + dy * dy);
			if (e >= tau)
				Ws[i] = 0;
			else {
				e /= tau;
				e = 1 - e * e;
				Ws[i] = e * e;
			}
		}
	}
	returnPoint: opt->nIterRW = k;
	delete[] Ws;

	if (opt->verboseRW) {
		printf("err:%lf-->%lf\n", opt->err0, opt->err);
		printf("-------------end of intra-camera pose estimation ---------\n");
	}
	return ret;
}
예제 #10
0
bool intraCamLMEpiWeightedProc(const double K[9],
		const double invK[9],
		const double R0[9],
		const double t0[3],
		int n3D2D,
		const double Ws[],
		const double Ms[],
		const double ms[],
		int n2D2D,
		const double Rpre[],
		const double tpre[],
		const double uWs[],
		const double umspre[],
		const double ums[],
		double R_new[9],
		double t_new[3],
		IntraCamPoseOption* opt) {
	assert(opt);
	double param[6];

	//compute the reprojection error
	opt->npts = n3D2D;
	opt->lambda = opt->lambda0;

	double err1 = reprojError2Weighted(K, R0, t0, n3D2D, Ws, Ms, ms);
	double err2 = _epiError2Weighted(invK, n2D2D, uWs, Rpre, tpre, umspre, R0, t0, ums);

	opt->err0 = err1 + err2;
	opt->err = opt->err0;

	if (opt->verboseLM > 0) {
		printf("[%d]err:%lf (%lf,%lf), lambda:%lf\n", -1, opt->err, err1, err2, opt->lambda);
	}

	double R[9], t[3], R_opt[9], t_opt[3];
	doubleArrCopy(R, 0, R0, 9);
	doubleArrCopy(t, 0, t0, 3);

	opt->retTypeLM = 1;
	int i = 0;
	for (; i < opt->maxIterLM; i++) {
		intraCamEpiWeightedLMStep(K, invK, R, t, n3D2D, Ws, Ms, ms, n2D2D, Rpre, tpre, uWs, umspre, ums, param,
				opt->lambda);
		intraCamUpdatePose(R, t, param, R_new, t_new);

		err1 = reprojError2Weighted(K, R_new, t_new, n3D2D, Ws, Ms, ms);
		err2 = _epiError2Weighted(invK, n2D2D, uWs, Rpre, tpre, umspre, R_new, t_new, ums);

		double err = err1 + err2;

		if (opt->verboseLM > 0)
			printf("[%d]err:%lf (%lf,%lf), lambda:%lf\n", i, err, err1, err2, opt->lambda);

		if (fabs(err - opt->err) < opt->epsErrorChangeLM) {
			opt->retTypeLM = 0;
			break;
		}
		if (err < opt->err) {
			//accept the new parameter
			doubleArrCopy(R, 0, R_new, 9);
			doubleArrCopy(t, 0, t_new, 3);
			doubleArrCopy(R_opt, 0, R_new, 9);
			doubleArrCopy(t_opt, 0, t_new, 3);
			opt->err = err;
			opt->lambda /= 10;
		} else {
			opt->lambda *= 100;
			if (opt->lambda > 1e+4) {
				//cannot find the optimum 
				opt->retTypeLM = -1;
				break;
			}
		}
	}
	//	if (opt->retTypeLM == -1) {
	//		doubleArrCopy(R_new, 0, R_opt, 9);
	//		doubleArrCopy(t_new, 0, t_opt, 3);
	//	}
	opt->nIterLM = i;
	return opt->retTypeLM >= 0;
}