feat: 切换后端至PaddleOCR-NCNN,切换工程为CMake

1.项目后端整体迁移至PaddleOCR-NCNN算法,已通过基本的兼容性测试
2.工程改为使用CMake组织,后续为了更好地兼容第三方库,不再提供QMake工程
3.重整权利声明文件,重整代码工程,确保最小化侵权风险

Log: 切换后端至PaddleOCR-NCNN,切换工程为CMake
Change-Id: I4d5d2c5d37505a4a24b389b1a4c5d12f17bfa38c
This commit is contained in:
wangzhengyang
2022-05-10 09:54:44 +08:00
parent ecdd171c6f
commit 718c41634f
10018 changed files with 3593797 additions and 186748 deletions

View File

@ -0,0 +1,6 @@
set(sample example-camera-calibration)
add_android_project(${sample} "${CMAKE_CURRENT_SOURCE_DIR}" LIBRARY_DEPS "${OPENCV_ANDROID_LIB_DIR}" SDK_TARGET 11 "${ANDROID_SDK_TARGET}")
if(TARGET ${sample})
add_dependencies(opencv_android_examples ${sample})
endif()

View File

@ -0,0 +1,31 @@
apply plugin: 'com.android.application'
android {
compileSdkVersion @ANDROID_COMPILE_SDK_VERSION@
defaultConfig {
applicationId "org.opencv.samples.cameracalibration"
minSdkVersion @ANDROID_MIN_SDK_VERSION@
targetSdkVersion @ANDROID_TARGET_SDK_VERSION@
versionCode 301
versionName "3.01"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
sourceSets {
main {
java.srcDirs = @ANDROID_SAMPLE_JAVA_PATH@
aidl.srcDirs = @ANDROID_SAMPLE_JAVA_PATH@
res.srcDirs = @ANDROID_SAMPLE_RES_PATH@
manifest.srcFile '@ANDROID_SAMPLE_MANIFEST_PATH@'
}
}
}
dependencies {
//implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation project(':opencv')
}

View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.opencv.samples.cameracalibration"
>
<application
android:label="@string/app_name"
android:icon="@drawable/icon">
<activity android:name="CameraCalibrationActivity"
android:label="@string/app_name"
android:screenOrientation="landscape"
android:configChanges="keyboardHidden|orientation">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<supports-screens android:resizeable="true"
android:smallScreens="true"
android:normalScreens="true"
android:largeScreens="true"
android:anyDensity="true" />
<uses-permission android:name="android.permission.CAMERA"/>
<uses-feature android:name="android.hardware.camera" android:required="false"/>
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false"/>
<uses-feature android:name="android.hardware.camera.front" android:required="false"/>
<uses-feature android:name="android.hardware.camera.front.autofocus" android:required="false"/>
</manifest>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -0,0 +1,12 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:opencv="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<org.opencv.android.JavaCameraView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/camera_calibration_java_surface_view" />
</LinearLayout>

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<group android:checkableBehavior="single">
<item android:id="@+id/calibrate"
android:title="@string/action_calibrate"
android:showAsAction="ifRoom|withText" />
<item android:id="@+id/preview_mode"
android:title="@string/preview_mode">
<menu>
<group android:checkableBehavior="single">
<item android:id="@+id/calibration"
android:title="@string/calibration"
android:checked="true" />
<item android:id="@+id/undistortion"
android:title="@string/undistortion" />
<item android:id="@+id/comparison"
android:title="@string/comparison" />
</group>
</menu>
</item>
</group>
</menu>

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">OCV Camera Calibration</string>
<string name="action_calibrate">Calibrate</string>
<string name="calibration">Calibration</string>
<string name="undistortion">Undistortion</string>
<string name="comparison">Comparison</string>
<string name="preview_mode">Preview mode</string>
<string name="calibration_successful">Successfully calibrated!\nAvg. re-projection error:</string>
<string name="calibration_unsuccessful">Unsuccessful calibration.\nTry again</string>
<string name="more_samples">Please, capture more samples</string>
<string name="calibrating">Calibrating...</string>
<string name="please_wait">Please, wait</string>
<string name="original">Original</string>
<string name="undistorted">Undistorted</string>
</resources>

View File

@ -0,0 +1,69 @@
package org.opencv.samples.cameracalibration;
import org.opencv.core.Mat;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;
public abstract class CalibrationResult {
private static final String TAG = "OCV::CalibrationResult";
private static final int CAMERA_MATRIX_ROWS = 3;
private static final int CAMERA_MATRIX_COLS = 3;
private static final int DISTORTION_COEFFICIENTS_SIZE = 5;
public static void save(Activity activity, Mat cameraMatrix, Mat distortionCoefficients) {
SharedPreferences sharedPref = activity.getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
double[] cameraMatrixArray = new double[CAMERA_MATRIX_ROWS * CAMERA_MATRIX_COLS];
cameraMatrix.get(0, 0, cameraMatrixArray);
for (int i = 0; i < CAMERA_MATRIX_ROWS; i++) {
for (int j = 0; j < CAMERA_MATRIX_COLS; j++) {
int id = i * CAMERA_MATRIX_ROWS + j;
editor.putFloat(Integer.toString(id), (float)cameraMatrixArray[id]);
}
}
double[] distortionCoefficientsArray = new double[DISTORTION_COEFFICIENTS_SIZE];
distortionCoefficients.get(0, 0, distortionCoefficientsArray);
int shift = CAMERA_MATRIX_ROWS * CAMERA_MATRIX_COLS;
for (int i = shift; i < DISTORTION_COEFFICIENTS_SIZE + shift; i++) {
editor.putFloat(Integer.toString(i), (float)distortionCoefficientsArray[i-shift]);
}
editor.apply();
Log.i(TAG, "Saved camera matrix: " + cameraMatrix.dump());
Log.i(TAG, "Saved distortion coefficients: " + distortionCoefficients.dump());
}
public static boolean tryLoad(Activity activity, Mat cameraMatrix, Mat distortionCoefficients) {
SharedPreferences sharedPref = activity.getPreferences(Context.MODE_PRIVATE);
if (sharedPref.getFloat("0", -1) == -1) {
Log.i(TAG, "No previous calibration results found");
return false;
}
double[] cameraMatrixArray = new double[CAMERA_MATRIX_ROWS * CAMERA_MATRIX_COLS];
for (int i = 0; i < CAMERA_MATRIX_ROWS; i++) {
for (int j = 0; j < CAMERA_MATRIX_COLS; j++) {
int id = i * CAMERA_MATRIX_ROWS + j;
cameraMatrixArray[id] = sharedPref.getFloat(Integer.toString(id), -1);
}
}
cameraMatrix.put(0, 0, cameraMatrixArray);
Log.i(TAG, "Loaded camera matrix: " + cameraMatrix.dump());
double[] distortionCoefficientsArray = new double[DISTORTION_COEFFICIENTS_SIZE];
int shift = CAMERA_MATRIX_ROWS * CAMERA_MATRIX_COLS;
for (int i = shift; i < DISTORTION_COEFFICIENTS_SIZE + shift; i++) {
distortionCoefficientsArray[i - shift] = sharedPref.getFloat(Integer.toString(i), -1);
}
distortionCoefficients.put(0, 0, distortionCoefficientsArray);
Log.i(TAG, "Loaded distortion coefficients: " + distortionCoefficients.dump());
return true;
}
}

View File

@ -0,0 +1,235 @@
// This sample is based on "Camera calibration With OpenCV" tutorial:
// https://docs.opencv.org/3.4/d4/d94/tutorial_camera_calibration.html
//
// It uses standard OpenCV asymmetric circles grid pattern 11x4:
// https://github.com/opencv/opencv/blob/3.4/doc/acircles_pattern.png
// The results are the camera matrix and 5 distortion coefficients.
//
// Tap on highlighted pattern to capture pattern corners for calibration.
// Move pattern along the whole screen and capture data.
//
// When you've captured necessary amount of pattern corners (usually ~20 are enough),
// press "Calibrate" button for performing camera calibration.
package org.opencv.samples.cameracalibration;
import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.CameraActivity;
import org.opencv.android.CameraBridgeViewBase;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
import org.opencv.core.Mat;
import android.app.ProgressDialog;
import android.content.res.Resources;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.WindowManager;
import android.widget.Toast;
import java.util.Collections;
import java.util.List;
public class CameraCalibrationActivity extends CameraActivity implements CvCameraViewListener2, OnTouchListener {
private static final String TAG = "OCVSample::Activity";
private CameraBridgeViewBase mOpenCvCameraView;
private CameraCalibrator mCalibrator;
private OnCameraFrameRender mOnCameraFrameRender;
private Menu mMenu;
private int mWidth;
private int mHeight;
private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
@Override
public void onManagerConnected(int status) {
switch (status) {
case LoaderCallbackInterface.SUCCESS:
{
Log.i(TAG, "OpenCV loaded successfully");
mOpenCvCameraView.enableView();
mOpenCvCameraView.setOnTouchListener(CameraCalibrationActivity.this);
} break;
default:
{
super.onManagerConnected(status);
} break;
}
}
};
public CameraCalibrationActivity() {
Log.i(TAG, "Instantiated new " + this.getClass());
}
@Override
public void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "called onCreate");
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.camera_calibration_surface_view);
mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.camera_calibration_java_surface_view);
mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);
mOpenCvCameraView.setCvCameraViewListener(this);
}
@Override
public void onPause()
{
super.onPause();
if (mOpenCvCameraView != null)
mOpenCvCameraView.disableView();
}
@Override
public void onResume()
{
super.onResume();
if (!OpenCVLoader.initDebug()) {
Log.d(TAG, "Internal OpenCV library not found. Using OpenCV Manager for initialization");
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_0_0, this, mLoaderCallback);
} else {
Log.d(TAG, "OpenCV library found inside package. Using it!");
mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
}
}
@Override
protected List<? extends CameraBridgeViewBase> getCameraViewList() {
return Collections.singletonList(mOpenCvCameraView);
}
public void onDestroy() {
super.onDestroy();
if (mOpenCvCameraView != null)
mOpenCvCameraView.disableView();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.calibration, menu);
mMenu = menu;
return true;
}
@Override
public boolean onPrepareOptionsMenu (Menu menu) {
super.onPrepareOptionsMenu(menu);
menu.findItem(R.id.preview_mode).setEnabled(true);
if (mCalibrator != null && !mCalibrator.isCalibrated()) {
menu.findItem(R.id.preview_mode).setEnabled(false);
}
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.calibration:
mOnCameraFrameRender =
new OnCameraFrameRender(new CalibrationFrameRender(mCalibrator));
item.setChecked(true);
return true;
case R.id.undistortion:
mOnCameraFrameRender =
new OnCameraFrameRender(new UndistortionFrameRender(mCalibrator));
item.setChecked(true);
return true;
case R.id.comparison:
mOnCameraFrameRender =
new OnCameraFrameRender(new ComparisonFrameRender(mCalibrator, mWidth, mHeight, getResources()));
item.setChecked(true);
return true;
case R.id.calibrate:
final Resources res = getResources();
if (mCalibrator.getCornersBufferSize() < 2) {
(Toast.makeText(this, res.getString(R.string.more_samples), Toast.LENGTH_SHORT)).show();
return true;
}
mOnCameraFrameRender = new OnCameraFrameRender(new PreviewFrameRender());
new AsyncTask<Void, Void, Void>() {
private ProgressDialog calibrationProgress;
@Override
protected void onPreExecute() {
calibrationProgress = new ProgressDialog(CameraCalibrationActivity.this);
calibrationProgress.setTitle(res.getString(R.string.calibrating));
calibrationProgress.setMessage(res.getString(R.string.please_wait));
calibrationProgress.setCancelable(false);
calibrationProgress.setIndeterminate(true);
calibrationProgress.show();
}
@Override
protected Void doInBackground(Void... arg0) {
mCalibrator.calibrate();
return null;
}
@Override
protected void onPostExecute(Void result) {
calibrationProgress.dismiss();
mCalibrator.clearCorners();
mOnCameraFrameRender = new OnCameraFrameRender(new CalibrationFrameRender(mCalibrator));
String resultMessage = (mCalibrator.isCalibrated()) ?
res.getString(R.string.calibration_successful) + " " + mCalibrator.getAvgReprojectionError() :
res.getString(R.string.calibration_unsuccessful);
(Toast.makeText(CameraCalibrationActivity.this, resultMessage, Toast.LENGTH_SHORT)).show();
if (mCalibrator.isCalibrated()) {
CalibrationResult.save(CameraCalibrationActivity.this,
mCalibrator.getCameraMatrix(), mCalibrator.getDistortionCoefficients());
}
}
}.execute();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
public void onCameraViewStarted(int width, int height) {
if (mWidth != width || mHeight != height) {
mWidth = width;
mHeight = height;
mCalibrator = new CameraCalibrator(mWidth, mHeight);
if (CalibrationResult.tryLoad(this, mCalibrator.getCameraMatrix(), mCalibrator.getDistortionCoefficients())) {
mCalibrator.setCalibrated();
} else {
if (mMenu != null && !mCalibrator.isCalibrated()) {
mMenu.findItem(R.id.preview_mode).setEnabled(false);
}
}
mOnCameraFrameRender = new OnCameraFrameRender(new CalibrationFrameRender(mCalibrator));
}
}
public void onCameraViewStopped() {
}
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
return mOnCameraFrameRender.render(inputFrame);
}
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.d(TAG, "onTouch invoked");
mCalibrator.addCorners();
return false;
}
}

