Esempio n. 1
0
cv::Mat mu::dlt(const std::vector<cv::Mat_<double> > &points3D, const std::vector<cv::Matx31d> &points2D) {

    cv::Mat A(2 * points3D.size(), 12, CV_64F);

    double *p = A.ptr<double>(0);

    //Compute A
    for (uint i = 0; i < points3D.size(); ++i) {
        // TODO: Put matrix from theory
        cv::Matx41d p3D(points3D.at(i).at<double>(0), points3D.at(i).at<double>(1), points3D.at(i).at<double>(2), 1);
        cv::Point2d p2D(points2D.at(i).val[0], points2D.at(i).val[1]);

        // first row
        *p++ = p3D.val[0];
        *p++ = p3D.val[1];
        *p++ = p3D.val[2];
        *p++ = 1;
        *p++ = 0;
        *p++ = 0;
        *p++ = 0;
        *p++ = 0;
        *p++ = -(p2D.x * p3D.val[0]);
        *p++ = -(p2D.x * p3D.val[1]);
        *p++ = -(p2D.x * p3D.val[2]);
        *p++ = -p2D.x;

        // second row
        *p++ = 0;
        *p++ = 0;
        *p++ = 0;
        *p++ = 0;
        *p++ = p3D.val[0];
        *p++ = p3D.val[1];
        *p++ = p3D.val[2];
        *p++ = 1;
        *p++ = -(p2D.y * p3D.val[0]);
        *p++ = -(p2D.y * p3D.val[1]);
        *p++ = -(p2D.y * p3D.val[2]);
        *p++ = -p2D.y;
    }

    cv::SVD svd(A, cv::SVD::MODIFY_A | cv::SVD::FULL_UV);
    cv::Mat Hn = svd.vt.row(11).reshape(0, 3); // H12

    return Hn;
}
Esempio n. 2
0
bool Viewer::on_eventbox_extrinsics_clicked(GdkEventButton * event)
{

	if (mCalibration){

		pthread_mutex_lock(&mutex);
		bool res = mCalibration->addPatternPixel (
				Eigen::Vector3d ((int) event->x, (int) event->y, 1.0), mDepthVector);

		if (res == false)
		{
			Eigen::Vector3d p2D ((int) event->x, (int) event->y, 1.0);
			mCalibration->test(p2D, mDepthVector);
		}

		pthread_mutex_unlock(&mutex);
	}
	return true;
}
Esempio n. 3
0
void Run2D::runPoisson2D(int argc, char** argv) {
	Device2D dev2D = createDevice2D(argc, argv);
	Poisson2D p2D(dev2D);
    std::vector<double> vtgArray =p2D.rangeByStep(io2D.vtgArray[0], io2D.vtgArray[1], io2D.vtgArray[2]);
    std::vector<double> vbgArray =p2D.rangeByStep(io2D.vbgArray[0], io2D.vbgArray[1], io2D.vbgArray[2]);
    std::vector<double> vdsArray =p2D.rangeByStep(io2D.vdsArray[0], io2D.vdsArray[1], io2D.vdsArray[2]);
    std::vector<double> vssArray =p2D.rangeByStep(io2D.vssArray[0], io2D.vssArray[1], io2D.vssArray[2]);

    std::vector<int> sdIndex = p2D.sourceDrain2DLayerIndex(io2D.connect2Drain, io2D.connect2Source);
    std::cout << "drain index: " << sdIndex[0] << " , source index: " << sdIndex[1] << std::endl;

    std::cout << " ***** Poisson2D is started." << std::endl;
    Capacitance capa;
    GateEfficiency gE;
    GateEfficiency gE2; // for gate efficiency at the edge.

    /* [different bias][different bands][band data at different point] */
    std::vector< std::vector< std::vector<double> > > band2DPerBias;

    for (double Vbg : vbgArray) {
    	for (double Vss : vssArray) {
    		for (double Vds : vdsArray) {

    			// used to calculate gate efficiency: /* [different Vtg][different bands][band data at different point] */
    			std::vector< std::vector< std::vector<double> > > band2DPerVtg;

    			for (double Vtg : vtgArray) {

    				if (io2D.terminalConnect[0] == true)  // Vbg = Vtg always
    					Vbg = Vtg;

    				std::cout << "Vbg = " << Vbg << " V; " << "Vtg = " << Vtg << " V; "
    						<< "Vds = " << Vds << " V; " << "Vss = " << Vss << std::endl;

    				// Gate bias
    				p2D.setGateBias_2D(io2D.gateBiasMap(Vtg, Vbg));

    				// Fermi levels
    				/* Vds: Caution: the negative sign is taken into consideration within createFermiLevelMap */
    				p2D.setFLnArray_2D(p2D.createFermiLevelMap(io2D.connect2Drain, Vds, io2D.connect2Source, Vss));
    				p2D.setFLpArray_2D(p2D.createFermiLevelMap(io2D.connect2Drain, Vds, io2D.connect2Source, Vss)); // when equilibrum, Flp = Fln

    				p2D.runPoisson2D(io2D.voltageErr, io2D.carrierConcenErr, io2D.magicNum,  true);
    				std::cout << "2D Poisson Finished." << std::endl;

    				// Extract Data
    				ExtractData eD;
    				eD.bandAndCharge2D(p2D, dev2D); // first read into band info for this bias

    				// Store the bandAlignment for selected layer for gate efficiency calculation
    				if (Vss == 0) {
    					eD.bASemiOnly2D(sdIndex);
    					band2DPerVtg.push_back(eD.bandByLayer); /* [different Vtg][different bands][band data at different point] */
    					band2DPerBias.push_back(eD.bandByLayer); /* [different bias][different bands][band data at different point] */
    				}

    				// read top gate charge into capa for later capacitance calculation
    				capa.readCharge(Vtg, Vbg, Vds, Vss, eD.topGateCharge2D(dev2D, io2D.topGateArea)); // read in all the data needed for capa
    			}

    			if (Vss == 0) {
    				// measure near the center of the channel
    				gE.calGateEfficiency(Vbg, Vds, io2D.vtgArray[0], io2D.vtgArray[2], 100, 100, 10, 100, band2DPerVtg);
    				// measure at the edge for Thin-TFET (SO, only use it for Thin-TFET!!)
    				gE2.calGateEfficiency(Vbg, Vds, io2D.vtgArray[0], io2D.vtgArray[2],
    						io2D.blockPoint[0] + io2D.blockPoint[1], io2D.blockPoint[0] + io2D.blockPoint[1], // for ThinTFET, valence band in bottom, conduction band in top
							10, 100, band2DPerVtg);
    			}

    		}
    	}
    	if (io2D.terminalConnect[0] == true)  // Vbg = Vtg always
    		break;
    }

    capa.calCggCgsCgd(vtgArray, vbgArray, vdsArray, vssArray, io2D.terminalConnect); // calculate capacitance

    /**
     * Output
     */
      io2D.writeBandsinSemi(io2D.devName+"_"+io2D.userCom+"_Bands", vtgArray, vdsArray, vbgArray, band2DPerBias);
//    io2D.writeCapaMap(io2D.devName+"_"+io2D.userCom+"_Cgs", capa.getCgsMap());
//    io2D.writeCapaMap(io2D.devName+"_"+io2D.userCom+"_Cgd", capa.getCgdMap());
//    io2D.writeCapaMap(io2D.devName+"_"+io2D.userCom+"_Cgg", capa.getCggMap());
//    io2D.writeGateEffMap(io2D.devName+"_"+io2D.userCom+"_GateEfficiency_atChannelCenter", gE.getGateEffMap());
//    io2D.writeGateEffMap(io2D.devName+"_"+io2D.userCom+"_GateEfficiency_atEdgeThinTFET", gE2.getGateEffMap());
}
/**
 * @brief Generates a optimised point cloud from a collection of processed keyframes using sparse bundle adjustment.
 * @param allFrames A vector containing keyframes which have been completely processed.
 * @param outputCloud The cloud generated from the keyframes.
 */
