New to OpenCV so please bear with me. I have a 180' fisheye lens which I'm trying to calibrate using the methods in cv::fisheye. I tried to come up with an example program similar to the one that uses cv::calibrateCamera (but way less featured).
The problem I'm facing is that I get this assert failure when calling cv::fisheye::calibrate
OpenCV Error: Assertion failed (svd.w.at<double>(0) / svd.w.at<double>((int)svd.w.total() - 1) < thresh_cond) in CalibrateExtrinsics, file /opt/local/var/macports/build/_opt_mports_dports_graphics_opencv/opencv/work/opencv-3.0.0/modules/calib3d/src/fisheye.cpp, line 1379
The call itself looks like this:
int flags = 0;
flags |= cv::fisheye::CALIB_RECOMPUTE_EXTRINSIC;
flags |= cv::fisheye::CALIB_CHECK_COND;
flags |= cv::fisheye::CALIB_FIX_SKEW;
fisheye::calibrate(obj_points, img_points, frame.size(), K, D,
noArray(), noArray(), flags);
I noticed that removing CALIB_CHECK_COND gets rid of the assertion but my undistorted image looks wrong. Any help is appreciated, the full code is below.
If I can get this working I'd love to have such an example somewhere in opensource, I found it hard to find much documentation for this sort of thing.
#include <string>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
int main(int argc, char** argv) {
VideoCapture camera(0);
if (!camera.isOpened()) {
cout << "Failed to open camera." << std::endl;
return -1;
}
const char* window_name = "output";
namedWindow(window_name, WINDOW_NORMAL);
Mat frame;
Size boardSize;
boardSize.width = 9;
boardSize.height = 6;
int remaining_frames = 10;
Mat K;
Mat D;
Mat identity = Mat::eye(3, 3, CV_64F);
vector<vector<Point2f> > img_points;
vector<vector<Point3f> > obj_points(1);
int width = 9;
int height = 6;
int sq_sz = 50;
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
obj_points[0].push_back(Point3f(float(j * sq_sz), float(i * sq_sz), 0));
}
}
obj_points.resize(remaining_frames, obj_points[0]);
while (1) {
if (!camera.read(frame)) {
cout << "Failed to read frame" << std::endl;
break;
}
if (remaining_frames > 0) {
vector<Point2f> corners;
bool found = findChessboardCorners(frame, boardSize, corners,
CALIB_CB_ADAPTIVE_THRESH|CALIB_CB_NORMALIZE_IMAGE|CALIB_CB_FAST_CHECK);
drawChessboardCorners(frame, boardSize, corners, found);
if (found) {
img_points.push_back(corners);
remaining_frames--;
cout << remaining_frames << " frames to calibration." << endl;
if (remaining_frames == 0) {
cout << "Computing distortion" << endl;
int flags = 0;
flags |= cv::fisheye::CALIB_RECOMPUTE_EXTRINSIC;
flags |= cv::fisheye::CALIB_CHECK_COND;
flags |= cv::fisheye::CALIB_FIX_SKEW;
fisheye::calibrate(obj_points, img_points, frame.size(), K, D,
noArray(), noArray(), flags);
cout << "Finished computing distortion" << endl;
}
}
imshow(window_name, frame);
} else {
Mat output;
fisheye::undistortImage(frame, output, K, D, identity);
imshow(window_name, output);
}
if (waitKey(30) > 0) {
break;
}
}
return 0;
}