Home | History | Annotate | Download | only in interface
      1 /*
      2  * feature_match.cpp - optical flow feature match
      3  *
      4  *  Copyright (c) 2016-2017 Intel Corporation
      5  *
      6  * Licensed under the Apache License, Version 2.0 (the "License");
      7  * you may not use this file except in compliance with the License.
      8  * You may obtain a copy of the License at
      9  *
     10  *   http://www.apache.org/licenses/LICENSE-2.0
     11  *
     12  * Unless required by applicable law or agreed to in writing, software
     13  * distributed under the License is distributed on an "AS IS" BASIS,
     14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     15  * See the License for the specific language governing permissions and
     16  * limitations under the License.
     17  *
     18  * Author: Wind Yuan <feng.yuan (at) intel.com>
     19  * Author: Yinhang Liu <yinhangx.liu (at) intel.com>
     20  */
     21 
     22 #include "feature_match.h"
     23 
     24 #define XCAM_FM_DEBUG 0
     25 
     26 namespace XCam {
     27 
     28 FeatureMatch::FeatureMatch ()
     29     : _x_offset (0.0f)
     30     , _mean_offset (0.0f)
     31     , _valid_count (0)
     32     , _fm_idx (-1)
     33     , _frame_num (0)
     34 {
     35 }
     36 
     37 void
     38 FeatureMatch::set_config (CVFMConfig config)
     39 {
     40     _config = config;
     41 }
     42 
     43 CVFMConfig
     44 FeatureMatch::get_config ()
     45 {
     46     return _config;
     47 }
     48 
     49 void
     50 FeatureMatch::set_fm_index (int idx)
     51 {
     52     _fm_idx = idx;
     53 }
     54 
     55 void
     56 FeatureMatch::reset_offsets ()
     57 {
     58     _x_offset = 0.0f;
     59     _mean_offset = 0.0f;
     60 }
     61 
     62 bool
     63 FeatureMatch::get_mean_offset (std::vector<float> &offsets, float sum, int &count, float &mean_offset)
     64 {
     65     if (count < _config.min_corners)
     66         return false;
     67 
     68     mean_offset = sum / count;
     69 
     70 #if XCAM_FM_DEBUG
     71     XCAM_LOG_INFO (
     72         "FeatureMatch(idx:%d): X-axis mean offset:%.2f, pre_mean_offset:%.2f (%d times, count:%d)",
     73         _fm_idx, mean_offset, 0.0f, 0, count);
     74 #endif
     75 
     76     bool ret = true;
     77     float delta = 20.0f;//mean_offset;
     78     float pre_mean_offset = mean_offset;
     79     for (int try_times = 1; try_times < 4; ++try_times) {
     80         int recur_count = 0;
     81         sum = 0.0f;
     82 
     83         for (size_t i = 0; i < offsets.size (); ++i) {
     84             if (fabs (offsets[i] - mean_offset) >= _config.recur_offset_error)
     85                 continue;
     86             sum += offsets[i];
     87             ++recur_count;
     88         }
     89 
     90         if (recur_count < _config.min_corners) {
     91             ret = false;
     92             break;
     93         }
     94 
     95         mean_offset = sum / recur_count;
     96 #if XCAM_FM_DEBUG
     97         XCAM_LOG_INFO (
     98             "FeatureMatch(idx:%d): X-axis mean_offset:%.2f, pre_mean_offset:%.2f (%d times, count:%d)",
     99             _fm_idx, mean_offset, pre_mean_offset, try_times, recur_count);
    100 #endif
    101 
    102         if (mean_offset == pre_mean_offset && recur_count == count)
    103             return true;
    104 
    105         if (fabs (mean_offset - pre_mean_offset) > fabs (delta) * 1.2f) {
    106             ret = false;
    107             break;
    108         }
    109 
    110         delta = mean_offset - pre_mean_offset;
    111         pre_mean_offset = mean_offset;
    112         count = recur_count;
    113     }
    114 
    115     return ret;
    116 }
    117 
    118 void
    119 FeatureMatch::adjust_stitch_area (int dst_width, float &x_offset, Rect &stitch0, Rect &stitch1)
    120 {
    121     if (fabs (x_offset) < 5.0f)
    122         return;
    123 
    124     int last_overlap_width = stitch1.pos_x + stitch1.width + (dst_width - (stitch0.pos_x + stitch0.width));
    125     // int final_overlap_width = stitch1.pos_x + stitch1.width + (dst_width - (stitch0.pos_x - x_offset + stitch0.width));
    126     if ((stitch0.pos_x - x_offset + stitch0.width) > dst_width)
    127         x_offset = dst_width - (stitch0.pos_x + stitch0.width);
    128     int final_overlap_width = last_overlap_width + x_offset;
    129     final_overlap_width = XCAM_ALIGN_AROUND (final_overlap_width, 8);
    130     XCAM_ASSERT (final_overlap_width >= _config.sitch_min_width);
    131     int center = final_overlap_width / 2;
    132     XCAM_ASSERT (center >= _config.sitch_min_width / 2);
    133 
    134     stitch1.pos_x = XCAM_ALIGN_AROUND (center - _config.sitch_min_width / 2, 8);
    135     stitch1.width = _config.sitch_min_width;
    136     stitch0.pos_x = dst_width - final_overlap_width + stitch1.pos_x;
    137     stitch0.width = _config.sitch_min_width;
    138 
    139     float delta_offset = final_overlap_width - last_overlap_width;
    140     x_offset -= delta_offset;
    141 }
    142 
    143 }
    144