void utils::calculateSBACloud(std::vector<KeyframeContainer>& allFrames,boost::shared_ptr<pcl::PointCloud<pcl::PointXYZRGB> >& outputCloud)
{
	sba::SysSBA bundleAdjuster;
	//set the verbosity of the bundle adjuster
#ifndef NDEBUG
	bundleAdjuster.verbose=100;
#else
	bundleAdjuster.verbose=0;
#endif

	//a list of keypoints that already have been added to the SBA system
	std::vector<std::pair<int,uint> > addedPoints; //(frameID,keypointIndex)
	//maps frame IDs to frame index in the vector
	std::map<int,uint> ID2Ind;
	for(uint f=0;f<allFrames.size();++f) ID2Ind[allFrames[f].ID]=f;
	//maps the frame vector index to the node vector index
	std::map<uint,int> fInd2NInd;

	//count the number of 2D/3D-points and camera nodes if in debug mode
#ifndef NDEBUG
	uint nrP3D=0;
	uint nrP2D=0;
	uint nrC=0;
#endif

	//add every valid frame as a camera node to the sba system
	for(uint f=0;f<allFrames.size();++f)
	{
		if(!allFrames[f].invalid)
		{
			//get rotation and translation from the projection matrix
			Eigen::Matrix3d rot;
			cv::Mat_<double> cvT;
			Eigen::Vector4d t;
			//get rotation
			for(int x=0;x<3;++x) for(int y=0;y<3;++y) rot(x,y)=allFrames[f].projectionMatrix(x,y);
			//solve for translation
			cv::solve(allFrames[f].projectionMatrix(cv::Range(0,3),cv::Range(0,3)),allFrames[f].projectionMatrix(cv::Range(0,3),cv::Range(3,4)),cvT);
			//save translation
			for(int x=0;x<3;++x) t(x)=-cvT(x,0);
			t(3)=1.0;

			//convert rotation to quaternion
			Eigen::Quaterniond qrot(rot);
			qrot.normalize();

			//convert camera calibration matrix
			frame_common::CamParams cameraParameters;
			cameraParameters.fx=allFrames[f].cameraCalibration(0,0);
			cameraParameters.fy=allFrames[f].cameraCalibration(1,1);
			cameraParameters.cx=allFrames[f].cameraCalibration(0,2);
			cameraParameters.cy=allFrames[f].cameraCalibration(1,2);
			cameraParameters.tx=0.0;

			//add the frame as a camera node
			fInd2NInd[f]=bundleAdjuster.addNode(t,qrot,cameraParameters,false);
#ifndef NDEBUG
			++nrC;
#endif
		}
		else
			fInd2NInd[f]=-1;
	}

	//add the points to the correct nodes
	for(uint f=0;f<allFrames.size();++f)
	{
		if(!allFrames[f].invalid)
		{
			//add the points
			for(uint m=0;m<allFrames[f].matches.size();++m)
			{
				std::pair<int,uint> myP(allFrames[f].ID,m);
				bool goodToAdd=!utils::vectorContainsElement(addedPoints,myP);

				//point hasn't been added yet
				if(goodToAdd)
				{
					//check if the point has valid depth information
					float depth=allFrames[f].depthImg.image.at<float>(allFrames[f].keypoints[m].pt.y,allFrames[f].keypoints[m].pt.x);
					if(isnan(depth)==0)
					{
						//find the largest completely connected component emanating from this point (clique)
						std::vector<std::pair<int,uint> > pointsComplete;
						pointsComplete.push_back(std::pair<int,uint>(allFrames[f].ID,m));
						//check all matches of the point if they haven't been added yet and their frame is valid
						for(uint o=0;o<allFrames[f].matches[m].size();++o)
						{
							std::pair<int,uint> newElement(allFrames[f].matches[m][o].first.val[0],allFrames[f].matches[m][o].first.val[1]);
							if(!utils::vectorContainsElement(addedPoints,newElement) && !allFrames[ID2Ind[newElement.first]].invalid)
								pointsComplete.push_back(newElement);
						}

						//weed out all points that are not completely connected
						while(pointsComplete.size()>1)
						{
							//find the point with the fewest connections (if the component is completely connected all points have the same number of connections)
							uint minCorrespondences=pointsComplete.size();
							uint worstInd=0;
							for(uint i=0;i<pointsComplete.size();++i)
							{
								//count the number of connections that this point has
								uint fInd=ID2Ind[pointsComplete[i].first];
								uint myCorr=0;
								for(uint q=0;q<allFrames[fInd].matches.size();++q)
									for(uint r=0;r<allFrames[fInd].matches[q].size();++r)
									{
										std::pair<int,uint> tmpElement(allFrames[fInd].matches[q][r].first.val[0],allFrames[fInd].matches[q][r].first.val[1]);
										if(utils::vectorContainsElement(pointsComplete,tmpElement))
											++myCorr;
									}

								//save this point if it is the current worst
								if(myCorr<minCorrespondences)
								{
									minCorrespondences=myCorr;
									worstInd=i;
								}
							}

							//if the worst point has not the maximal number of connections erase it, else break as all points have the maximal number of connections
							if(minCorrespondences<pointsComplete.size()-1)
							{
								pointsComplete.erase(pointsComplete.begin()+worstInd);
							}
							else
								break;
						}

						//now pointsComplete contains the clique if the clique has more than one isolated point, write the points to the system
						if(pointsComplete.size()>1)
						{
							//calculate the 3D point and add it to the system
							cv::Mat_<double> p2D(2,1,0.0);
							p2D(0,0)=allFrames[f].keypoints[m].pt.x;
							p2D(1,0)=allFrames[f].keypoints[m].pt.y;
							cv::Mat_<double> p3D=reprojectImagePointTo3D(p2D,allFrames[f].cameraCalibration,allFrames[f].projectionMatrix,depth);
							Eigen::Vector4d newPoint;
							for(uint x=0;x<4;++x) newPoint(x)=p3D(x,0);
							int pointIndex=bundleAdjuster.addPoint(newPoint);
#ifndef NDEBUG
							++nrP3D;
#endif
							//add all image points corresponding to the 3D point to the system
							for(uint i=0;i<pointsComplete.size();++i)
							{
								uint fInd=ID2Ind[pointsComplete[i].first];
								Eigen::Vector2d imgPoint;
								imgPoint(0)=allFrames[fInd].keypoints[pointsComplete[i].second].pt.x;
								imgPoint(1)=allFrames[fInd].keypoints[pointsComplete[i].second].pt.y;
								bundleAdjuster.addMonoProj(fInd2NInd[fInd],pointIndex,imgPoint);
#ifndef NDEBUG
								++nrP2D;
#endif
							}
						}
					}
				}
			}
		}
	}

#ifndef NDEBUG
	ROS_INFO("C: %u;3D: %u;2D: %u",nrC,nrP3D,nrP2D);
#endif

	//remove bad tracks
	bundleAdjuster.calcCost();
	bundleAdjuster.removeBad(2);
	bundleAdjuster.reduceTracks();

	//run 100 iterations of sba
	bundleAdjuster.doSBA(100,1e-3, SBA_SPARSE_CHOLESKY);

	//save the new projective matrix calculated with sba
	for(uint f=0;f<allFrames.size();++f)
		if(!allFrames[f].invalid)
			for(int x=0;x<3;++x) for(int y=0;y<4;++y) allFrames[f].projectionMatrix(x,y)=bundleAdjuster.nodes[fInd2NInd[f]].w2n(x,y);

	//generate the point cloud from the new projection matrices
	utils::generateCloud(allFrames,*outputCloud);
}