1 // This sample is based on "Camera calibration With OpenCV" tutorial:
2 // http://docs.opencv.org/doc/tutorials/calib3d/camera_calibration/camera_calibration.html
4 // It uses standard OpenCV asymmetric circles grid pattern 11x4:
5 // https://github.com/Itseez/opencv/blob/2.4/doc/acircles_pattern.png.
6 // The results are the camera matrix and 5 distortion coefficients.
8 // Tap on highlighted pattern to capture pattern corners for calibration.
9 // Move pattern along the whole screen and capture data.
11 // When you've captured necessary amount of pattern corners (usually ~20 are enough),
12 // press "Calibrate" button for performing camera calibration.
14 package org.opencv.samples.cameracalibration;
16 import org.opencv.android.BaseLoaderCallback;
17 import org.opencv.android.CameraBridgeViewBase;
18 import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;
19 import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2;
20 import org.opencv.android.LoaderCallbackInterface;
21 import org.opencv.android.OpenCVLoader;
22 import org.opencv.core.Mat;
24 import android.app.Activity;
25 import android.app.ProgressDialog;
26 import android.content.res.Resources;
27 import android.os.AsyncTask;
28 import android.os.Bundle;
29 import android.util.Log;
30 import android.view.Menu;
31 import android.view.MenuItem;
32 import android.view.MotionEvent;
33 import android.view.SurfaceView;
34 import android.view.View;
35 import android.view.View.OnTouchListener;
36 import android.view.WindowManager;
37 import android.widget.Toast;
39 public class CameraCalibrationActivity extends Activity implements CvCameraViewListener2, OnTouchListener {
40 private static final String TAG = "OCVSample::Activity";
42 private CameraBridgeViewBase mOpenCvCameraView;
43 private CameraCalibrator mCalibrator;
44 private OnCameraFrameRender mOnCameraFrameRender;
48 private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
50 public void onManagerConnected(int status) {
52 case LoaderCallbackInterface.SUCCESS:
54 Log.i(TAG, "OpenCV loaded successfully");
55 mOpenCvCameraView.enableView();
56 mOpenCvCameraView.setOnTouchListener(CameraCalibrationActivity.this);
60 super.onManagerConnected(status);
66 public CameraCalibrationActivity() {
67 Log.i(TAG, "Instantiated new " + this.getClass());
71 public void onCreate(Bundle savedInstanceState) {
72 Log.i(TAG, "called onCreate");
73 super.onCreate(savedInstanceState);
74 getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
76 setContentView(R.layout.camera_calibration_surface_view);
78 mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.camera_calibration_java_surface_view);
79 mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);
80 mOpenCvCameraView.setCvCameraViewListener(this);
87 if (mOpenCvCameraView != null)
88 mOpenCvCameraView.disableView();
92 public void onResume()
95 OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_2, this, mLoaderCallback);
98 public void onDestroy() {
100 if (mOpenCvCameraView != null)
101 mOpenCvCameraView.disableView();
105 public boolean onCreateOptionsMenu(Menu menu) {
106 super.onCreateOptionsMenu(menu);
107 getMenuInflater().inflate(R.menu.calibration, menu);
113 public boolean onPrepareOptionsMenu (Menu menu) {
114 super.onPrepareOptionsMenu(menu);
115 menu.findItem(R.id.preview_mode).setEnabled(true);
116 if (!mCalibrator.isCalibrated())
117 menu.findItem(R.id.preview_mode).setEnabled(false);
123 public boolean onOptionsItemSelected(MenuItem item) {
124 switch (item.getItemId()) {
125 case R.id.calibration:
126 mOnCameraFrameRender =
127 new OnCameraFrameRender(new CalibrationFrameRender(mCalibrator));
128 item.setChecked(true);
130 case R.id.undistortion:
131 mOnCameraFrameRender =
132 new OnCameraFrameRender(new UndistortionFrameRender(mCalibrator));
133 item.setChecked(true);
135 case R.id.comparison:
136 mOnCameraFrameRender =
137 new OnCameraFrameRender(new ComparisonFrameRender(mCalibrator, mWidth, mHeight, getResources()));
138 item.setChecked(true);
141 final Resources res = getResources();
142 if (mCalibrator.getCornersBufferSize() < 2) {
143 (Toast.makeText(this, res.getString(R.string.more_samples), Toast.LENGTH_SHORT)).show();
147 mOnCameraFrameRender = new OnCameraFrameRender(new PreviewFrameRender());
148 new AsyncTask<Void, Void, Void>() {
149 private ProgressDialog calibrationProgress;
152 protected void onPreExecute() {
153 calibrationProgress = new ProgressDialog(CameraCalibrationActivity.this);
154 calibrationProgress.setTitle(res.getString(R.string.calibrating));
155 calibrationProgress.setMessage(res.getString(R.string.please_wait));
156 calibrationProgress.setCancelable(false);
157 calibrationProgress.setIndeterminate(true);
158 calibrationProgress.show();
162 protected Void doInBackground(Void... arg0) {
163 mCalibrator.calibrate();
168 protected void onPostExecute(Void result) {
169 calibrationProgress.dismiss();
170 mCalibrator.clearCorners();
171 mOnCameraFrameRender = new OnCameraFrameRender(new CalibrationFrameRender(mCalibrator));
172 String resultMessage = (mCalibrator.isCalibrated()) ?
173 res.getString(R.string.calibration_successful) + " " + mCalibrator.getAvgReprojectionError() :
174 res.getString(R.string.calibration_unsuccessful);
175 (Toast.makeText(CameraCalibrationActivity.this, resultMessage, Toast.LENGTH_SHORT)).show();
177 if (mCalibrator.isCalibrated()) {
178 CalibrationResult.save(CameraCalibrationActivity.this,
179 mCalibrator.getCameraMatrix(), mCalibrator.getDistortionCoefficients());
185 return super.onOptionsItemSelected(item);
189 public void onCameraViewStarted(int width, int height) {
190 if (mWidth != width || mHeight != height) {
193 mCalibrator = new CameraCalibrator(mWidth, mHeight);
194 if (CalibrationResult.tryLoad(this, mCalibrator.getCameraMatrix(), mCalibrator.getDistortionCoefficients())) {
195 mCalibrator.setCalibrated();
198 mOnCameraFrameRender = new OnCameraFrameRender(new CalibrationFrameRender(mCalibrator));
202 public void onCameraViewStopped() {
205 public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
206 return mOnCameraFrameRender.render(inputFrame);
210 public boolean onTouch(View v, MotionEvent event) {
211 Log.d(TAG, "onTouch invoked");
213 mCalibrator.addCorners();