From f04c5806d1bd55fd1241bc3284005b7ae25055ca Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 5 May 2014 12:32:50 -0430 Subject: [PATCH] Added intradocumentation. --- src/ve/ucv/ciens/ccg/nxtar/MainActivity.java | 179 ++++++++++++++----- 1 file changed, 130 insertions(+), 49 deletions(-) diff --git a/src/ve/ucv/ciens/ccg/nxtar/MainActivity.java b/src/ve/ucv/ciens/ccg/nxtar/MainActivity.java index cab216c..9d4b2fa 100644 --- a/src/ve/ucv/ciens/ccg/nxtar/MainActivity.java +++ b/src/ve/ucv/ciens/ccg/nxtar/MainActivity.java @@ -43,6 +43,12 @@ import com.badlogic.gdx.backends.android.AndroidApplication; import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration; import com.badlogic.gdx.controllers.mappings.Ouya; +/** + *

The main activity of the application.

+ * + *

Provides operating system services to the LibGDX platform + * independant code, and handles OpenCV initialization and api calls.

+ */ public class MainActivity extends AndroidApplication implements OSFunctionalityProvider, CVProcessor{ private static final String TAG = "NXTAR_ANDROID_MAIN"; private static final String CLASS_NAME = MainActivity.class.getSimpleName(); @@ -62,6 +68,10 @@ public class MainActivity extends AndroidApplication implements OSFunctionalityP public native boolean findCalibrationPattern(long inMat, long outMat, float[] points); public native double calibrateCameraParameters(long camMat, long distMat, long frame, float[] calibrationPoints); + /** + *

Static block. Tries to load OpenCV and the native method implementations + * statically if running on an OUYA device.

+ */ static{ if(Ouya.runningOnOuya){ if(!OpenCVLoader.initDebug()) @@ -76,28 +86,41 @@ public class MainActivity extends AndroidApplication implements OSFunctionalityP } } + /** + *

Initializes this activity

+ * + *

This method handles the initialization of LibGDX and OpenCV. OpenCV is + * loaded the asynchronous method if the devices is not an OUYA console. + */ @Override public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); cameraCalibrated = false; + // Set screen orientation. Portrait on mobile devices, landscape on OUYA. if(!Ouya.runningOnOuya){ setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); }else{ setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); } + // Set up the Android related variables. uiHandler = new Handler(); uiContext = this; wifiManager = (WifiManager)getSystemService(Context.WIFI_SERVICE); + // Attempt to initialize OpenCV. if(!Ouya.runningOnOuya){ + // If running on a moble device, use the asynchronous method aided + // by the OpenCV Manager app. loaderCallback = new BaseLoaderCallback(this){ @Override public void onManagerConnected(int status){ switch(status){ case LoaderCallbackInterface.SUCCESS: + // If successfully initialized then load the native method implementations and + // initialize the static matrices. System.loadLibrary("cvproc"); ocvOn = true; cameraMatrix = new Mat(); @@ -105,34 +128,46 @@ public class MainActivity extends AndroidApplication implements OSFunctionalityP break; default: Toast.makeText(uiContext, R.string.ocv_failed, Toast.LENGTH_LONG).show(); - Gdx.app.exit(); + ocvOn = false; break; } } }; + // Launch the asynchronous initializer. OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_7, this, loaderCallback); + }else{ - if(!ocvOn){ - Toast.makeText(uiContext, R.string.ocv_failed, Toast.LENGTH_LONG).show(); - }else{ + // If running on an OUYA device. + if(ocvOn){ + // If OpenCV loaded successfully then initialize the native matrices. cameraMatrix = new Mat(); distortionCoeffs = new Mat(); + }else{ + Toast.makeText(uiContext, R.string.ocv_failed, Toast.LENGTH_LONG).show(); } } + // Configure LibGDX. AndroidApplicationConfiguration cfg = new AndroidApplicationConfiguration(); cfg.useGL20 = true; cfg.useAccelerometer = false; cfg.useCompass = false; cfg.useWakelock = true; + // Launch the LibGDX core game class. initialize(new NxtARCore(this), cfg); } //////////////////////////////////////////////// // OSFunctionalityProvider interface methods. // //////////////////////////////////////////////// + + /** + *

Implementation of the showShortToast method.

+ * + *

