Permalink
Browse files

calibrate and visualize a projector-camera system. works for small sy…

…stems.
  • Loading branch information...
1 parent 5cae375 commit 44dceca32d846da70f7adfd8f4ea1928d4622205 @kylemcdonald kylemcdonald committed Nov 6, 2011
@@ -0,0 +1,9 @@
+//THE PATH TO THE ROOT OF OUR OF PATH RELATIVE TO THIS PROJECT.
+//THIS NEEDS TO BE DEFINED BEFORE CoreOF.xcconfig IS INCLUDED
+OF_PATH = ../../..
+
+//THIS HAS ALL THE HEADER AND LIBS FOR OF CORE
+#include "../../../libs/openFrameworksCompiled/project/osx/CoreOF.xcconfig"
+
+OTHER_LDFLAGS = $(OF_CORE_LIBS)
+HEADER_SEARCH_PATHS = $(OF_CORE_HEADERS) "../../../addons/ofxCv/libs/opencv/include/" "../../../addons/ofxCv/libs/ofxCv/include/"
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>${EXECUTABLE_NAME}</string>
+ <key>CFBundleIdentifier</key>
+ <string>com.yourcompany.openFrameworks</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1.0</string>
+</dict>
+</plist>
@@ -0,0 +1,8 @@
+#include "testApp.h"
+#include "ofAppGlutWindow.h"
+
+int main() {
+ ofAppGlutWindow window;
+ ofSetupOpenGL(&window, 1280, 960, OF_WINDOW);
+ ofRunApp(new testApp());
+}
@@ -0,0 +1,157 @@
+#include "testApp.h"
+
+using namespace cv;
+using namespace ofxCv;
+
+void testApp::setup() {
+ ofSetVerticalSync(true);
+ ofSetDrawBitmapMode(OF_BITMAPMODE_MODEL_BILLBOARD);
+
+ curPair = 0;
+ patternSize = cv::Size(4, 11);
+ squareSize = 16.5; // units in mm
+
+ ofDirectory proDir, camDir;
+ proDir.listDir("pro");
+ camDir.listDir("cam");
+
+ int objectCount = 0;
+ for(int i = 0; i < camDir.size(); i++) {
+ ofImage curCam, curPro;
+ curCam.loadImage(camDir.getPath(i));
+ curPro.loadImage(proDir.getPath(i));
+ Mat camMat = toCv(curCam);
+ Mat proMat = toCv(curPro);
+ vector<Point2f> curCamImagePoints, curProImagePoints;
+ bool foundCam = findCirclesGrid(camMat, patternSize, curCamImagePoints, CALIB_CB_CLUSTERING | CALIB_CB_ASYMMETRIC_GRID);
+ bool foundPro = findCirclesGrid(proMat, patternSize, curProImagePoints, CALIB_CB_CLUSTERING | CALIB_CB_ASYMMETRIC_GRID);
+ if(foundCam && foundPro) {
+ camImagePoints.push_back(curCamImagePoints);
+ proImagePoints.push_back(curProImagePoints);
+ camImages.push_back(curCam);
+ proImages.push_back(curPro);
+ objectCount++;
+ }
+ camSize = camMat.size();
+ proSize = proMat.size();
+ }
+
+ cout << "detecting objects: " << objectCount << endl;
+
+ camMatrix = Mat::eye(3, 3, CV_64F);
+ camDistCoeffs = Mat::zeros(8, 1, CV_64F);
+ proMatrix = Mat::eye(3, 3, CV_64F);
+ proDistCoeffs = Mat::zeros(8, 1, CV_64F);
+
+ objectPoints = buildObjectPoints(patternSize, squareSize, objectCount, ASYMMETRIC_CIRCLES_GRID);
+ int calibFlags = 0;
+ float camRms = calibrateCamera(objectPoints, camImagePoints, camSize, camMatrix, camDistCoeffs, camRot, camTrans, calibFlags);
+ float proRms = calibrateCamera(objectPoints, proImagePoints, proSize, proMatrix, proDistCoeffs, proRot, proTrans, calibFlags);
+
+ cout << "cam has " << camRms << endl;
+ cout << "cam matrix " << camMatrix << endl;
+ cout << "pro has " << proRms << endl;
+ cout << "pro matrix " << proMatrix << endl;
+
+ // uses CALIB_FIX_INTRINSIC by default
+ stereoCalibrate(objectPoints,
+ proImagePoints, camImagePoints, // A, B
+ proMatrix, proDistCoeffs, // A, A
+ camMatrix, camDistCoeffs, // B, B
+ camSize, rotation, translation,
+ essentialMatrix, fundamentalMatrix);
+ // returns the results rotation and translation
+ // rotation * A + translation = B
+ // e.g., A is projector, B is camera
+ // translation : [-332.5760929883801; 255.8786193463019; -117.7930503532803]
+ // the projector is to the left, beneath, behind the camera
+
+ cout << "translation: " << translation << endl;
+ cout << "rotation: " << rotation << endl;
+
+ Mat camMatrixInv = camMatrix.inv();
+ Mat proMatrixInv = proMatrix.inv();
+
+ cout << "cam inv: " << camMatrixInv << endl;
+ cout << "pro inv: " << proMatrixInv << endl;
+
+ cout << "cam dist: " << camDistCoeffs << endl;
+ cout << "pro dist: " << proDistCoeffs << endl;
+
+ FileStorage cfs(ofToDataPath("cam.yml"), FileStorage::WRITE);
+ cfs << "cameraMatrix" << camMatrix;
+ cfs << "imageSize_width" << camSize.width;
+ cfs << "imageSize_height" << camSize.height;
+ cfs << "distCoeffs" << camDistCoeffs;
+ cfs << "reprojectionError" << camRms;
+
+ FileStorage pfs(ofToDataPath("pro.yml"), FileStorage::WRITE);
+ pfs << "cameraMatrix" << proMatrix;
+ pfs << "imageSize_width" << proSize.width;
+ pfs << "imageSize_height" << proSize.height;
+ pfs << "distCoeffs" << proDistCoeffs;
+ pfs << "reprojectionError" << proRms;
+ pfs << "rotation" << rotation;
+ pfs << "translation" << translation;
+
+ resultPoints.resize(objectCount);
+ for(int i = 0; i < objectCount; i++) {
+ resultPoints[i] = triangulatePositions(
+ camImagePoints[i], camMatrix, camDistCoeffs,
+ proImagePoints[i], proMatrix, proDistCoeffs,
+ rotation, translation);
+ }
+}
+
+void testApp::update() {
+}
+
+void testApp::draw() {
+/*
+ camImages[curPair].draw(0, 0);
+ drawChessboardCorners(patternSize, camImagePoints[curPair]);
+
+ ofTranslate(640, 0);
+ proImages[curPair].draw(0, 0);
+ drawChessboardCorners(patternSize, proImagePoints[curPair]);
+ */
+
+ ofBackground(0);
+
+ cam.begin();
+ ofScale(1, -1, -1);
+
+ glEnable(GL_DEPTH_TEST);
+
+ ofTranslate(0, 0, -1200);
+
+ ofSetColor(magentaPrint);
+ drawCamera("camera",
+ camMatrix, camSize,
+ objectPoints[curPair], camRot[curPair], camTrans[curPair],
+ camImagePoints[curPair],
+ camImages[curPair]);
+
+ ofSetColor(cyanPrint);
+ drawCamera("projector",
+ proMatrix, proSize,
+ objectPoints[curPair], proRot[curPair], proTrans[curPair],
+ proImagePoints[curPair],
+ proImages[curPair],
+ rotation, translation);
+
+ ofSetColor(yellowPrint);
+ drawObjectPoints(resultPoints[curPair]);
+
+ cam.end();
+}
+
+void testApp::keyPressed(int key) {
+ if(key == OF_KEY_UP) {
+ curPair--;
+ }
+ if(key == OF_KEY_DOWN) {
+ curPair++;
+ }
+ curPair = ofClamp(curPair, 0, camImages.size() - 1);
+}
@@ -0,0 +1,34 @@
+#pragma once
+
+#include "ofMain.h"
+#include "ofxCv.h"
+#include "ofxProCamToolkit.h"
+
+class testApp : public ofBaseApp {
+public:
+ void setup();
+ void update();
+ void draw();
+ void decodeAndSave(string filename);
+ void keyPressed(int key);
+
+ cv::Size patternSize;
+ float squareSize;
+ int curPair;
+ vector<ofImage> camImages, proImages;
+ vector<vector<cv::Point2f> > camImagePoints, proImagePoints;
+ vector<vector<cv::Point3f> > objectPoints;
+
+ vector<vector<cv::Point3f> > resultPoints;
+
+ cv::Size proSize, camSize;
+
+ cv::Mat camMatrix, proMatrix;
+ cv::Mat camDistCoeffs, proDistCoeffs;
+ vector<cv::Mat> camRot, camTrans, proRot, proTrans;
+
+ cv::Mat rotation, translation;
+ cv::Mat fundamentalMatrix, essentialMatrix;
+
+ ofEasyCam cam;
+};

0 comments on commit 44dceca

Please sign in to comment.