From 784b14c9e9775fdf5cc826d275e039ec194ebd44 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 30 Apr 2014 13:05:36 -0430 Subject: [PATCH] Implemented the calibration interface. --- jni/cv_proc.cpp | 18 ++-- src/ve/ucv/ciens/ccg/nxtar/MainActivity.java | 92 +++++++++++++++++--- 2 files changed, 92 insertions(+), 18 deletions(-) diff --git a/jni/cv_proc.cpp b/jni/cv_proc.cpp index 26f1bb9..26d90ce 100644 --- a/jni/cv_proc.cpp +++ b/jni/cv_proc.cpp @@ -23,13 +23,14 @@ #ifdef CAN_LOG #define log(TAG, MSG) (__android_log_write(ANDROID_LOG_DEBUG, TAG, MSG)) -const char * TAG = "CVPROC_NATIVE"; #else #define log(TAG, MSG) (1 + 1) #endif extern "C"{ +const char * TAG = "CVPROC_NATIVE"; + 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; @@ -39,12 +40,13 @@ JNIEXPORT void JNICALL Java_ve_ucv_ciens_ccg_nxtar_MainActivity_getMarkerCodesAn cv::Mat& myuv = *(cv::Mat*)addrMatIn; cv::Mat& mbgr = *(cv::Mat*)addrMatOut; jint * _codes = env->GetIntArrayElements(codes, 0); + cv::Mat temp; log(TAG, "getMarkerCodesAndLocations(): Converting color space before processing."); - cv::cvtColor(myuv, mbgr, CV_RGB2BGR); + cv::cvtColor(myuv, temp, CV_RGB2BGR); log(TAG, "getMarkerCodesAndLocations(): Finding markers."); - nxtar::getAllMarkers(vCodes, mbgr); + nxtar::getAllMarkers(vCodes, temp); log(TAG, "getMarkerCodesAndLocations(): Copying marker codes."); for(int i = 0; i < vCodes.size() && i < 15; i++){ @@ -52,8 +54,9 @@ JNIEXPORT void JNICALL Java_ve_ucv_ciens_ccg_nxtar_MainActivity_getMarkerCodesAn } vCodes.clear(); - log(TAG, "getMarkerCodesAndLocations(): Releasing native data."); + cv::cvtColor(temp, mbgr, CV_BGR2RGB); + log(TAG, "getMarkerCodesAndLocations(): Releasing native data."); env->ReleaseIntArrayElements(codes, _codes, 0); } @@ -66,12 +69,13 @@ JNIEXPORT jboolean JNICALL Java_ve_ucv_ciens_ccg_nxtar_MainActivity_findCalibrat cv::Mat& myuv = *(cv::Mat*)addrMatIn; cv::Mat& mbgr = *(cv::Mat*)addrMatOut; jfloat * _points = env->GetFloatArrayElements(points, 0); + cv::Mat temp; log(TAG, "findCalibrationPattern(): Converting color space before processing."); - cv::cvtColor(myuv, mbgr, CV_RGB2BGR); + cv::cvtColor(myuv, temp, CV_RGB2BGR); log(TAG, "findCalibrationPattern(): Finding calibration pattern."); - found = nxtar::findCalibrationPattern(v_points, mbgr); + 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){ @@ -79,6 +83,8 @@ JNIEXPORT jboolean JNICALL Java_ve_ucv_ciens_ccg_nxtar_MainActivity_findCalibrat _points[p + 1] = (jfloat)v_points[i].y; } + cv::cvtColor(temp, mbgr, CV_BGR2RGB); + log(TAG, "findCalibrationPattern(): Releasing native data."); env->ReleaseFloatArrayElements(points, _points, 0); diff --git a/src/ve/ucv/ciens/ccg/nxtar/MainActivity.java b/src/ve/ucv/ciens/ccg/nxtar/MainActivity.java index c328b33..96c40ec 100644 --- a/src/ve/ucv/ciens/ccg/nxtar/MainActivity.java +++ b/src/ve/ucv/ciens/ccg/nxtar/MainActivity.java @@ -24,6 +24,7 @@ import org.opencv.imgproc.Imgproc; import ve.ucv.ciens.ccg.nxtar.interfaces.CVProcessor; import ve.ucv.ciens.ccg.nxtar.interfaces.OSFunctionalityProvider; +import ve.ucv.ciens.ccg.nxtar.utils.ProjectConstants; import android.content.Context; import android.content.pm.ActivityInfo; import android.graphics.Bitmap; @@ -45,6 +46,7 @@ public class MainActivity extends AndroidApplication implements OSFunctionalityP private static final String CLASS_NAME = MainActivity.class.getSimpleName(); private static boolean ocvOn = false; + private static Mat cameraMatrix, distortionCoeffs; private WifiManager wifiManager; private MulticastLock multicastLock; @@ -71,6 +73,9 @@ public class MainActivity extends AndroidApplication implements OSFunctionalityP public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); + cameraMatrix = new Mat(); + distortionCoeffs = new Mat(); + if(!Ouya.runningOnOuya){ setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); }else{ @@ -134,7 +139,7 @@ public class MainActivity extends AndroidApplication implements OSFunctionalityP // CVProcessor interface methods. // //////////////////////////////////// @Override - public CVData findMarkersInFrame(byte[] frame, int w, int h) { + public CVMarkerData findMarkersInFrame(byte[] frame){ if(ocvOn){ int codes[] = new int[15]; Bitmap tFrame, mFrame; @@ -147,14 +152,14 @@ public class MainActivity extends AndroidApplication implements OSFunctionalityP getMarkerCodesAndLocations(inImg.getNativeObjAddr(), outImg.getNativeObjAddr(), codes); - Mat temp = new Mat(); - Imgproc.cvtColor(outImg, temp, Imgproc.COLOR_BGR2RGB); + //Mat temp = new Mat(); + //Imgproc.cvtColor(outImg, temp, Imgproc.COLOR_BGR2RGB); - mFrame = Bitmap.createBitmap(temp.cols(), temp.rows(), Bitmap.Config.RGB_565); - Utils.matToBitmap(temp, mFrame); + mFrame = Bitmap.createBitmap(outImg.cols(), outImg.rows(), Bitmap.Config.RGB_565); + Utils.matToBitmap(outImg, mFrame); mFrame.compress(CompressFormat.JPEG, 100, outputStream); - CVData data = new CVData(); + CVMarkerData data = new CVMarkerData(); data.outFrame = outputStream.toByteArray(); data.markerCodes = codes; @@ -164,15 +169,78 @@ public class MainActivity extends AndroidApplication implements OSFunctionalityP return data; }else{ - Gdx.app.debug(TAG, CLASS_NAME + ".processFrame(): OpenCV is not ready or failed to load."); - + Gdx.app.debug(TAG, CLASS_NAME + ".findMarkersInFrame(): OpenCV is not ready or failed to load."); return null; } } @Override - public void calibrateCamera() { - // TODO Auto-generated method stub - + public CVCalibrationData findCalibrationPattern(byte[] frame){ + if(ocvOn){ + boolean found; + float points[] = new float[ProjectConstants.CALIBRATION_PATTERN_POINTS * 2]; + Bitmap tFrame, mFrame; + Mat inImg = new Mat(), outImg = new Mat(); + CVCalibrationData data = new CVCalibrationData(); + + // Decode the input frame and convert it to an OpenCV Matrix. + tFrame = BitmapFactory.decodeByteArray(frame, 0, frame.length); + Utils.bitmapToMat(tFrame, inImg); + + // Attempt to find the calibration pattern in the input frame. + found = findCalibrationPattern(inImg.getNativeObjAddr(), outImg.getNativeObjAddr(), points); + + // 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 output data structure. + data.outFrame = outputStream.toByteArray(); + data.calibrationPoints = found ? points : null; + + // Clean up memory. + tFrame.recycle(); + mFrame.recycle(); + outputStream.reset(); + + return data; + }else{ + Gdx.app.debug(TAG, CLASS_NAME + ".findCalibrationPattern(): OpenCV is not ready or failed to load."); + return null; + } } -} \ No newline at end of file + @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; + } + } +}