jakobwilm / slstudio

SLStudio -- Real Time Structured Light. A comprehensive software suite for capturing and reconstructing 3D scenes with a camera-projector pair.
Other
515 stars 194 forks source link

Calibration of projector #31

Closed johntraynor closed 5 years ago

johntraynor commented 5 years ago

Hi,

Thanks for sharing this code.

I am a little confused on how the projector is calibrated so I was hoping someone could explain the theory. Does the projector not need to project it's own pattern in order to calibrate it?

In particular I am confused about how the projector corner coordinates are calculated using the code snippet below. I understand the camera calibration part.

for(unsigned int j=0; j<qci.size(); j++){

            const cv::Point2f &qcij = qci[j];

            // Collect neighbor points
            const unsigned int WINDOW_SIZE = 10;
            std::vector<cv::Point2f> N_qcij, N_qpij;

            // avoid going out of bounds
            unsigned int starth = max(int(qcij.y+0.5)-WINDOW_SIZE, 0u);
            unsigned int stoph  = min(int(qcij.y+0.5)+WINDOW_SIZE, frameHeight-1);
            unsigned int startw = max(int(qcij.x+0.5)-WINDOW_SIZE, 0u);
            unsigned int stopw  = min(int(qcij.x+0.5)+WINDOW_SIZE, frameWidth-1);

            for(unsigned int h=starth; h<=stoph; h++){
                for(unsigned int w=startw; w<=stopw; w++){
                    // stay within mask
                    if(mask[i].at<bool>(h,w)){
                        N_qcij.push_back(cv::Point2f(w, h));

                        float upijwh = up[i].at<float>(h,w);
                        float vpijwh = vp[i].at<float>(h,w);
                        N_qpij.push_back(cv::Point2f(upijwh, vpijwh));
                    }
                }
            }
            //std::cout << i << " findHomography " << N_qcij.size() << " " << N_qpij.size() << std::endl;
            // if enough valid points to build homography
            if(N_qpij.size() >= 50){

// std::cout << i << " findHomography" << std::endl; // translate qcij into qpij using local homography cv::Mat H = cv::findHomography(N_qcij, N_qpij, cv::LMEDS); if(!H.empty()){ cv::Point3d Q = cv::Point3d(cv::Mat(H*cv::Mat(cv::Point3d(qcij.x, qcij.y, 1.0)))); cv::Point2f qpij = cv::Point2f(Q.x/Q.z, Q.y/Q.z);

                    qpi_a.push_back(qpij);
                    qci_a.push_back(qci[j]);
                    Qi_a.push_back(Qi[j]);
                }
            }
        }

Also is there a reason why one white image of the calibrations grid is not taken as opposed to 12 using the phase patterns. Is this way more accurate?

Thanks

jakobwilm commented 5 years ago

Hi John, have a look at: "Wilm, Jakob, Oline V. Olesen, and Rasmus Larsen. "Accurate and simple calibration of DLP projector systems." Emerging Digital Micromirror Device Based Systems and Applications VI. Vol. 8979. 2014." Regards, Jakob

johntraynor commented 5 years ago

Many thanks -