View File

@ -0,0 +1,170 @@
package org.opencv.samples.cameracalibration;
import java.util.ArrayList;
import java.util.List;
import org.opencv.calib3d.Calib3d;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfDouble;
import org.opencv.core.MatOfPoint2f;
import org.opencv.core.MatOfPoint3f;
import org.opencv.core.Point;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.imgproc.Imgproc;
import android.util.Log;
public class CameraCalibrator {
private static final String TAG = "OCV::CameraCalibrator";
private final Size mPatternSize = new Size(4, 11);
private final int mCornersSize = (int)(mPatternSize.width * mPatternSize.height);
private boolean mPatternWasFound = false;
private MatOfPoint2f mCorners = new MatOfPoint2f();
private List<Mat> mCornersBuffer = new ArrayList<>();
private boolean mIsCalibrated = false;
private Mat mCameraMatrix = new Mat();
private Mat mDistortionCoefficients = new Mat();
private int mFlags;
private double mRms;
private double mSquareSize = 0.0181;
private Size mImageSize;
public CameraCalibrator(int width, int height) {
mImageSize = new Size(width, height);
mFlags = Calib3d.CALIB_FIX_PRINCIPAL_POINT +
Calib3d.CALIB_ZERO_TANGENT_DIST +
Calib3d.CALIB_FIX_ASPECT_RATIO +
Calib3d.CALIB_FIX_K4 +
Calib3d.CALIB_FIX_K5;
Mat.eye(3, 3, CvType.CV_64FC1).copyTo(mCameraMatrix);
mCameraMatrix.put(0, 0, 1.0);
Mat.zeros(5, 1, CvType.CV_64FC1).copyTo(mDistortionCoefficients);
Log.i(TAG, "Instantiated new " + this.getClass());
}
public void processFrame(Mat grayFrame, Mat rgbaFrame) {
findPattern(grayFrame);
renderFrame(rgbaFrame);
}
public void calibrate() {
ArrayList<Mat> rvecs = new ArrayList<>();
ArrayList<Mat> tvecs = new ArrayList<>();
Mat reprojectionErrors = new Mat();
ArrayList<Mat> objectPoints = new ArrayList<>();
objectPoints.add(Mat.zeros(mCornersSize, 1, CvType.CV_32FC3));
calcBoardCornerPositions(objectPoints.get(0));
for (int i = 1; i < mCornersBuffer.size(); i++) {
objectPoints.add(objectPoints.get(0));
}
Calib3d.calibrateCamera(objectPoints, mCornersBuffer, mImageSize,
mCameraMatrix, mDistortionCoefficients, rvecs, tvecs, mFlags);
mIsCalibrated = Core.checkRange(mCameraMatrix)
&& Core.checkRange(mDistortionCoefficients);
mRms = computeReprojectionErrors(objectPoints, rvecs, tvecs, reprojectionErrors);
Log.i(TAG, String.format("Average re-projection error: %f", mRms));
Log.i(TAG, "Camera matrix: " + mCameraMatrix.dump());
Log.i(TAG, "Distortion coefficients: " + mDistortionCoefficients.dump());
}
public void clearCorners() {
mCornersBuffer.clear();
}
private void calcBoardCornerPositions(Mat corners) {
final int cn = 3;
float[] positions = new float[mCornersSize * cn];
for (int i = 0; i < mPatternSize.height; i++) {
for (int j = 0; j < mPatternSize.width * cn; j += cn) {
positions[(int) (i * mPatternSize.width * cn + j + 0)] =
(2 * (j / cn) + i % 2) * (float) mSquareSize;
positions[(int) (i * mPatternSize.width * cn + j + 1)] =
i * (float) mSquareSize;
positions[(int) (i * mPatternSize.width * cn + j + 2)] = 0;
}
}
corners.create(mCornersSize, 1, CvType.CV_32FC3);
corners.put(0, 0, positions);
}
private double computeReprojectionErrors(List<Mat> objectPoints,
List<Mat> rvecs, List<Mat> tvecs, Mat perViewErrors) {
MatOfPoint2f cornersProjected = new MatOfPoint2f();
double totalError = 0;
double error;
float[] viewErrors = new float[objectPoints.size()];
MatOfDouble distortionCoefficients = new MatOfDouble(mDistortionCoefficients);
int totalPoints = 0;
for (int i = 0; i < objectPoints.size(); i++) {
MatOfPoint3f points = new MatOfPoint3f(objectPoints.get(i));
Calib3d.projectPoints(points, rvecs.get(i), tvecs.get(i),
mCameraMatrix, distortionCoefficients, cornersProjected);
error = Core.norm(mCornersBuffer.get(i), cornersProjected, Core.NORM_L2);
int n = objectPoints.get(i).rows();
viewErrors[i] = (float) Math.sqrt(error * error / n);
totalError += error * error;
totalPoints += n;
}
perViewErrors.create(objectPoints.size(), 1, CvType.CV_32FC1);
perViewErrors.put(0, 0, viewErrors);
return Math.sqrt(totalError / totalPoints);
}
private void findPattern(Mat grayFrame) {
mPatternWasFound = Calib3d.findCirclesGrid(grayFrame, mPatternSize,
mCorners, Calib3d.CALIB_CB_ASYMMETRIC_GRID);
}
public void addCorners() {
if (mPatternWasFound) {
mCornersBuffer.add(mCorners.clone());
}
}
private void drawPoints(Mat rgbaFrame) {
Calib3d.drawChessboardCorners(rgbaFrame, mPatternSize, mCorners, mPatternWasFound);
}
private void renderFrame(Mat rgbaFrame) {
drawPoints(rgbaFrame);
Imgproc.putText(rgbaFrame, "Captured: " + mCornersBuffer.size(), new Point(rgbaFrame.cols() / 3 * 2, rgbaFrame.rows() * 0.1),
Imgproc.FONT_HERSHEY_SIMPLEX, 1.0, new Scalar(255, 255, 0));
}
public Mat getCameraMatrix() {
return mCameraMatrix;
}
public Mat getDistortionCoefficients() {
return mDistortionCoefficients;
}
public int getCornersBufferSize() {
return mCornersBuffer.size();
}
public double getAvgReprojectionError() {
return mRms;
}
public boolean isCalibrated() {
return mIsCalibrated;
}
public void setCalibrated() {
mIsCalibrated = true;
}
}

