@ -1,6 +1,7 @@
# include <vector>
# include <string>
# include <limits>
# include <cstdio>
# include <stdexcept> // std::runtime_error
# include <opencv2/opencv.hpp> // all opencv header
# include "hdrplus/align.h"
@ -74,8 +75,8 @@ static void upsample_alignment_stride( \
{
// Scale alignment
std : : pair < int , int > align_i = src_alignment [ row_i ] [ col_i ] ;
align_i . first * = s cale_fac to r;
align_i . second * = s cale_fac to r;
align_i . first * = s tride ;
align_i . second * = s tride ;
// repeat
for ( int stride_row_i = 0 ; stride_row_i < stride ; + + stride_row_i )
@ -89,8 +90,27 @@ static void upsample_alignment_stride( \
}
}
template < typename T >
void print_tile ( const cv : : Mat & img , int tile_size , int start_idx_x , int start_idx_y )
{
const T * img_ptr = ( T * ) img . data ;
int src_height = img . size ( ) . height ;
int src_width = img . size ( ) . width ;
int src_step = img . step1 ( ) ;
for ( int row = 0 ; row < tile_size ; + + row )
{
const T * img_ptr_row = img_ptr + row * src_step ;
for ( int col = 0 ; col < tile_size ; + + col )
{
printf ( " %d " , img_ptr_row [ col ] ) ;
}
printf ( " \n " ) ;
}
printf ( " \n " ) ;
}
static void align_image_level ( \
void align_image_level ( \
const cv : : Mat & ref_img , \
const cv : : Mat & alt_img , \
const std : : vector < std : : vector < std : : pair < int , int > > > & reftiles_start , \
@ -113,6 +133,8 @@ static void align_image_level( \
int num_tiles_h = reftiles_start . size ( ) ;
int num_tiles_w = reftiles_start . at ( 0 ) . size ( ) ;
printf ( " num tile h %d, num tile w %d \n " , num_tiles_h , num_tiles_w ) ;
/* Upsample pervious layer alignment */
std : : vector < std : : vector < std : : pair < int , int > > > upsampled_prev_aligement ;
@ -132,6 +154,7 @@ static void align_image_level( \
}
else if ( scale_factor_prev_curr = = 4 )
{
// TODO: add choose from 3 neighbour
upsample_alignment_stride < 4 > ( prev_aligement , upsampled_prev_aligement ) ;
}
else
@ -145,19 +168,26 @@ static void align_image_level( \
cv : : copyMakeBorder ( alt_img , \
alt_img_pad , \
search_radiou , search_radiou , search_radiou , search_radiou , \
cv : : BORDER_CONSTANT , std: : numeric_limits < char16_t > : : max ) ;
cv : : BORDER_CONSTANT , cv: : Scalar ( UINT_LEAST16_MAX ) ) ;
/* Iterate through all reference tile & compute distance */
for ( int ref_tile_row = 0 ; ref_tile_row < num_tile _h; ref_tile_row + + )
for ( int ref_tile_row = 0 ; ref_tile_row < num_tile s _h; ref_tile_row + + )
{
for ( int ref_tile_col = 0 ; ref_tile_col < num_tile _w; ref_tile_col + + )
for ( int ref_tile_col = 0 ; ref_tile_col < num_tile s _w; ref_tile_col + + )
{
// Upper left index of reference tile
int ref_tile_idx_x = reftiles_start . at ( ref_tile_row ) . at ( ref_tile_col ) ;
int ref_tile_idx_y = reftiles_start . at ( ref_tile_row ) . at ( ref_tile_col ) ;
int ref_tile_idx_x = reftiles_start . at ( ref_tile_row ) . at ( ref_tile_col ) .first ;
int ref_tile_idx_y = reftiles_start . at ( ref_tile_row ) . at ( ref_tile_col ) .second ;
// Upsampled alignment at this tile
int
// int prev_alignment_x = upsampled_prev_aligement.at( ref_tile_row ).at( ref_tile_col ).first;
// int prev_alignment_y = upsampled_prev_aligement.at( ref_tile_row ).at( ref_tile_col ).second;
// int alt_tile_idx_x = ref_tile_idx_x + prev_alignment_x;
// int alt_tile_idx_y = ref_tile_idx_y + prev_alignment_y;
printf ( " Ref img tile [%d, %d] \n " , ref_tile_row , ref_tile_col ) ;
print_tile < uint16_t > ( ref_img , 8 , ref_tile_idx_x , ref_tile_idx_y ) ;
}
}
@ -169,13 +199,13 @@ static void build_per_pyramid_reftiles_start( \
const std : : vector < std : : vector < cv : : Mat > > & per_grayimg_pyramid , \
const std : : vector < int > & grayimg_tile_sizes )
{
per_pyramid_reftiles_start . resize ( per_grayimg_pyramid . size( ) ) ;
per_pyramid_reftiles_start . resize ( per_grayimg_pyramid . at( 0 ) . size( ) ) ;
// Every image pyramid level
for ( int level_i = 0 ; level_i < per_grayimg_pyramid . size( ) ; level_i + + )
for ( int level_i = 0 ; level_i < per_grayimg_pyramid . at( 0 ) . size( ) ; level_i + + )
{
int level_i_img_h = per_grayimg_pyramid . at ( level_i ) . size ( ) . height ;
int level_i_img_w = per_grayimg_pyramid . at ( level_i ) . size ( ) . width ;
int level_i_img_h = per_grayimg_pyramid . at ( 0 ) . at ( level_i ) . size ( ) . height ;
int level_i_img_w = per_grayimg_pyramid . at ( 0 ) . at ( level_i ) . size ( ) . width ;
int level_i_tile_size = grayimg_tile_sizes . at ( level_i ) ;
@ -190,7 +220,7 @@ static void build_per_pyramid_reftiles_start( \
for ( int tile_row_j = 0 ; tile_row_j < num_tiles_w ; tile_row_j + + )
{
per_pyramid_reftiles_start . at ( level_i ) . at ( tile_col_i ) . at ( tile_row_j ) \
= std : : make_pair < int , int > ( tile_col_i * level_i_tile_size , tile_ col _j * level_i_tile_size ) ;
= std : : make_pair < int , int > ( tile_col_i * level_i_tile_size , tile_ row _j * level_i_tile_size ) ;
}
}
}
@ -223,7 +253,6 @@ void align::process( const hdrplus::burst& burst_images, \
printf ( " \n " ) ;
# endif
// Tile starting location for each tile level
std : : vector < std : : vector < std : : vector < std : : pair < int , int > > > > per_pyramid_reftiles_start ;
@ -245,25 +274,27 @@ void align::process( const hdrplus::burst& burst_images, \
// Align every level from coarse to grain
// level 0 : finest level, the original image
// level 3 : coarsest level
std : : vector < std : : pair< int , int > > curr_alignment ;
std : : vector < std : : pair< int , int > > prev_alignment ;
std : : vector < std : : vector< std : : pair< int , int > > > curr_alignment ;
std : : vector < std : : vector< std : : pair< int , int > > > prev_alignment ;
for ( int level_i = num_levels - 1 ; level_i > = 0 ; level_i - - )
{
align_image_level (
ref_grayimg_pyramid [ level_i ] , // reference image at current level
alt_grayimg_pyramid [ level_i ] , // alternative image at current level
per_pyramid_reftiles_start [ level_i ] // reference tile start location for current level
per_pyramid_reftiles_start [ level_i ] , // reference tile start location for current level
prev_alignment , // previous layer alignment
curr_alignment , // current layer alignment
( level_i = = ( num_levels - 1 ) ? - 1 : inv_scale_factors [ level_i ] ) , // scale factor between previous layer and current layer. -1 if current layer is the coarsest layer
grayimg_tile_sizes [ level_i ] , // current level tile size
( level_i = = ( num_levels - 1 ) ? - 1 : tile_sizes[ level_i + 1 ] ) , // previous level tile size
( level_i = = ( num_levels - 1 ) ? - 1 : grayimg_ tile_sizes[ level_i + 1 ] ) , // previous level tile size
grayimg_search_radious [ level_i ] , // search radious
distances [ level_i ] ) ; // L1/L2 distance
// make curr alignment as previous alignment
prev_alignment . swap ( curr_alignment ) ;
curr_alignment . clear ( ) ;
break ;
} // for pyramid level