diff --git a/jni/cv_proc.cpp b/jni/cv_proc.cpp index 5d6b631..3ecd1ff 100644 --- a/jni/cv_proc.cpp +++ b/jni/cv_proc.cpp @@ -20,11 +20,11 @@ #include "marker.hpp" -//#define CAN_LOG +//#define LOG_ENABLED #define POINTS_PER_CALIBRATION_SAMPLE 54 #define CALIBRATION_SAMPLES 10 -#ifdef CAN_LOG +#ifdef LOG_ENABLED #define log(TAG, MSG) (__android_log_write(ANDROID_LOG_DEBUG, TAG, MSG)) #else #define log(TAG, MSG) ; @@ -35,65 +35,79 @@ const char * TAG = "CVPROC_NATIVE"; extern "C"{ /** - * + * JNI wrapper around the nxtar::getAllMarkers() method. */ JNIEXPORT void JNICALL Java_ve_ucv_ciens_ccg_nxtar_MainActivity_getMarkerCodesAndLocations(JNIEnv* env, jobject jobj, jlong addrMatIn, jlong addrMatOut, jintArray codes){ char codeMsg[128]; std::vector vCodes; + cv::Mat temp; log(TAG, "getMarkerCodesAndLocations(): Requesting native data."); + // Get the native object addresses. cv::Mat& myuv = *(cv::Mat*)addrMatIn; cv::Mat& mbgr = *(cv::Mat*)addrMatOut; jint * _codes = env->GetIntArrayElements(codes, 0); - cv::Mat temp; + // Convert the input image to the BGR color space. log(TAG, "getMarkerCodesAndLocations(): Converting color space before processing."); cv::cvtColor(myuv, temp, CV_RGB2BGR); + // Find all markers in the input image. log(TAG, "getMarkerCodesAndLocations(): Finding markers."); nxtar::getAllMarkers(vCodes, temp); + // Copy the marker codes to the output vector. log(TAG, "getMarkerCodesAndLocations(): Copying marker codes."); for(int i = 0; i < vCodes.size() && i < 15; i++){ _codes[i] = (jint)vCodes[i]; } vCodes.clear(); + // Convert the output image back to the RGB color space. cv::cvtColor(temp, mbgr, CV_BGR2RGB); + // Release native data. log(TAG, "getMarkerCodesAndLocations(): Releasing native data."); env->ReleaseIntArrayElements(codes, _codes, 0); } /** - * + * JNI wrapper around the nxtar::findCalibrationPattern() method. */ JNIEXPORT jboolean JNICALL Java_ve_ucv_ciens_ccg_nxtar_MainActivity_findCalibrationPattern(JNIEnv* env, jobject jobj, jlong addrMatIn, jlong addrMatOut, jfloatArray points){ nxtar::points_vector v_points; bool found; + cv::Mat temp; log(TAG, "findCalibrationPattern(): Requesting native data."); + // Get the native object addresses. cv::Mat& myuv = *(cv::Mat*)addrMatIn; cv::Mat& mbgr = *(cv::Mat*)addrMatOut; jfloat * _points = env->GetFloatArrayElements(points, 0); - cv::Mat temp; + // Convert the input image to the BGR color space. log(TAG, "findCalibrationPattern(): Converting color space before processing."); cv::cvtColor(myuv, temp, CV_RGB2BGR); + // Find the calibration points in the input image. log(TAG, "findCalibrationPattern(): Finding calibration pattern."); found = nxtar::findCalibrationPattern(v_points, temp); - log(TAG, "findCalibrationPattern(): Copying calibration points."); - for(size_t i = 0, p = 0; i < v_points.size(); i++, p += 2){ - _points[p] = (jfloat)v_points[i].x; - _points[p + 1] = (jfloat)v_points[i].y; + // If the points were found then save them to the output array. + if(found){ + log(TAG, "findCalibrationPattern(): Copying calibration points."); + for(size_t i = 0, p = 0; i < v_points.size(); i++, p += 2){ + _points[p] = (jfloat)v_points[i].x; + _points[p + 1] = (jfloat)v_points[i].y; + } } + // Convert the output image back to the RGB color space. cv::cvtColor(temp, mbgr, CV_BGR2RGB); + // Release native data. log(TAG, "findCalibrationPattern(): Releasing native data."); env->ReleaseFloatArrayElements(points, _points, 0); @@ -101,7 +115,7 @@ JNIEXPORT jboolean JNICALL Java_ve_ucv_ciens_ccg_nxtar_MainActivity_findCalibrat } /** - * + * JNI wrapper around the nxtar::getCameraParameters() method. */ JNIEXPORT jdouble JNICALL Java_ve_ucv_ciens_ccg_nxtar_MainActivity_calibrateCameraParameters(JNIEnv* env, jobject jobj, jlong addrMatIn, jlong addrMatOut, jlong addrMatFrame, jfloatArray points){ double error; diff --git a/src/ve/ucv/ciens/ccg/nxtar/MainActivity.java b/src/ve/ucv/ciens/ccg/nxtar/MainActivity.java index 9d4b2fa..7c12214 100644 --- a/src/ve/ucv/ciens/ccg/nxtar/MainActivity.java +++ b/src/ve/ucv/ciens/ccg/nxtar/MainActivity.java @@ -50,23 +50,95 @@ import com.badlogic.gdx.controllers.mappings.Ouya; * independant code, and handles OpenCV initialization and api calls.

