/* * Copyright (C) 2011 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /////////////////////////////////////////////////// // AlignFeatures.cpp // S.O. # : // Author(s): zkira, mbansal, bsouthall, narodits // $Id: AlignFeatures.cpp,v 1.20 2011/06/17 13:35:47 mbansal Exp $ #include #include #include "trsMatrix.h" #include "MatrixUtils.h" #include "AlignFeatures.h" #include "Log.h" #define LOG_TAG "AlignFeatures" const double Align::DEFAULT_MAX_DISPARITY=0.1;//0.4; Align::Align() { width = height = 0; frame_number = 0; num_frames_captured = 0; reference_frame_index = 0; db_Identity3x3(Hcurr); db_Identity3x3(Hprev); } Align::~Align() { // Free gray-scale image if (imageGray != ImageUtils::IMAGE_TYPE_NOIMAGE) ImageUtils::freeImage(imageGray); } char* Align::getRegProfileString() { return reg.profile_string; } int Align::initialize(int width, int height, bool _quarter_res, float _thresh_still) { int nr_corners = DEFAULT_NR_CORNERS; double max_disparity = DEFAULT_MAX_DISPARITY; int motion_model_type = DEFAULT_MOTION_MODEL; int nrsamples = DB_DEFAULT_NR_SAMPLES; double scale = DB_POINT_STANDARDDEV; int chunk_size = DB_DEFAULT_CHUNK_SIZE; 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; const bool DEFAULT_USE_SMALLER_MATCHING_WINDOW = false; bool use_smaller_matching_window = DEFAULT_USE_SMALLER_MATCHING_WINDOW; quarter_res = _quarter_res; 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); } this->width = width; this->height = height; imageGray = ImageUtils::allocateImage(width, height, 1); if (reg.Initialized()) return ALIGN_RET_OK; else return ALIGN_RET_ERROR; } int Align::addFrameRGB(ImageType imageRGB) { ImageUtils::rgb2gray(imageGray, imageRGB, width, height); return addFrame(imageGray); } int Align::addFrame(ImageType imageGray_) { 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); 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])