Beispiel #1
0
void CalibrateThread::run()
{
    Size boardSize, imageSize;
    float squareSize = 1.f, aspectRatio = 1.f;
    Mat cameraMatrix, distCoeffs;
    //QString of = ui->lineEdit_WorkFolder->text() + '/' + ui->lineEdit_OutputName->text();
    QByteArray ba = strFileName.toLatin1();
    const char* outputFilename = ba.data();

    int i, nframes = 0;
    bool writeExtrinsics = true, writePoints = true;
    bool undistortImage = false;
    int flags = 0;
    VideoCapture capture;
    bool flipVertical = false;
    bool showUndistorted = false;

    int delay = 1000;
    clock_t prevTimestamp = 0;
    int mode = CAPTURING;
    vector<vector<Point2f> > imagePoints;
    vector<string> imageList;
    Pattern pattern = CHESSBOARD;

    boardSize.width = m_width;
    boardSize.height = m_height;
    squareSize = m_squaresize;



    //ui->textEdit_Information->append("\nCalibrating... Please wait for a while\n");


    if( imgList.size() == 0  )
    {
        //QMessageBox::warning(NULL, "Error", "Please choose a right folder");
        emit popupErrorInformation("Please choose a right folder");
        emit closeImageWindow();
        return;
    }
    else
    {
        nframes = imgList.size();
    }

    emit appendText("\nCalibrating... Please wait for a while\n");
    //namedWindow( "Image View", 1 );
    //bDialog->show();

    for(i = 0; i < nframes ;i++)
    {
        //ui->textEdit_Information->append("Processing the image No. " + QString::number(i + 1));


        emit appendText("Processing the image No. " + QString::number(i + 1));
        Mat view, viewGray;
        bool blink = false;
        qDebug(imgList.at(i).toLatin1().data());
        if( i < (int)imgList.size() )
            view = imread(imgList.at(i).toLatin1().data(), 1);

        if(!view.data)
        {
            //QMessageBox::warning(NULL, "Error", );
            emit popupErrorInformation("Could not open image files");
            return;
        }

        imageSize = view.size();

        if( flipVertical )
            flip( view, view, 0 );

        vector<Point2f> pointbuf;
        cvtColor(view, viewGray, CV_BGR2GRAY);

        bool found;
        switch( pattern )
        {
        case CHESSBOARD:
            found = findChessboardCorners( view, boardSize, pointbuf,
                                           CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FAST_CHECK | CV_CALIB_CB_NORMALIZE_IMAGE);
            break;
        case CIRCLES_GRID:
            found = findCirclesGrid( view, boardSize, pointbuf );
            break;
        case ASYMMETRIC_CIRCLES_GRID:
            found = findCirclesGrid( view, boardSize, pointbuf, CALIB_CB_ASYMMETRIC_GRID );
            break;
        }

        // improve the found corners' coordinate accuracy
        if( pattern == CHESSBOARD && found) cornerSubPix( viewGray, pointbuf, Size(11,11),
                                                          Size(-1,-1), TermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 30, 0.1 ));

        if( mode == CAPTURING && found &&
                (!capture.isOpened() || clock() - prevTimestamp > delay*1e-3*CLOCKS_PER_SEC) )
        {
            imagePoints.push_back(pointbuf);
            prevTimestamp = clock();
            blink = capture.isOpened();
        }
        if(found)
            drawChessboardCorners( view, boardSize, Mat(pointbuf), found );

        string msg = mode == CAPTURING ? "100/100" :
                                         mode == CALIBRATED ? "Calibrated" : "Press 'g' to start";
        int baseLine = 0;
        Size textSize = getTextSize(msg, 1, 1, 1, &baseLine);
        Point textOrigin(view.cols - 2*textSize.width - 10, view.rows - 2*baseLine - 10);

        if( mode == CAPTURING )
        {
            if(undistortImage)
                msg = format( "%d/%d Undist", (int)imagePoints.size(), nframes );
            else
                msg = format( "%d/%d", (int)imagePoints.size(), nframes );
        }

        putText( view, msg, textOrigin, 1, 1,
                 mode != CALIBRATED ? Scalar(0,0,255) : Scalar(0,255,0));

        if( blink )
            bitwise_not(view, view);

        if( mode == CALIBRATED && undistortImage )
        {
            Mat temp = view.clone();
            undistort(temp, view, cameraMatrix, distCoeffs);
        }

        Mat rgb;
        cvtColor(view, rgb, CV_BGR2RGB);

        QImage  image32 = QImage(rgb.cols, rgb.rows, QImage::Format_RGB32);
        QRgb value;
        for(int r = 0; r < rgb.rows; r++)
        {
            for(int c = 0; c < rgb.cols; c++)
            {
                value = qRgb(rgb.ptr<uchar>(0)[r * rgb.cols * 3 + c * 3 + 0], rgb.ptr<uchar>(0)[r * rgb.cols * 3 + c * 3 + 1], rgb.ptr<uchar>(0)[r * rgb.cols * 3 + c * 3 + 2]);
                image32.setPixel(c, r, value);
            }
        }


        emit showBitmap(image32);

        int key;
        if(i < nframes - 1)
        {
            key = 0xff & waitKey(500);
        }
        else
        {
            key = waitKey(500);
        }

        if( (key & 255) == 27 )
            break;

        if( key == 'u' && mode == CALIBRATED )
            undistortImage = !undistortImage;




    }
    if(imagePoints.size() > 0)
    {
        emit appendText("\n" + QString::number(imagePoints.size()) + " out of " + QString::number(nframes) + " images are effective!\n" );
        runAndSave(outputFilename, imagePoints, imageSize,
                   boardSize, pattern, squareSize, aspectRatio,
                   flags, cameraMatrix, distCoeffs,
                   writeExtrinsics, writePoints);

    }
    else
    {
        emit appendText("Calibrating is not successful! \nPlease change the parameters and try again!");
        emit popupErrorInformation("Sorry, no enough points are detected! Please try another group of images!");
        emit closeImageWindow();
        return;

    }


    emit appendText("Calibrating Successfully! \nPlease go to the folder to check the out put files!");
    emit closeImageWindow();
    if( !capture.isOpened() && showUndistorted )
    {
        Mat view, rview, map1, map2;
        initUndistortRectifyMap(cameraMatrix, distCoeffs, Mat(),
                                getOptimalNewCameraMatrix(cameraMatrix, distCoeffs, imageSize, 1, imageSize, 0),
                                imageSize, CV_16SC2, map1, map2);

        for( i = 0; i < (int)imageList.size(); i++ )
        {
            view = imread(imageList[i], 1);
            if(!view.data)
                continue;
            //undistort( view, rview, cameraMatrix, distCoeffs, cameraMatrix );
            remap(view, rview, map1, map2, INTER_LINEAR);
            imshow("Image View", rview);
            int c = 0xff & waitKey();
            if( (c & 255) == 27 || c == 'q' || c == 'Q' )
                break;
        }
    }

    return;
}
Beispiel #2
0
int main(int argc, char** argv){

	int status,i;
	Ice::CommunicatorPtr ic;
	Ice::PropertiesPtr prop;
	cv::Size boardSize;

	Pattern pattern = CHESSBOARD;
	float squareSize;
	float aspectRatio;
	int nframes;
	bool writeExtrinsics = false;
	bool writePoints = false;
    int delay;
    clock_t prevTimestamp = 0;
    int mode = DETECTION;
    bool undistortImage = false;
    bool globalCalibrated=false;

    std::vector<cameraData> cameras;

	try{
		ic = Ice::initialize(argc,argv);
		prop = ic->getProperties();
	}catch (const Ice::Exception& ex) {
		std::cerr << ex << std::endl;
		return 1;
	}
	catch (const char* msg) {
		std::cerr <<"Error :" << msg << std::endl;
		return 1;
	}

	std::string componentPrefix("cameraCalibrator");

	std::cout << "Ncameras: " << prop->getPropertyAsIntWithDefault(componentPrefix+".nCameras",1) << std::endl;

	for (int i=0; i< prop->getPropertyAsIntWithDefault(componentPrefix+".nCameras",1); i++){
		cameraData cam;
		std::stringstream ss;
		ss << componentPrefix << ".camera." <<i <<".";
		cam.outputFilename=prop->getProperty(ss.str()+"outFile");
		cam.proxy = new jderobot::cameraClient(ic,ss.str());
		if (cam.proxy != NULL){
			cam.proxy->start();
		}
		else{
			throw "rgbdViewer: failed to load RGB Camera";
		}
		cam.calibrated=false;
		cameras.push_back(cam);

	}



	//parsing calibration parameteres
	boardSize.height=prop->getPropertyAsIntWithDefault(componentPrefix+".pattern.height",6);
	boardSize.width=prop->getPropertyAsIntWithDefault(componentPrefix+".pattern.width",9);
	std::string patterType =prop->getProperty(componentPrefix+".pattern.type");
	if( !strcmp( patterType.c_str(), "circles" ) )
		pattern = CIRCLES_GRID;
	else if( !strcmp( patterType.c_str(), "acircles" ) )
		pattern = ASYMMETRIC_CIRCLES_GRID;
	else if( !strcmp( patterType.c_str(), "chessboard" ) )
		pattern = CHESSBOARD;
	else
		return fprintf( stderr, "Invalid pattern type: must be chessboard or circles\n" ), -1;

	squareSize=atof(prop->getProperty(componentPrefix+".pattern.size").c_str());
	aspectRatio=atof(prop->getProperty(componentPrefix+".pattern.ratio").c_str());
	nframes=prop->getPropertyAsIntWithDefault(componentPrefix+".frames",10);
	writePoints=boost::lexical_cast<bool>(prop->getProperty(componentPrefix+".writePoints"));
	writeExtrinsics=boost::lexical_cast<bool>(prop->getProperty(componentPrefix+".writeEstrinsics"));
	delay=prop->getPropertyAsIntWithDefault(componentPrefix+".delay",1000);



	//init the poling
	while (1){
		cv::Mat frame;
		for (std::vector<cameraData>::iterator it= cameras.begin(); it != cameras.end(); it++){
			while (it->frame.cols ==0){
				it->proxy->getImage(it->frame);
			}
			it->imageSize=it->frame.size();
		}
		break;
	}

	std::cout << "Poling init done" << std::endl;
	while (1){
		for (std::vector<cameraData>::iterator it= cameras.begin(); it != cameras.end(); it++){
			it->proxy->getImage(it->frame);
			it->frame.copyTo(it->raw_frame);
			it->pointbuf.resize(0);
			if (it->frame.channels() ==3)
			  cv::cvtColor(it->frame, it->viewGray, cv::COLOR_BGR2GRAY);
			else
			  it->frame.copyTo(it->viewGray);
			it->found=false;

			switch( pattern )
			{
				case CHESSBOARD:
					it->found = cv::findChessboardCorners( it->frame, boardSize, it->pointbuf,
					CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FAST_CHECK | CV_CALIB_CB_NORMALIZE_IMAGE);
					break;
				case CIRCLES_GRID:
					it->found = cv::findCirclesGrid( it->frame, boardSize, it->pointbuf );
					break;
				case ASYMMETRIC_CIRCLES_GRID:
					it->found = cv::findCirclesGrid( it->frame, boardSize, it->pointbuf, cv::CALIB_CB_ASYMMETRIC_GRID );
					break;
				default:
					return fprintf( stderr, "Unknown pattern type\n" ), -1;
			}

			if( pattern == CHESSBOARD && it->found)
				cv::cornerSubPix( it->viewGray, it->pointbuf, cv::Size(11,11), cv::Size(-1,-1), cv::TermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 30, 0.1 ));
			if(it->found)
				cv::drawChessboardCorners( it->frame, boardSize, cv::Mat(it->pointbuf), it->found );
		}

		bool globalFound=true;
		for (std::vector<cameraData>::iterator it= cameras.begin(); it != cameras.end(); it++){
			globalFound=globalFound && it->found;
		}



        if( mode == CAPTURING && globalFound && (clock() - prevTimestamp > delay*1e-3*CLOCKS_PER_SEC) )
        {
    		for (std::vector<cameraData>::iterator it= cameras.begin(); it != cameras.end(); it++){
    			cv::Mat temp;
    			it->raw_frame.copyTo(temp);
    			it->images.push_back(temp);
                it->imagePoints.push_back(it->pointbuf);
    		}
            prevTimestamp = clock();
        }


		for (std::vector<cameraData>::iterator it= cameras.begin(); it != cameras.end(); it++){

			std::string msg =  mode == CAPTURING ? "100/100" : mode == CALIBRATED ? "Calibrated" : "Press 'g' to start";
			int baseLine = 0;
			cv::Size textSize = cv::getTextSize(msg, 1, 1, 1, &baseLine);

			cv::Point textOrigin(cameras[0].frame.cols - 2*textSize.width - 10, cameras[0].frame.rows - 2*baseLine - 10);


			if( mode == CAPTURING )
			{
				if(undistortImage)
					msg = cv::format( "%d/%d Undist", (int)it->imagePoints.size(), nframes );
				else
					msg = cv::format( "%d/%d", (int)it->imagePoints.size(), nframes );
			}

			cv::putText( it->frame, msg, textOrigin, 1, 1, mode != CALIBRATED ? cv::Scalar(0,0,255) : cv::Scalar(0,255,0));

			if( mode == CALIBRATED && undistortImage )
			{
				cv::Mat temp = it->frame.clone();
				undistort(temp, it->frame, it->cameraMatrix, it->distCoeffs);
			}
			std::stringstream ss;
			ss << "Image " << it-cameras.begin();


			cv::imshow(ss.str(),it->frame);
			int key=0xff & cv::waitKey(1);

			if( (key & 255) == 27 )
				break;

			if( key == 'u' && mode == CALIBRATED )
				undistortImage = !undistortImage;

			if(  key == 'g' )
			{
				mode = CAPTURING;
				it->imagePoints.clear();
			}

			if( !globalCalibrated && it->imagePoints.size() >= (unsigned)nframes )
				{
					if( runAndSave(it->outputFilename, it->imagePoints, it->imageSize,
							   boardSize, pattern, squareSize, aspectRatio,
							   0, it->cameraMatrix, it->distCoeffs,
							   writeExtrinsics, writePoints)){
						mode = CALIBRATED;
						it->calibrated=true;;
					}
					else
						mode = DETECTION;

					//save pictures
					int cameraID = std::distance(cameras.begin(),it);
					for ( std::vector<cv::Mat>::iterator itImage = it->images.begin(); itImage != it->images.end(); itImage++){
						std::stringstream ss;
						ss << "camera-" << cameraID << "-" << std::distance(it->images.begin(), itImage) << ".png";
						cv::imwrite(ss.str(),*itImage);
					}

				}


		}
		for (std::vector<cameraData>::iterator it= cameras.begin(); it != cameras.end(); it++){
			if (it == cameras.begin()){
				globalCalibrated=it->calibrated;
			}
			else
				globalCalibrated=globalCalibrated && it->calibrated;
		}



	}
}