fix search bug

main
Xiao Song 3 years ago
parent 13b86f42fa
commit 6fc12d8116

@ -43,7 +43,8 @@ cv::Mat box_filter_kxk( const cv::Mat& src_image )
{ {
for ( int col_i = 0; col_i < dst_width; col_i++ ) for ( int col_i = 0; col_i < dst_width; col_i++ )
{ {
T box_sum = T(0); // Take ceiling for rounding
T box_sum = T( kernel * kernel - 1 );
//#pragma LOOP_UNROLL //#pragma LOOP_UNROLL
for ( int kernel_row_i = 0; kernel_row_i < kernel; ++kernel_row_i ) for ( int kernel_row_i = 0; kernel_row_i < kernel; ++kernel_row_i )
{ {

@ -103,15 +103,15 @@ static void upsample_alignment_stride( \
// Set tilesize as template argument for better compiler optimization result. // Set tilesize as template argument for better compiler optimization result.
template< typename T, int tile_size > template< typename data_type, typename return_type, int tile_size >
static T l1_distance( const cv::Mat& img1, const cv::Mat& img2, \ static unsigned long long l1_distance( const cv::Mat& img1, const cv::Mat& img2, \
int img1_tile_row_start_idx, int img1_tile_col_start_idx, \ int img1_tile_row_start_idx, int img1_tile_col_start_idx, \
int img2_tile_row_start_idx, int img2_tile_col_start_idx ) int img2_tile_row_start_idx, int img2_tile_col_start_idx )
{ {
#define CUSTOME_ABS( x ) ( x ) > 0 ? ( x ) : - ( x ) #define CUSTOME_ABS( x ) ( x ) > 0 ? ( x ) : - ( x )
const T* img1_ptr = (const T*)img1.data; const data_type* img1_ptr = (const data_type*)img1.data;
const T* img2_ptr = (const T*)img2.data; const data_type* img2_ptr = (const data_type*)img2.data;
int img1_step = img1.step1(); int img1_step = img1.step1();
int img2_step = img2.step1(); int img2_step = img2.step1();
@ -143,7 +143,7 @@ static T l1_distance( const cv::Mat& img1, const cv::Mat& img2, \
throw std::runtime_error("l1 distance img2_tile_col_start_idx out of valid range\n"); throw std::runtime_error("l1 distance img2_tile_col_start_idx out of valid range\n");
} }
T sum(0); return_type sum(0);
// TODO: add pragma unroll here // TODO: add pragma unroll here
for ( int row_i = 0; row_i < tile_size; ++row_i ) for ( int row_i = 0; row_i < tile_size; ++row_i )
{ {
@ -152,7 +152,8 @@ static T l1_distance( const cv::Mat& img1, const cv::Mat& img2, \
for ( int col_i = 0; col_i < tile_size; ++col_i ) for ( int col_i = 0; col_i < tile_size; ++col_i )
{ {
sum += CUSTOME_ABS( img1_ptr_row_i[ col_i ] - img2_ptr_row_i[ col_i ] ); data_type l1 = CUSTOME_ABS( img1_ptr_row_i[ col_i ] - img2_ptr_row_i[ col_i ] );
sum += l1;
} }
} }
@ -162,15 +163,15 @@ static T l1_distance( const cv::Mat& img1, const cv::Mat& img2, \
} }
template< typename T, int tile_size > template< typename data_type, typename return_type, int tile_size >
static T l2_distance( const cv::Mat& img1, const cv::Mat& img2, \ static return_type l2_distance( const cv::Mat& img1, const cv::Mat& img2, \
int img1_tile_row_start_idx, int img1_tile_col_start_idx, \ int img1_tile_row_start_idx, int img1_tile_col_start_idx, \
int img2_tile_row_start_idx, int img2_tile_col_start_idx ) int img2_tile_row_start_idx, int img2_tile_col_start_idx )
{ {
#define CUSTOME_ABS( x ) ( x ) > 0 ? ( x ) : - ( x ) #define CUSTOME_ABS( x ) ( x ) > 0 ? ( x ) : - ( x )
const T* img1_ptr = (const T*)img1.data; const data_type* img1_ptr = (const data_type*)img1.data;
const T* img2_ptr = (const T*)img2.data; const data_type* img2_ptr = (const data_type*)img2.data;
int img1_step = img1.step1(); int img1_step = img1.step1();
int img2_step = img2.step1(); int img2_step = img2.step1();
@ -202,16 +203,16 @@ static T l2_distance( const cv::Mat& img1, const cv::Mat& img2, \
throw std::runtime_error("l1 distance img2_tile_col_start_idx out of valid range\n"); throw std::runtime_error("l1 distance img2_tile_col_start_idx out of valid range\n");
} }
T sum(0); return_type sum(0);
// TODO: add pragma unroll here // TODO: add pragma unroll here
for ( int row_i = 0; row_i < tile_size; ++row_i ) for ( int row_i = 0; row_i < tile_size; ++row_i )
{ {
const T* img1_ptr_row_i = img1_ptr + img1_tile_row_start_idx * img1_step + img1_tile_col_start_idx; const data_type* img1_ptr_row_i = img1_ptr + img1_tile_row_start_idx * img1_step + img1_tile_col_start_idx;
const T* img2_ptr_row_i = img2_ptr + img2_tile_row_start_idx * img2_step + img2_tile_col_start_idx; const data_type* img2_ptr_row_i = img2_ptr + img2_tile_row_start_idx * img2_step + img2_tile_col_start_idx;
for ( int col_i = 0; col_i < tile_size; ++col_i ) for ( int col_i = 0; col_i < tile_size; ++col_i )
{ {
T l1 = CUSTOME_ABS( img1_ptr_row_i[ col_i ] - img2_ptr_row_i[ col_i ] ); data_type l1 = CUSTOME_ABS( img1_ptr_row_i[ col_i ] - img2_ptr_row_i[ col_i ] );
sum += ( l1 * l1 ); sum += ( l1 * l1 );
} }
} }
@ -292,28 +293,28 @@ void align_image_level( \
// 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
uint16_t (*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;
if ( distance_type == 1 ) // l1 distance if ( distance_type == 1 ) // l1 distance
{ {
if ( curr_tile_size == 8 ) if ( curr_tile_size == 8 )
{ {
distance_func_ptr = &l1_distance<uint16_t, 8>; distance_func_ptr = &l1_distance<uint16_t, unsigned long long, 8>;
} }
else if ( curr_tile_size == 16 ) else if ( curr_tile_size == 16 )
{ {
distance_func_ptr = &l1_distance<uint16_t, 16>; distance_func_ptr = &l1_distance<uint16_t, unsigned long long, 16>;
} }
} }
else if ( distance_type == 2 ) // l2 distance else if ( distance_type == 2 ) // l2 distance
{ {
if ( curr_tile_size == 8 ) if ( curr_tile_size == 8 )
{ {
distance_func_ptr = &l2_distance<uint16_t, 8>; distance_func_ptr = &l2_distance<uint16_t, unsigned long long, 8>;
} }
else if ( curr_tile_size == 16 ) else if ( curr_tile_size == 16 )
{ {
distance_func_ptr = &l2_distance<uint16_t, 16>; distance_func_ptr = &l2_distance<uint16_t, unsigned long long, 16>;
} }
} }
@ -376,6 +377,8 @@ 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 );
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 */
for ( int ref_tile_row_i = 0; ref_tile_row_i < num_tiles_h; ref_tile_row_i++ ) for ( int ref_tile_row_i = 0; ref_tile_row_i < num_tiles_h; ref_tile_row_i++ )
{ {
@ -385,7 +388,7 @@ void align_image_level( \
int ref_tile_row_start_idx_i = ref_tile_row_i * curr_tile_size / 2; int ref_tile_row_start_idx_i = ref_tile_row_i * curr_tile_size / 2;
int ref_tile_col_start_idx_i = ref_tile_col_i * curr_tile_size / 2; int ref_tile_col_start_idx_i = ref_tile_col_i * curr_tile_size / 2;
printf("Ref img tile [%d, %d] -> start idx [%d, %d] (row, col)\n", \ printf("\nRef img tile [%d, %d] -> start idx [%d, %d] (row, col)\n", \
ref_tile_row_i, ref_tile_col_i, ref_tile_row_start_idx_i, ref_tile_col_start_idx_i ); ref_tile_row_i, ref_tile_col_i, ref_tile_row_start_idx_i, ref_tile_col_start_idx_i );
print_tile<uint16_t>( ref_img, 8, ref_tile_row_start_idx_i, ref_tile_col_start_idx_i ); print_tile<uint16_t>( ref_img, 8, ref_tile_row_start_idx_i, ref_tile_col_start_idx_i );
@ -423,16 +426,19 @@ void align_image_level( \
print_tile<uint16_t>( alt_img_pad, 16, alt_tile_row_start_idx_i, alt_tile_col_start_idx_i ); print_tile<uint16_t>( alt_img_pad, 16, alt_tile_row_start_idx_i, alt_tile_col_start_idx_i );
// Search based on L1/L2 distance // Search based on L1/L2 distance
uint16_t min_distance_i = UINT_LEAST16_MAX; unsigned long long min_distance_i = ULONG_LONG_MAX;
int min_distance_row_i = -1; int min_distance_row_i = -1;
int min_distance_col_i = -1; int min_distance_col_i = -1;
for ( int search_row_j = 0; search_row_j < search_radiou * 2; search_row_j++ ) for ( int search_row_j = 0; search_row_j < ( search_radiou * 2 + 1 ); search_row_j++ )
{ {
for ( int search_col_j = 0; search_col_j < search_radiou * 2; search_col_j++ ) for ( int search_col_j = 0; search_col_j < ( search_radiou * 2 + 1 ); search_col_j++ )
{ {
uint16_t distance_j = distance_func_ptr( ref_img, alt_img_pad, \ unsigned long long distance_j = distance_func_ptr( ref_img, alt_img_pad, \
ref_tile_row_start_idx_i, ref_tile_col_start_idx_i, \ ref_tile_row_start_idx_i, ref_tile_col_start_idx_i, \
alt_tile_row_start_idx_i, alt_tile_col_start_idx_i ); alt_tile_row_start_idx_i + search_row_j, alt_tile_col_start_idx_i + search_col_j );
printf("tile at (%d, %d) search (%d, %d), new dis %llu, old dis %llu\n", \
ref_tile_row_i, ref_tile_col_i, search_row_j, search_col_j, distance_j, min_distance_i );
// If this is smaller distance // If this is smaller distance
if ( distance_j < min_distance_i ) if ( distance_j < min_distance_i )
@ -444,8 +450,8 @@ void align_image_level( \
} }
} }
printf("tile local (%d, %d) -> start idx(%d, %d)\n", \ printf("tile at (%d, %d) alignment (%d, %d)\n", \
ref_tile_row_i, ref_tile_col_i, min_distance_col_i, min_distance_row_i ); ref_tile_row_i, ref_tile_col_i, min_distance_row_i, min_distance_col_i );
int alignment_row_i = prev_alignment_row_i + min_distance_row_i - search_radiou; int alignment_row_i = prev_alignment_row_i + min_distance_row_i - search_radiou;
int alignment_col_i = prev_alignment_col_i + min_distance_col_i - search_radiou; int alignment_col_i = prev_alignment_col_i + min_distance_col_i - search_radiou;
@ -454,6 +460,17 @@ void align_image_level( \
// Add min_distance_i's corresbonding idx as min // Add min_distance_i's corresbonding idx as min
curr_alignment.at( ref_tile_row_i ).at( ref_tile_col_i ) = alignment_i; curr_alignment.at( ref_tile_row_i ).at( ref_tile_col_i ) = alignment_i;
distances.at( ref_tile_row_i ).at( ref_tile_col_i ) = min_distance_i;
}
}
printf("Min distance for each tile \n");
for ( int tile_row = 0; tile_row < num_tiles_h; tile_row++ )
{
for ( int tile_col = 0; tile_col < num_tiles_w; ++tile_col )
{
printf("tile (%d, %d) distance %u\n", \
tile_row, tile_col, distances.at( tile_row).at(tile_col ) );
} }
} }
@ -468,6 +485,7 @@ void align_image_level( \
tile_row, tile_col, tile_start.first, tile_start.second); tile_row, tile_col, tile_start.first, tile_start.second);
} }
} }
} }

Loading…
Cancel
Save