fix upsample alignemnt and num of tile bug

main
Xiao Song 3 years ago
parent b31ce44987
commit 6e15be8de4

@ -65,16 +65,21 @@ static void build_per_grayimg_pyramid( \
} }
template< int stride > template< int pyramid_scale_factor_prev_curr, int tilesize_scale_factor_prev_curr >
static void upsample_alignment_stride( \ static void build_upsampled_prev_aligement( \
std::vector<std::vector<std::pair<int, int>>>& src_alignment, \ std::vector<std::vector<std::pair<int, int>>>& src_alignment, \
std::vector<std::vector<std::pair<int, int>>>& dst_alignment ) std::vector<std::vector<std::pair<int, int>>>& dst_alignment )
{ {
printf("build_upsampled_prev_aligement with scale factor %d and tile size factor %d\n", \
pyramid_scale_factor_prev_curr, tilesize_scale_factor_prev_curr );
int src_height = src_alignment.size(); int src_height = src_alignment.size();
int src_width = src_alignment[ 0 ].size(); int src_width = src_alignment[ 0 ].size();
int dst_height = src_height * stride; int repeat_factor = pyramid_scale_factor_prev_curr / tilesize_scale_factor_prev_curr;
int dst_width = src_width * stride;
int dst_height = src_height * repeat_factor;
int dst_width = src_width * repeat_factor;
// Allocate data for dst_alignment // Allocate data for dst_alignment
dst_alignment.resize( dst_height, std::vector<std::pair<int, int>>( dst_width ) ); dst_alignment.resize( dst_height, std::vector<std::pair<int, int>>( dst_width ) );
@ -86,15 +91,15 @@ static void upsample_alignment_stride( \
{ {
// Scale alignment // Scale alignment
std::pair<int, int> align_i = src_alignment[ row_i ][ col_i ]; std::pair<int, int> align_i = src_alignment[ row_i ][ col_i ];
align_i.first *= stride; align_i.first *= pyramid_scale_factor_prev_curr;
align_i.second *= stride; align_i.second *= pyramid_scale_factor_prev_curr;
// repeat // repeat
for ( int stride_row_i = 0; stride_row_i < stride; ++stride_row_i ) for ( int repeat_row_i = 0; repeat_row_i < repeat_factor; ++repeat_row_i )
{ {
for ( int stride_col_i = 0; stride_col_i < stride; ++stride_col_i ) for ( int repeat_col_i = 0; repeat_col_i < repeat_factor; ++repeat_col_i )
{ {
dst_alignment[ row_i + stride_row_i ][ col_i + stride_col_i ] = align_i; dst_alignment[ row_i + repeat_row_i ][ col_i + repeat_col_i ] = align_i;
} }
} }
} }
@ -292,10 +297,6 @@ void align_image_level( \
int search_radiou, \ int search_radiou, \
int distance_type ) int distance_type )
{ {
/* Basic infos */
int num_tiles_h = ref_img.size().height / (curr_tile_size / 2) - 1;
int num_tiles_w = ref_img.size().width / (curr_tile_size / 2 ) - 1 ;
// Every align image level share the same distance function. // Every align image level share the same distance function.
// Use function ptr to reduce if else overhead inside for loop // Use function ptr to reduce if else overhead inside for loop
unsigned long long (*distance_func_ptr)(const cv::Mat&, const cv::Mat&, int, int, int, int) = nullptr; unsigned long long (*distance_func_ptr)(const cv::Mat&, const cv::Mat&, int, int, int, int) = nullptr;
@ -323,17 +324,41 @@ void align_image_level( \
} }
} }
#ifndef NDEBUG // Every level share the same upsample function
printf("%s::%s start: \n", __FILE__, __func__ ); void (*upsample_alignment_func_ptr)(std::vector<std::vector<std::pair<int, int>>>&, std::vector<std::vector<std::pair<int, int>>>&) = nullptr;
printf(" scale_factor_prev_curr %d, tile_size %d, prev_tile_size %d, search_radiou %d, distance L%d, \n", \ if ( scale_factor_prev_curr == 2 )
scale_factor_prev_curr, curr_tile_size, prev_tile_size, search_radiou, distance_type ); {
printf(" ref img size h=%d w=%d, alt img size h=%d w=%d, \n", \ if ( curr_tile_size / prev_tile_size == 2 )
ref_img.size().height, ref_img.size().width, alt_img.size().height, alt_img.size().width ); {
printf(" num tile h %d, num tile w %d\n", num_tiles_h, num_tiles_w); upsample_alignment_func_ptr = &build_upsampled_prev_aligement<2, 2>;
#endif }
else if ( curr_tile_size / prev_tile_size == 1 )
{
upsample_alignment_func_ptr = &build_upsampled_prev_aligement<2, 1>;
}
else
{
throw std::runtime_error("Something wrong with upsampling function setting\n");
}
}
else if ( scale_factor_prev_curr == 4 )
{
if ( curr_tile_size / prev_tile_size == 2 )
{
upsample_alignment_func_ptr = &build_upsampled_prev_aligement<4, 2>;
}
else if ( curr_tile_size / prev_tile_size == 1 )
{
upsample_alignment_func_ptr = &build_upsampled_prev_aligement<4, 1>;
}
else
{
throw std::runtime_error("Something wrong with upsampling function setting\n");
}
}
printf("Reference image h=%d, w=%d: \n", ref_img.size().height, ref_img.size().width ); int num_tiles_ref_h = ref_img.size().height / (curr_tile_size / 2) - 1;
print_img<uint16_t>( ref_img ); int num_tiles_ref_w = ref_img.size().width / (curr_tile_size / 2 ) - 1;
/* Upsample pervious layer alignment */ /* Upsample pervious layer alignment */
std::vector<std::vector<std::pair<int, int>>> upsampled_prev_aligement; std::vector<std::vector<std::pair<int, int>>> upsampled_prev_aligement;
@ -342,28 +367,30 @@ void align_image_level( \
// prev_alignment is invalid / empty, construct alignment as (0,0) // prev_alignment is invalid / empty, construct alignment as (0,0)
if ( prev_tile_size == -1 ) if ( prev_tile_size == -1 )
{ {
printf("create empty prev alignment\n"); upsampled_prev_aligement.resize( num_tiles_ref_h, \
upsampled_prev_aligement.resize( num_tiles_h, std::vector<std::pair<int, int>>( num_tiles_w, std::pair<int, int>(0, 0) ) ); std::vector<std::pair<int, int>>( num_tiles_ref_w, std::pair<int, int>(0, 0) ) );
} }
// Upsample previous level alignment // Upsample previous level alignment
else else
{ {
if ( scale_factor_prev_curr == 2 ) upsample_alignment_func_ptr( prev_aligement, upsampled_prev_aligement );
{
// TODO: add choose from 3 neighbour
upsample_alignment_stride<2>( prev_aligement, upsampled_prev_aligement );
}
else if ( scale_factor_prev_curr == 4 )
{
// TODO: add choose from 3 neighbour
upsample_alignment_stride<4>( prev_aligement, upsampled_prev_aligement );
}
else
{
throw std::runtime_error("Invalid scale factor" + std::to_string( scale_factor_prev_curr ) );
}
} }
/* Basic infos */
// NOTE: num_tile_h might be different from num_tile_ref_h
int num_tiles_h = upsampled_prev_aligement.size();
int num_tiles_w = upsampled_prev_aligement.at(0).size();
#ifndef NDEBUG
printf("%s::%s start: \n", __FILE__, __func__ );
printf(" scale_factor_prev_curr %d, tile_size %d, prev_tile_size %d, search_radiou %d, distance L%d, \n", \
scale_factor_prev_curr, curr_tile_size, prev_tile_size, search_radiou, distance_type );
printf(" ref img size h=%d w=%d, alt img size h=%d w=%d, \n", \
ref_img.size().height, ref_img.size().width, alt_img.size().height, alt_img.size().width );
printf(" num tile h (upsampled) %d, num tile w (upsampled) %d\n", num_tiles_h, num_tiles_w);
printf(" num tile h (gray) %d, num tile w (gray) %d\n", num_tiles_ref_h, num_tiles_ref_w);
#endif
// allocate memory for current alignmenr // allocate memory for current alignmenr
curr_alignment.resize( num_tiles_h, std::vector<std::pair<int, int>>( num_tiles_w, std::pair<int, int>(0, 0) ) ); curr_alignment.resize( num_tiles_h, std::vector<std::pair<int, int>>( num_tiles_w, std::pair<int, int>(0, 0) ) );
@ -374,6 +401,9 @@ void align_image_level( \
search_radiou, search_radiou, search_radiou, search_radiou, \ search_radiou, search_radiou, search_radiou, search_radiou, \
cv::BORDER_CONSTANT, cv::Scalar( UINT_LEAST16_MAX ) ); cv::BORDER_CONSTANT, cv::Scalar( UINT_LEAST16_MAX ) );
printf("Reference image h=%d, w=%d: \n", ref_img.size().height, ref_img.size().width );
print_img<uint16_t>( ref_img );
printf("Alter image pad h=%d, w=%d: \n", alt_img_pad.size().height, alt_img_pad.size().width ); printf("Alter image pad h=%d, w=%d: \n", alt_img_pad.size().height, alt_img_pad.size().width );
print_img<uint16_t>( alt_img_pad ); print_img<uint16_t>( alt_img_pad );
@ -382,6 +412,7 @@ void align_image_level( \
int alt_tile_row_idx_max = alt_img_pad.size().height - ( curr_tile_size + 2 * search_radiou ); int alt_tile_row_idx_max = alt_img_pad.size().height - ( curr_tile_size + 2 * search_radiou );
int alt_tile_col_idx_max = alt_img_pad.size().width - ( curr_tile_size + 2 * search_radiou ); int alt_tile_col_idx_max = alt_img_pad.size().width - ( curr_tile_size + 2 * search_radiou );
// TODO delete below distance vector, this is for debug only
std::vector<std::vector<uint16_t>> distances( num_tiles_h, std::vector<uint16_t>( num_tiles_w, 0 )); std::vector<std::vector<uint16_t>> distances( num_tiles_h, std::vector<uint16_t>( num_tiles_w, 0 ));
/* Iterate through all reference tile & compute distance */ /* Iterate through all reference tile & compute distance */
@ -605,6 +636,7 @@ void align::process( const hdrplus::burst& burst_images, \
std::vector<std::vector<std::pair<int, int>>> prev_alignment; std::vector<std::vector<std::pair<int, int>>> prev_alignment;
for ( int level_i = num_levels - 1; level_i >= 0; level_i-- ) for ( int level_i = num_levels - 1; level_i >= 0; level_i-- )
{ {
printf("\n\n########################align level %d\n", level_i );
align_image_level( align_image_level(
ref_grayimg_pyramid[ level_i ], // reference image at current level ref_grayimg_pyramid[ level_i ], // reference image at current level
alt_grayimg_pyramid[ level_i ], // alternative image at current level alt_grayimg_pyramid[ level_i ], // alternative image at current level
@ -620,6 +652,8 @@ void align::process( const hdrplus::burst& burst_images, \
prev_alignment.swap( curr_alignment ); prev_alignment.swap( curr_alignment );
curr_alignment.clear(); curr_alignment.clear();
// Stop at second iteration
if ( level_i == num_levels - 2 )
break; break;
} // for pyramid level } // for pyramid level

Loading…
Cancel
Save