The C++ example is quite complicated, in that it can use multiple calibration patterns, and can using a list of image as well as live video. I decided that this example only uses a folder of several chessboard photos as input.
import java.io.File;
import java.util.ArrayList;
import org.opencv.calib3d.Calib3d;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfPoint2f;
import org.opencv.core.MatOfPoint3f;
import org.opencv.core.Point3;
import org.opencv.core.Size;
import org.opencv.core.TermCriteria;
import org.opencv.highgui.Highgui;
import org.opencv.imgproc.Imgproc;
public class CalibChessBoard {
int flagsCorner = Calib3d.CALIB_CB_ADAPTIVE_THRESH
| Calib3d.CALIB_CB_FAST_CHECK
| Calib3d.CALIB_CB_NORMALIZE_IMAGE;
int flagsCalib = Calib3d.CALIB_ZERO_TANGENT_DIST
| Calib3d.CALIB_FIX_PRINCIPAL_POINT
| Calib3d.CALIB_FIX_K4
| Calib3d.CALIB_FIX_K5;
TermCriteria criteria = new TermCriteria(TermCriteria.EPS
+ TermCriteria.MAX_ITER, 40, 0.001);
Size winSize = new Size(5, 5), zoneSize = new Size(-1, -1);
Size patternSize;
ArrayList objectPoints, imagePoints = new ArrayList();
ArrayList vCorners;
ArrayList vImg;
Mat cameraMatrix = Mat.eye(3, 3, CvType.CV_64F);
Mat distCoeffs = Mat.zeros(8, 1, CvType.CV_64F);
ArrayList rvecs = new ArrayList();
ArrayList tvecs = new ArrayList();
CalibChessBoard() {
}
CalibChessBoard(Size patternSize) {
this.patternSize = patternSize;
}
boolean getCorners(Mat gray, MatOfPoint2f corners) {
if (!Calib3d.findChessboardCorners(gray, patternSize,
corners, flagsCorner))
return false;
Imgproc.cornerSubPix(gray, corners, winSize, zoneSize,
criteria);
return true;
}
MatOfPoint3f getCorner3f() {
MatOfPoint3f corners3f = new MatOfPoint3f();
double squareSize = 50;
Point3[] vp = new Point3[(int) (patternSize.height *
patternSize.width)];
int cnt = 0;
for (int i = 0; i < patternSize.height; ++i)
for (int j = 0; j < patternSize.width; ++j, cnt++)
vp[cnt] = new Point3(j * squareSize,
i * squareSize, 0.0d);
corners3f.fromArray(vp);
return corners3f;
}
public static void main(String[] args) {
test0();
}
static void test0() {
CalibChessBoard cb = new CalibChessBoard(new Size(8, 6));
cb.getAllCornors("/the/photo/folder");
cb.calibrate();
}
void calibrate() {
double errReproj = Calib3d.calibrateCamera(objectPoints,
imagePoints,vImg.get(0).size(), cameraMatrix,
distCoeffs, rvecs, tvecs,flagsCalib);
System.out.println("done, \nerrReproj = " + errReproj);
System.out.println("cameraMatrix = \n" + cameraMatrix.dump());
System.out.println("distCoeffs = \n" + distCoeffs.dump());
}
void getAllCornors(String path) {
vImg = new ArrayList();
objectPoints = new ArrayList();
imagePoints = new ArrayList();
MatOfPoint3f corners3f = getCorner3f();
for (File f : new File(path).listFiles()) {
Mat mat = Highgui.imread(f.getPath(),
Highgui.CV_LOAD_IMAGE_COLOR);
if (mat == null || mat.channels() != 3)
continue;
System.out.println("fn = " + f.getPath());
System.out.println("mat.channels() = " + mat.channels()
+ ", " + mat.cols() + ", " + mat.rows());
Mat gray = new Mat();
Imgproc.cvtColor(mat, gray, Imgproc.COLOR_BGR2GRAY);
MatOfPoint2f corners = new MatOfPoint2f();
if (!getCorners(gray, corners))
continue;
objectPoints.add(corners3f);
imagePoints.add(corners);
vImg.add(mat);
}
}
static {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
}
}
Here are the list of images that give the following results:
errReproj = 0.25108
cameraMatrix =
[614.561, 0, 319.5;
0, 615.445, 239.5;
0, 0, 1]
distCoeffs = [0.155040; 0.075046; 0; 0; -2.318117]
This comment has been removed by the author.
ReplyDeleteSir, can you give me the current link for the images?
ReplyDeleteThis comment has been removed by the author.
ReplyDelete