View File

@ -0,0 +1,103 @@
package org.opencv.samples.cameracalibration;
import java.util.ArrayList;
import java.util.List;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;
import org.opencv.calib3d.Calib3d;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfPoint;
import org.opencv.core.Point;
import org.opencv.core.Range;
import org.opencv.core.Scalar;
import org.opencv.imgproc.Imgproc;
import android.content.res.Resources;
abstract class FrameRender {
protected CameraCalibrator mCalibrator;
public abstract Mat render(CvCameraViewFrame inputFrame);
}
class PreviewFrameRender extends FrameRender {
@Override
public Mat render(CvCameraViewFrame inputFrame) {
return inputFrame.rgba();
}
}
class CalibrationFrameRender extends FrameRender {
public CalibrationFrameRender(CameraCalibrator calibrator) {
mCalibrator = calibrator;
}
@Override
public Mat render(CvCameraViewFrame inputFrame) {
Mat rgbaFrame = inputFrame.rgba();
Mat grayFrame = inputFrame.gray();
mCalibrator.processFrame(grayFrame, rgbaFrame);
return rgbaFrame;
}
}
class UndistortionFrameRender extends FrameRender {
public UndistortionFrameRender(CameraCalibrator calibrator) {
mCalibrator = calibrator;
}
@Override
public Mat render(CvCameraViewFrame inputFrame) {
Mat renderedFrame = new Mat(inputFrame.rgba().size(), inputFrame.rgba().type());
Calib3d.undistort(inputFrame.rgba(), renderedFrame,
mCalibrator.getCameraMatrix(), mCalibrator.getDistortionCoefficients());
return renderedFrame;
}
}
class ComparisonFrameRender extends FrameRender {
private int mWidth;
private int mHeight;
private Resources mResources;
public ComparisonFrameRender(CameraCalibrator calibrator, int width, int height, Resources resources) {
mCalibrator = calibrator;
mWidth = width;
mHeight = height;
mResources = resources;
}
@Override
public Mat render(CvCameraViewFrame inputFrame) {
Mat undistortedFrame = new Mat(inputFrame.rgba().size(), inputFrame.rgba().type());
Calib3d.undistort(inputFrame.rgba(), undistortedFrame,
mCalibrator.getCameraMatrix(), mCalibrator.getDistortionCoefficients());
Mat comparisonFrame = inputFrame.rgba();
undistortedFrame.colRange(new Range(0, mWidth / 2)).copyTo(comparisonFrame.colRange(new Range(mWidth / 2, mWidth)));
List<MatOfPoint> border = new ArrayList<MatOfPoint>();
final int shift = (int)(mWidth * 0.005);
border.add(new MatOfPoint(new Point(mWidth / 2 - shift, 0), new Point(mWidth / 2 + shift, 0),
new Point(mWidth / 2 + shift, mHeight), new Point(mWidth / 2 - shift, mHeight)));
Imgproc.fillPoly(comparisonFrame, border, new Scalar(255, 255, 255));
Imgproc.putText(comparisonFrame, mResources.getString(R.string.original), new Point(mWidth * 0.1, mHeight * 0.1),
Imgproc.FONT_HERSHEY_SIMPLEX, 1.0, new Scalar(255, 255, 0));
Imgproc.putText(comparisonFrame, mResources.getString(R.string.undistorted), new Point(mWidth * 0.6, mHeight * 0.1),
Imgproc.FONT_HERSHEY_SIMPLEX, 1.0, new Scalar(255, 255, 0));
return comparisonFrame;
}
}
class OnCameraFrameRender {
private FrameRender mFrameRender;
public OnCameraFrameRender(FrameRender frameRender) {
mFrameRender = frameRender;
}
public Mat render(CvCameraViewFrame inputFrame) {
return mFrameRender.render(inputFrame);
}
}