From dd28e1cc00373c02adf88dff878dbbe5d8be9e59 Mon Sep 17 00:00:00 2001 From: mbansal Date: Wed, 21 Sep 2011 14:19:17 -0400 Subject: Updates to handle textureless scenes during capture. 1) Starts stitching only when the camera sees a textured scene at the beginning. 2) If a texturess scene is encountered in the middle of a capture, the stitching continues with the intermediate frames translated using the pan velocity estimate. 3) Added more error codes and percolated them up to the java layer. 4) Fix a build error in Mosaic::addFrame() and added comments. 5) Update the javadoc in Mosaic.java to reflect the new returning codes. Change-Id: I7727ace615ece22adefe313a19ac2cbe8c8d21a8 --- jni/feature_mos/src/mosaic/AlignFeatures.cpp | 119 +++++++++++++++++++++++---- jni/feature_mos/src/mosaic/AlignFeatures.h | 16 +++- jni/feature_mos/src/mosaic/Mosaic.cpp | 42 ++++++---- jni/feature_mos/src/mosaic/Mosaic.h | 2 + 4 files changed, 139 insertions(+), 40 deletions(-) (limited to 'jni/feature_mos/src') diff --git a/jni/feature_mos/src/mosaic/AlignFeatures.cpp b/jni/feature_mos/src/mosaic/AlignFeatures.cpp index a181dd8..aeabf8f 100644 --- a/jni/feature_mos/src/mosaic/AlignFeatures.cpp +++ b/jni/feature_mos/src/mosaic/AlignFeatures.cpp @@ -26,12 +26,18 @@ #include "trsMatrix.h" #include "MatrixUtils.h" #include "AlignFeatures.h" +#include "Log.h" + +#define LOG_TAG "AlignFeatures" Align::Align() { width = height = 0; frame_number = 0; + num_frames_captured = 0; + reference_frame_index = 0; db_Identity3x3(Hcurr); + db_Identity3x3(Hprev); } Align::~Align() @@ -54,8 +60,8 @@ int Align::initialize(int width, int height, bool _quarter_res, float _thresh_st int nrsamples = DB_DEFAULT_NR_SAMPLES; double scale = DB_POINT_STANDARDDEV; int chunk_size = DB_DEFAULT_CHUNK_SIZE; - int nrhorz = 20; // 1280/32 = 40 - int nrvert = 12; // 720/30 = 24 + int nrhorz = width/48; // Empirically determined number of horizontal + int nrvert = height/60; // and vertical buckets for harris corner detection. bool linear_polish = false; unsigned int reference_update_period = DEFAULT_REFERENCE_UPDATE_PERIOD; @@ -66,10 +72,17 @@ int Align::initialize(int width, int height, bool _quarter_res, float _thresh_st thresh_still = _thresh_still; frame_number = 0; + num_frames_captured = 0; + reference_frame_index = 0; db_Identity3x3(Hcurr); + db_Identity3x3(Hprev); + if (!reg.Initialized()) { - reg.Init(width,height,motion_model_type,20,linear_polish,quarter_res,scale,reference_update_period, false, 0, nrsamples,chunk_size,nr_corners,max_disparity,use_smaller_matching_window, nrhorz, nrvert); + reg.Init(width, height, motion_model_type, 20, linear_polish, quarter_res, + scale, reference_update_period, false, 0, nrsamples, chunk_size, + nr_corners, max_disparity, use_smaller_matching_window, + nrhorz, nrvert); } this->width = width; this->height = height; @@ -90,47 +103,90 @@ int Align::addFrameRGB(ImageType imageRGB) int Align::addFrame(ImageType imageGray_) { - // compute the homography: - double Hinv[9]; - double Hinv33[3][3]; - double Hprev33[3][3]; - double Hcurr33[3][3]; + int ret_code = ALIGN_RET_OK; // Obtain a vector of pointers to rows in image and pass in to dbreg ImageType *m_rows = ImageUtils::imageTypeToRowPointers(imageGray_, width, height); - reg.AddFrame(m_rows, Hcurr); + if (frame_number == 0) + { + reg.AddFrame(m_rows, Hcurr, true); // Force this to be a reference frame + int num_corner_ref = reg.GetNrRefCorners(); + + if (num_corner_ref < MIN_NR_REF_CORNERS) + { + return ALIGN_RET_LOW_TEXTURE; + } + } + else + { + reg.AddFrame(m_rows, Hcurr, false); + } + + // Average translation per frame = + // [Translation from Frame0 to Frame(n-1)] / [(n-1)] + average_tx_per_frame = (num_frames_captured < 2) ? 0.0 : + Hprev[2] / (num_frames_captured - 1); + + // Increment the captured frame counter if we already have a reference frame + num_frames_captured++; if (frame_number != 0) { + int num_inliers = reg.GetNrInliers(); + + if(num_inliers < MIN_NR_INLIERS) + { + ret_code = ALIGN_RET_FEW_INLIERS; + + Hcurr[0] = 1.0; + Hcurr[1] = 0.0; + // Set this as the average per frame translation taking into acccount + // the separation of the current frame from the reference frame... + Hcurr[2] = -average_tx_per_frame * + (num_frames_captured - reference_frame_index); + Hcurr[3] = 0.0; + Hcurr[4] = 1.0; + Hcurr[5] = 0.0; + Hcurr[6] = 0.0; + Hcurr[7] = 0.0; + Hcurr[8] = 1.0; + } if(fabs(Hcurr[2])image = imageYVU; - int align_flag = Align::ALIGN_RET_OK; - // Add frame to aligner + int ret = MOSAIC_RET_ERROR; if (aligner != NULL) { // Note aligner takes in RGB images - printf("Adding frame to aligner...\n"); + int align_flag = Align::ALIGN_RET_OK; align_flag = aligner->addFrame(frame->image); aligner->getLastTRS(frame->trs); - printf("Frame width %d,%d\n", frame->width, frame->height); if (frames_size >= max_frames) { - fprintf(stderr, "WARNING: More frames than preallocated, ignoring. Increase maximum number of frames (-f ) to avoid this\n"); + LOGV("WARNING: More frames than preallocated, ignoring." + "Increase maximum number of frames (-f ) to avoid this"); return MOSAIC_RET_ERROR; } - else if(align_flag == Align::ALIGN_RET_OK) - { - frames_size++; - return MOSAIC_RET_OK; - } - else + + switch (align_flag) { - return MOSAIC_RET_ERROR; + case Align::ALIGN_RET_OK: + frames_size++; + ret = MOSAIC_RET_OK; + break; + case Align::ALIGN_RET_FEW_INLIERS: + frames_size++; + ret = MOSAIC_RET_FEW_INLIERS; + break; + case Align::ALIGN_RET_LOW_TEXTURE: + ret = MOSAIC_RET_LOW_TEXTURE; + break; + case Align::ALIGN_RET_ERROR: + ret = MOSAIC_RET_ERROR; + break; + default: + break; } } - else - { - return MOSAIC_RET_ERROR; - } + + return ret; } int Mosaic::createMosaic(float &progress, bool &cancelComputation) { - printf("Creating mosaic\n"); - if (frames_size <= 0) { // Haven't accepted any frame in aligner. No need to do blending. diff --git a/jni/feature_mos/src/mosaic/Mosaic.h b/jni/feature_mos/src/mosaic/Mosaic.h index 36eafe7..fc6ecd9 100644 --- a/jni/feature_mos/src/mosaic/Mosaic.h +++ b/jni/feature_mos/src/mosaic/Mosaic.h @@ -146,6 +146,8 @@ public: static const int MOSAIC_RET_OK = 1; static const int MOSAIC_RET_ERROR = -1; static const int MOSAIC_RET_CANCELLED = -2; + static const int MOSAIC_RET_LOW_TEXTURE = -3; + static const int MOSAIC_RET_FEW_INLIERS = 2; protected: -- cgit v1.1