diff options
Diffstat (limited to 'jni/feature_mos/src/mosaic/AlignFeatures.cpp')
-rw-r--r-- | jni/feature_mos/src/mosaic/AlignFeatures.cpp | 119 |
1 files changed, 101 insertions, 18 deletions
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])<thresh_still && fabs(Hcurr[5])<thresh_still) // Still camera { return ALIGN_RET_ERROR; } + // compute the homography: + double Hinv33[3][3]; + double Hprev33[3][3]; + double Hcurr33[3][3]; + // Invert and multiple with previous transformation Matrix33::convert9to33(Hcurr33, Hcurr); Matrix33::convert9to33(Hprev33, Hprev); - //NormalizeProjMat(Hcurr33); normProjMat33d(Hcurr33); inv33d(Hcurr33, Hinv33); mult33d(Hcurr33, Hprev33, Hinv33); normProjMat33d(Hcurr33); - Matrix9::convert33to9(Hcurr, Hcurr33); + Matrix9::convert33to9(Hprev, Hcurr33); + // Since we have already factored the current transformation + // into Hprev, we can reset the Hcurr to identity + db_Identity3x3(Hcurr); + // Update the reference frame to be the current frame reg.UpdateReference(m_rows,quarter_res,false); + + // Update the reference frame index + reference_frame_index = num_frames_captured; } frame_number++; - // Copy curr to prev - memcpy(Happly, Hcurr, sizeof(double)*9); - memcpy(Hprev, Hcurr, sizeof(double)*9); - - return ALIGN_RET_OK; + return ret_code; } // Get current transformation @@ -138,11 +194,38 @@ int Align::getLastTRS(double trs[3][3]) { if (frame_number < 1) { - fprintf(stderr, "Error: Align::getLastTRS called before a frame was processed\n"); + trs[0][0] = 1.0; + trs[0][1] = 0.0; + trs[0][2] = 0.0; + trs[1][0] = 0.0; + trs[1][1] = 1.0; + trs[1][2] = 0.0; + trs[2][0] = 0.0; + trs[2][1] = 0.0; + trs[2][2] = 1.0; return ALIGN_RET_ERROR; } - Matrix33::convert9to33(trs, Happly); + // Note that the logic here handles the case, where a frame is not used for + // mosaicing but is captured and used in the preview-rendering. + // For these frames, we don't set Hcurr to identity in AddFrame() and the + // logic here appends their transformation to Hprev to render them with the + // correct transformation. For the frames we do use for mosaicing, we already + // append their Hcurr to Hprev in AddFrame() and then set Hcurr to identity. + + double Hinv33[3][3]; + double Hprev33[3][3]; + double Hcurr33[3][3]; + + Matrix33::convert9to33(Hcurr33, Hcurr); + normProjMat33d(Hcurr33); + inv33d(Hcurr33, Hinv33); + + Matrix33::convert9to33(Hprev33, Hprev); + + mult33d(trs, Hprev33, Hinv33); + normProjMat33d(trs); + return ALIGN_RET_OK; } |