*/ public class MainActivity extends AndroidApplication implements OSFunctionalityProvider, CVProcessor{ + /** + * Tag used for logging. + */ private static final String TAG = "NXTAR_ANDROID_MAIN"; + + /** + * Class name used for logging. + */ private static final String CLASS_NAME = MainActivity.class.getSimpleName(); + /** + * Output stream used to codify images as JPEG using Android's Bitmap class. + */ private static final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - private static boolean ocvOn = false; - private static Mat cameraMatrix, distortionCoeffs; + /** + * Indicates if OpenCV was initialized sucessfully. + */ + private static boolean ocvOn = false; + + /** + * Intrinsic camera matrix. + */ + private static Mat cameraMatrix; + + /** + * Distortion coeffitients matrix. + */ + private static Mat distortionCoeffs; + + /** + * Used to set and release multicast locks. + */ private WifiManager wifiManager; + + /** + * Used to maintain the multicast lock during the service discovery procedure. + */ private MulticastLock multicastLock; + + /** + * Handler used for requesting toast messages from the core LibGDX code. + */ private Handler uiHandler; + + /** + * User interface context used to show the toast messages. + */ private Context uiContext; + + /** + * OpenCV asynchronous initializer callback for mobile devices. + */ private BaseLoaderCallback loaderCallback; + + /** + * Indicates if the current video streaming camera has been calibrated. + */ private boolean cameraCalibrated; - public native void getMarkerCodesAndLocations(long inMat, long outMat, int[] codes); - public native boolean findCalibrationPattern(long inMat, long outMat, float[] points); - public native double calibrateCameraParameters(long camMat, long distMat, long frame, float[] calibrationPoints); + /** + *

Wrapper for the getAllMarkers native function.

+ * + * @param inMat INPUT. The image to analize. + * @param outMat OUTPUT. The image with the markers highlighted. + * @param codes OUTPUT. The codes for each marker detected. Must be 15 elements long. + */ + private native void getMarkerCodesAndLocations(long inMat, long outMat, int[] codes); + + /** + *

Wrapper for the findCalibrationPattern native function.

+ * + * @param inMat INPUT. The image to analize. + * @param outMat OUTPUT. The image with the calibration pattern highlighted. + * @param points OUTPUT. The spatial location of the calibration points if found. + * @return True if the calibration pattern was found. False otherwise. + */ + private native boolean findCalibrationPattern(long inMat, long outMat, float[] points); + + /** + *

Wrapper around the getCameraParameters native function.

+ * + * @param camMat OUTPUT. The intrinsic camera matrix. + * @param distMat OUTPUT. The distortion coeffitients matrix. + * @param frame INPUT. A sample input image from the camera to calibrate. + * @param calibrationPoints INPUT. The calibration points of all samples. + * @return The calibration error as returned by OpenCV. + */ + private native double calibrateCameraParameters(long camMat, long distMat, long frame, float[] calibrationPoints); /** *

Static block. Tries to load OpenCV and the native method implementations @@ -90,7 +162,9 @@ 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. + * loaded the asynchronous method if the devices is not an OUYA console.

+ * + * @param savedInstanceState The application state if it was saved in a previous run. */ @Override public void onCreate(Bundle savedInstanceState){ @@ -126,6 +200,7 @@ public class MainActivity extends AndroidApplication implements OSFunctionalityP cameraMatrix = new Mat(); distortionCoeffs = new Mat(); break; + default: Toast.makeText(uiContext, R.string.ocv_failed, Toast.LENGTH_LONG).show(); ocvOn = false; @@ -164,9 +239,9 @@ public class MainActivity extends AndroidApplication implements OSFunctionalityP //////////////////////////////////////////////// /** - *

Implementation of the showShortToast method.

- * *

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

+ * + * @param msg The message to show. */ @Override public void showShortToast(final String msg){ @@ -179,9 +254,9 @@ public class MainActivity extends AndroidApplication implements OSFunctionalityP } /** - *

Implementation of the showLongToast method.

- * *

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

+ * + * @param msg The message to show. */ @Override public void showLongToast(final String msg){ @@ -194,8 +269,6 @@ public class MainActivity extends AndroidApplication implements OSFunctionalityP } /** - *

Implementation of the enableMulticast method.

- * *

Enable the transmision and reception of multicast network messages.

*/ @Override @@ -207,8 +280,6 @@ public class MainActivity extends AndroidApplication implements OSFunctionalityP } /** - *

Implementation of the disableMulticast method.

- * *

Disables the transmision and reception of multicast network messages.

*/ @Override @@ -413,6 +484,8 @@ public class MainActivity extends AndroidApplication implements OSFunctionalityP /** *

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

+ * + * @return True if and only if OpenCV initialized succesfully and calibrateCamera has been called previously. */ @Override public boolean cameraIsCalibrated() {