Shows a short message on screen using Android's toast mechanism.

+ */ @Override public void showShortToast(final String msg){ uiHandler.post(new Runnable(){ @@ -143,6 +178,11 @@ public class MainActivity extends AndroidApplication implements OSFunctionalityP }); } + /** + *

Implementation of the showLongToast method.

+ * + *

Shows a long message on screen using Android's toast mechanism.

+ */ @Override public void showLongToast(final String msg){ uiHandler.post(new Runnable(){ @@ -153,6 +193,11 @@ public class MainActivity extends AndroidApplication implements OSFunctionalityP }); } + /** + *

Implementation of the enableMulticast method.

+ * + *

Enable the transmision and reception of multicast network messages.

+ */ @Override public void enableMulticast(){ Gdx.app.log(TAG, CLASS_NAME + ".enableMulticast() :: Requesting multicast lock."); @@ -161,6 +206,11 @@ public class MainActivity extends AndroidApplication implements OSFunctionalityP multicastLock.acquire(); } + /** + *

Implementation of the disableMulticast method.

+ * + *

Disables the transmision and reception of multicast network messages.

+ */ @Override public void disableMulticast(){ Gdx.app.log(TAG, CLASS_NAME + ".disableMulticast() :: Releasing multicast lock."); @@ -190,31 +240,33 @@ public class MainActivity extends AndroidApplication implements OSFunctionalityP if(ocvOn){ int codes[] = new int[15]; Bitmap tFrame, mFrame; - - tFrame = BitmapFactory.decodeByteArray(frame, 0, frame.length); - Mat inImg = new Mat(); Mat outImg = new Mat(); + + // Decode the input image and convert it to an OpenCV matrix. + tFrame = BitmapFactory.decodeByteArray(frame, 0, frame.length); Utils.bitmapToMat(tFrame, inImg); + // Find up to 15 markers in the input image. getMarkerCodesAndLocations(inImg.getNativeObjAddr(), outImg.getNativeObjAddr(), codes); - //Mat temp = new Mat(); - //Imgproc.cvtColor(outImg, temp, Imgproc.COLOR_BGR2RGB); - + // Encode the output image as a JPEG image. mFrame = Bitmap.createBitmap(outImg.cols(), outImg.rows(), Bitmap.Config.RGB_565); Utils.matToBitmap(outImg, mFrame); mFrame.compress(CompressFormat.JPEG, 100, outputStream); + // Create the output data structure. CVMarkerData data = new CVMarkerData(); data.outFrame = outputStream.toByteArray(); data.markerCodes = codes; + // Clean up memory. tFrame.recycle(); mFrame.recycle(); outputStream.reset(); return data; + }else{ Gdx.app.debug(TAG, CLASS_NAME + ".findMarkersInFrame(): OpenCV is not ready or failed to load."); return null; @@ -222,7 +274,17 @@ public class MainActivity extends AndroidApplication implements OSFunctionalityP } /** + *

Implementation of the findCalibrationPattern method.

* + *

Attempts to detect a checkerboard calibration pattern in the input image. + * If the pattenr is found the method returns an image with the pattern + * highlighted and the spatial location of the calibration points in the + * output data structure.

+ * + * @param frame The JPEG encoded input image. + * @return A data structure containing the processed output image and the + * location of the calibration points. If the pattern was not found, the returnd + * calibration points array is null. */ @Override public CVCalibrationData findCalibrationPattern(byte[] frame){ @@ -255,6 +317,7 @@ public class MainActivity extends AndroidApplication implements OSFunctionalityP outputStream.reset(); return data; + }else{ Gdx.app.debug(TAG, CLASS_NAME + ".findCalibrationPattern(): OpenCV is not ready or failed to load."); return null; @@ -262,44 +325,9 @@ public class MainActivity extends AndroidApplication implements OSFunctionalityP } /** + *

Implementation of the calibrateCamera method.

* - */ - @Override - public byte[] undistortFrame(byte[] frame){ - if(ocvOn){ - byte undistortedFrame[]; - Bitmap tFrame, mFrame; - Mat inImg = new Mat(), outImg = new Mat(); - - // Decode the input frame and convert it to an OpenCV Matrix. - tFrame = BitmapFactory.decodeByteArray(frame, 0, frame.length); - Utils.bitmapToMat(tFrame, inImg); - - // Apply the undistort correction to the input frame. - Imgproc.undistort(inImg, outImg, cameraMatrix, distortionCoeffs); - - // Encode the output image as a JPEG image. - mFrame = Bitmap.createBitmap(outImg.cols(), outImg.rows(), Bitmap.Config.RGB_565); - Utils.matToBitmap(outImg, mFrame); - mFrame.compress(CompressFormat.JPEG, 100, outputStream); - - // Prepare the return frame. - undistortedFrame = outputStream.toByteArray(); - - // Clean up memory. - tFrame.recycle(); - mFrame.recycle(); - outputStream.reset(); - - return undistortedFrame; - }else{ - Gdx.app.debug(TAG, CLASS_NAME + ".undistortFrame(): OpenCV is not ready or failed to load."); - return null; - } - } - - /** - * + *

Obtains the intrinsic camera parameters necesary for calibration.

*/ @Override public void calibrateCamera(float[][] calibrationSamples, byte[] frame) { @@ -309,6 +337,8 @@ public class MainActivity extends AndroidApplication implements OSFunctionalityP Bitmap tFrame; Mat inImg = new Mat(); + // Save the calibration points on a one dimensional array for easier parameter passing + // to the native code. for(int i = 0; i < ProjectConstants.CALIBRATION_SAMPLES; i++){ for(int j = 0, p = 0; j < ProjectConstants.CALIBRATION_PATTERN_POINTS; j++, p += 2){ calibrationPoints[p + (w * i)] = calibrationSamples[i][p]; @@ -316,13 +346,13 @@ public class MainActivity extends AndroidApplication implements OSFunctionalityP } } + // Decode the input image and convert it to an OpenCV matrix. tFrame = BitmapFactory.decodeByteArray(frame, 0, frame.length); Utils.bitmapToMat(tFrame, inImg); + // Attempt to obtain the camera parameters. double error = calibrateCameraParameters(cameraMatrix.getNativeObjAddr(), distortionCoeffs.getNativeObjAddr(), inImg.getNativeObjAddr(), calibrationPoints); - Gdx.app.log(TAG, CLASS_NAME + "calibrateCamera(): calibrateCameraParameters retured " + Double.toString(error)); - cameraCalibrated = true; }else{ @@ -330,8 +360,59 @@ public class MainActivity extends AndroidApplication implements OSFunctionalityP } } + /** + *

Implementation of the undistorFrame method.

* + *

Removes camera lens distortion from the input image using the + * camera parameters obtained by the calibrateCamera method.

+ * + * @return A JPEG encoded image that is the input image after distortion correction. If the + * camera has not been calibrated or OpenCV failed to load returns null. + */ + @Override + public byte[] undistortFrame(byte[] frame){ + if(ocvOn){ + if(cameraCalibrated){ + byte undistortedFrame[]; + Bitmap tFrame, mFrame; + Mat inImg = new Mat(), outImg = new Mat(); + + // Decode the input frame and convert it to an OpenCV Matrix. + tFrame = BitmapFactory.decodeByteArray(frame, 0, frame.length); + Utils.bitmapToMat(tFrame, inImg); + + // Apply the undistort correction to the input frame. + Imgproc.undistort(inImg, outImg, cameraMatrix, distortionCoeffs); + + // Encode the output image as a JPEG image. + mFrame = Bitmap.createBitmap(outImg.cols(), outImg.rows(), Bitmap.Config.RGB_565); + Utils.matToBitmap(outImg, mFrame); + mFrame.compress(CompressFormat.JPEG, 100, outputStream); + + // Prepare the return frame. + undistortedFrame = outputStream.toByteArray(); + + // Clean up memory. + tFrame.recycle(); + mFrame.recycle(); + outputStream.reset(); + + return undistortedFrame; + + }else{ + Gdx.app.debug(TAG, CLASS_NAME + ".undistortFrame(): Camera has not been calibrated."); + return null; + } + }else{ + Gdx.app.debug(TAG, CLASS_NAME + ".undistortFrame(): OpenCV is not ready or failed to load."); + return null; + } + } + + /** + *

Indicates if OpenCV has been sucessfully initialized and used + * to obtain the camera parameters for calibration.

*/ @Override public boolean cameraIsCalibrated() {