|
|
|
@ -5,6 +5,7 @@
|
|
|
|
|
#include <utility> // std::make_pair
|
|
|
|
|
#include <stdexcept> // std::runtime_error
|
|
|
|
|
#include <opencv2/opencv.hpp> // all opencv header
|
|
|
|
|
#include <omp.h>
|
|
|
|
|
#include "hdrplus/align.h"
|
|
|
|
|
#include "hdrplus/burst.h"
|
|
|
|
|
#include "hdrplus/utility.h"
|
|
|
|
@ -30,7 +31,7 @@ static void build_per_grayimg_pyramid( \
|
|
|
|
|
|
|
|
|
|
images_pyramid.resize( inv_scale_factors.size() );
|
|
|
|
|
|
|
|
|
|
for ( int i = 0; i < inv_scale_factors.size(); ++i )
|
|
|
|
|
for ( size_t i = 0; i < inv_scale_factors.size(); ++i )
|
|
|
|
|
{
|
|
|
|
|
cv::Mat blur_image;
|
|
|
|
|
cv::Mat downsample_image;
|
|
|
|
@ -43,7 +44,6 @@ static void build_per_grayimg_pyramid( \
|
|
|
|
|
downsample_image = src_image;
|
|
|
|
|
break;
|
|
|
|
|
case 2:
|
|
|
|
|
//printf("downsample with gaussian sigma %.2f", inv_scale_factors[ i ] * 0.5 );
|
|
|
|
|
// // Gaussian blur
|
|
|
|
|
cv::GaussianBlur( images_pyramid.at( i-1 ), blur_image, cv::Size(0, 0), inv_scale_factors[ i ] * 0.5 );
|
|
|
|
|
|
|
|
|
@ -56,9 +56,10 @@ static void build_per_grayimg_pyramid( \
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
case 4:
|
|
|
|
|
printf("downsample with gaussian sigma %.2f", inv_scale_factors[ i ] * 0.5 );
|
|
|
|
|
cv::GaussianBlur( images_pyramid.at( i-1 ), blur_image, cv::Size(0, 0), inv_scale_factors[ i ] * 0.5 );
|
|
|
|
|
|
|
|
|
|
downsample_image = downsample_nearest_neighbour<uint16_t, 4>( blur_image );
|
|
|
|
|
|
|
|
|
|
//downsample_image = downsample_nearest_neighbour<uint16_t, 4>( images_pyramid.at( i-1 ) );
|
|
|
|
|
images_pyramid.at( i ) = downsample_image.clone();
|
|
|
|
|
break;
|
|
|
|
@ -81,7 +82,7 @@ static void build_upsampled_prev_aligement( \
|
|
|
|
|
constexpr int repeat_factor = pyramid_scale_factor_prev_curr / tilesize_scale_factor_prev_curr;
|
|
|
|
|
|
|
|
|
|
// printf("build_upsampled_prev_aligement with scale factor %d, repeat factor %d, tile size factor %d\n", \
|
|
|
|
|
pyramid_scale_factor_prev_curr, repeat_factor, tilesize_scale_factor_prev_curr );
|
|
|
|
|
// pyramid_scale_factor_prev_curr, repeat_factor, tilesize_scale_factor_prev_curr );
|
|
|
|
|
|
|
|
|
|
int dst_height = src_height * repeat_factor;
|
|
|
|
|
int dst_width = src_width * repeat_factor;
|
|
|
|
@ -97,6 +98,7 @@ static void build_upsampled_prev_aligement( \
|
|
|
|
|
dst_alignment.resize( num_tiles_h, std::vector<std::pair<int, int>>( num_tiles_w, std::pair<int, int>(0, 0) ) );
|
|
|
|
|
|
|
|
|
|
// Upsample alignment
|
|
|
|
|
#pragma omp parallel for collapse(2)
|
|
|
|
|
for ( int row_i = 0; row_i < src_height; row_i++ )
|
|
|
|
|
{
|
|
|
|
|
for ( int col_i = 0; col_i < src_width; col_i++ )
|
|
|
|
@ -107,11 +109,15 @@ static void build_upsampled_prev_aligement( \
|
|
|
|
|
align_i.second *= pyramid_scale_factor_prev_curr;
|
|
|
|
|
|
|
|
|
|
// repeat
|
|
|
|
|
UNROLL_LOOP( repeat_factor )
|
|
|
|
|
for ( int repeat_row_i = 0; repeat_row_i < repeat_factor; ++repeat_row_i )
|
|
|
|
|
{
|
|
|
|
|
int repeat_row_i_offset = row_i * repeat_factor + repeat_row_i;
|
|
|
|
|
UNROLL_LOOP( repeat_factor )
|
|
|
|
|
for ( int repeat_col_i = 0; repeat_col_i < repeat_factor; ++repeat_col_i )
|
|
|
|
|
{
|
|
|
|
|
dst_alignment[ row_i * repeat_factor + repeat_row_i ][ col_i * repeat_factor + repeat_col_i ] = align_i;
|
|
|
|
|
int repeat_col_i_offset = col_i * repeat_factor + repeat_col_i;
|
|
|
|
|
dst_alignment[ repeat_row_i_offset ][ repeat_col_i_offset ] = align_i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -142,12 +148,14 @@ static unsigned long long l1_distance( const cv::Mat& img1, const cv::Mat& img2,
|
|
|
|
|
// Range check for safety
|
|
|
|
|
if ( img1_tile_row_start_idx < 0 || img1_tile_row_start_idx > img1_height - tile_size )
|
|
|
|
|
{
|
|
|
|
|
throw std::runtime_error("l1 distance img1_tile_row_start_idx out of valid range\n");
|
|
|
|
|
throw std::runtime_error("l1 distance img1_tile_row_start_idx" + std::to_string( img1_tile_row_start_idx ) + \
|
|
|
|
|
" out of valid range (0, " + std::to_string( img1_height - tile_size ) + ")\n" );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( img1_tile_col_start_idx < 0 || img1_tile_col_start_idx > img1_width - tile_size )
|
|
|
|
|
{
|
|
|
|
|
throw std::runtime_error("l1 distance img1_tile_col_start_idx out of valid range\n");
|
|
|
|
|
throw std::runtime_error("l1 distance img1_tile_col_start_idx" + std::to_string( img1_tile_col_start_idx ) + \
|
|
|
|
|
" out of valid range (0, " + std::to_string( img1_width - tile_size ) + ")\n" );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( img2_tile_row_start_idx < 0 || img2_tile_row_start_idx > img2_height - tile_size )
|
|
|
|
@ -161,12 +169,14 @@ static unsigned long long l1_distance( const cv::Mat& img1, const cv::Mat& img2,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return_type sum(0);
|
|
|
|
|
// TODO: add pragma unroll here
|
|
|
|
|
|
|
|
|
|
UNROLL_LOOP( tile_size )
|
|
|
|
|
for ( int row_i = 0; row_i < tile_size; ++row_i )
|
|
|
|
|
{
|
|
|
|
|
const data_type* img1_ptr_row_i = img1_ptr + (img1_tile_row_start_idx + row_i) * img1_step + img1_tile_col_start_idx;
|
|
|
|
|
const data_type* img2_ptr_row_i = img2_ptr + (img2_tile_row_start_idx + row_i) * img2_step + img2_tile_col_start_idx;
|
|
|
|
|
|
|
|
|
|
UNROLL_LOOP( tile_size )
|
|
|
|
|
for ( int col_i = 0; col_i < tile_size; ++col_i )
|
|
|
|
|
{
|
|
|
|
|
data_type l1 = CUSTOME_ABS( img1_ptr_row_i[ col_i ] - img2_ptr_row_i[ col_i ] );
|
|
|
|
@ -202,22 +212,24 @@ static return_type l2_distance( const cv::Mat& img1, const cv::Mat& img2, \
|
|
|
|
|
// Range check for safety
|
|
|
|
|
if ( img1_tile_row_start_idx < 0 || img1_tile_row_start_idx > img1_height - tile_size )
|
|
|
|
|
{
|
|
|
|
|
throw std::runtime_error("l1 distance img1_tile_row_start_idx out of valid range\n");
|
|
|
|
|
throw std::runtime_error("l2 distance img1_tile_row_start_idx" + std::to_string( img1_tile_row_start_idx ) + \
|
|
|
|
|
" out of valid range (0, " + std::to_string( img1_height - tile_size ) + ")\n" );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( img1_tile_col_start_idx < 0 || img1_tile_col_start_idx > img1_width - tile_size )
|
|
|
|
|
{
|
|
|
|
|
throw std::runtime_error("l1 distance img1_tile_col_start_idx out of valid range\n");
|
|
|
|
|
throw std::runtime_error("l2 distance img1_tile_col_start_idx" + std::to_string( img1_tile_col_start_idx ) + \
|
|
|
|
|
" out of valid range (0, " + std::to_string( img1_width - tile_size ) + ")\n" );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( img2_tile_row_start_idx < 0 || img2_tile_row_start_idx > img2_height - tile_size )
|
|
|
|
|
{
|
|
|
|
|
throw std::runtime_error("l1 distance img2_tile_row_start_idx out of valid range\n");
|
|
|
|
|
throw std::runtime_error("l2 distance img2_tile_row_start_idx out of valid range\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( img2_tile_col_start_idx < 0 || img2_tile_col_start_idx > img2_width - tile_size )
|
|
|
|
|
{
|
|
|
|
|
throw std::runtime_error("l1 distance img2_tile_col_start_idx out of valid range\n");
|
|
|
|
|
throw std::runtime_error("l2 distance img2_tile_col_start_idx out of valid range\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// printf("Search two tile with ref : \n");
|
|
|
|
@ -226,12 +238,14 @@ static return_type l2_distance( const cv::Mat& img1, const cv::Mat& img2, \
|
|
|
|
|
// print_tile<data_type>( img2, tile_size, img2_tile_row_start_idx, img2_tile_col_start_idx );
|
|
|
|
|
|
|
|
|
|
return_type sum(0);
|
|
|
|
|
// TODO: add pragma unroll here
|
|
|
|
|
|
|
|
|
|
UNROLL_LOOP( tile_size )
|
|
|
|
|
for ( int row_i = 0; row_i < tile_size; ++row_i )
|
|
|
|
|
{
|
|
|
|
|
const data_type* img1_ptr_row_i = img1_ptr + (img1_tile_row_start_idx + row_i) * img1_step + img1_tile_col_start_idx;
|
|
|
|
|
const data_type* img2_ptr_row_i = img2_ptr + (img2_tile_row_start_idx + row_i) * img2_step + img2_tile_col_start_idx;
|
|
|
|
|
|
|
|
|
|
UNROLL_LOOP( tile_size )
|
|
|
|
|
for ( int col_i = 0; col_i < tile_size; ++col_i )
|
|
|
|
|
{
|
|
|
|
|
data_type l1 = CUSTOME_ABS( img1_ptr_row_i[ col_i ] - img2_ptr_row_i[ col_i ] );
|
|
|
|
@ -245,6 +259,47 @@ static return_type l2_distance( const cv::Mat& img1, const cv::Mat& img2, \
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template<typename T, int tile_size>
|
|
|
|
|
static cv::Mat extract_img_tile( const cv::Mat& img, int img_tile_row_start_idx, int img_tile_col_start_idx )
|
|
|
|
|
{
|
|
|
|
|
const T* img_ptr = (const T*)img.data;
|
|
|
|
|
int img_width = img.size().width;
|
|
|
|
|
int img_height = img.size().height;
|
|
|
|
|
int img_step = img.step1();
|
|
|
|
|
|
|
|
|
|
if ( img_tile_row_start_idx < 0 || img_tile_row_start_idx > img_height - tile_size )
|
|
|
|
|
{
|
|
|
|
|
throw std::runtime_error("extract_img_tile img_tile_row_start_idx " + std::to_string( img_tile_row_start_idx ) + \
|
|
|
|
|
" out of valid range (0, " + std::to_string( img_height - tile_size ) + ")\n" );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( img_tile_col_start_idx < 0 || img_tile_col_start_idx > img_width - tile_size )
|
|
|
|
|
{
|
|
|
|
|
throw std::runtime_error("extract_img_tile img_tile_col_start_idx " + std::to_string( img_tile_col_start_idx ) + \
|
|
|
|
|
" out of valid range (0, " + std::to_string( img_width - tile_size ) + ")\n" );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cv::Mat img_tile( tile_size, tile_size, img.type() );
|
|
|
|
|
T* img_tile_ptr = (T*)img_tile.data;
|
|
|
|
|
int img_tile_step = img_tile.step1();
|
|
|
|
|
|
|
|
|
|
UNROLL_LOOP( tile_size )
|
|
|
|
|
for ( int row_i = 0; row_i < tile_size; ++row_i )
|
|
|
|
|
{
|
|
|
|
|
const T* img_ptr_row_i = img_ptr + img_step * ( img_tile_row_start_idx + row_i );
|
|
|
|
|
T* img_tile_ptr_row_i = img_tile_ptr + img_tile_step * row_i;
|
|
|
|
|
|
|
|
|
|
UNROLL_LOOP( tile_size )
|
|
|
|
|
for ( int col_i = 0; col_i < tile_size; ++col_i )
|
|
|
|
|
{
|
|
|
|
|
img_tile_ptr_row_i[ col_i ] = img_ptr_row_i[ img_tile_col_start_idx + col_i ];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return img_tile;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void align_image_level( \
|
|
|
|
|
const cv::Mat& ref_img, \
|
|
|
|
|
const cv::Mat& alt_img, \
|
|
|
|
@ -316,6 +371,42 @@ void align_image_level( \
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Function to extract reference image tile for memory cache
|
|
|
|
|
cv::Mat (*extract_ref_img_tile)(const cv::Mat&, int, int) = nullptr;
|
|
|
|
|
if ( curr_tile_size == 8 )
|
|
|
|
|
{
|
|
|
|
|
extract_ref_img_tile = &extract_img_tile<uint16_t, 8>;
|
|
|
|
|
}
|
|
|
|
|
else if ( curr_tile_size == 16 )
|
|
|
|
|
{
|
|
|
|
|
extract_ref_img_tile = &extract_img_tile<uint16_t, 16>;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Function to extract search image tile for memory cache
|
|
|
|
|
cv::Mat (*extract_alt_img_search)(const cv::Mat&, int, int) = nullptr;
|
|
|
|
|
if ( curr_tile_size == 8 )
|
|
|
|
|
{
|
|
|
|
|
if ( search_radiou == 1 )
|
|
|
|
|
{
|
|
|
|
|
extract_alt_img_search = &extract_img_tile<uint16_t, 8+1*2>;
|
|
|
|
|
}
|
|
|
|
|
else if ( search_radiou == 4 )
|
|
|
|
|
{
|
|
|
|
|
extract_alt_img_search = &extract_img_tile<uint16_t, 8+4*2>;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if ( curr_tile_size == 16 )
|
|
|
|
|
{
|
|
|
|
|
if ( search_radiou == 1 )
|
|
|
|
|
{
|
|
|
|
|
extract_alt_img_search = &extract_img_tile<uint16_t, 16+1*2>;
|
|
|
|
|
}
|
|
|
|
|
else if ( search_radiou == 4 )
|
|
|
|
|
{
|
|
|
|
|
extract_alt_img_search = &extract_img_tile<uint16_t, 16+4*2>;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
@ -372,15 +463,16 @@ void align_image_level( \
|
|
|
|
|
// 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 );
|
|
|
|
|
|
|
|
|
|
//printf("!! enlarged tile size %d\n", curr_tile_size + 2 * search_radiou );
|
|
|
|
|
// printf("!! enlarged tile size %d\n", 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 );
|
|
|
|
|
|
|
|
|
|
// TODO delete below distance vector, this is for debug only
|
|
|
|
|
// Dlete 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 ));
|
|
|
|
|
|
|
|
|
|
/* Iterate through all reference tile & compute distance */
|
|
|
|
|
#pragma omp parallel for collapse(2)
|
|
|
|
|
for ( int ref_tile_row_i = 0; ref_tile_row_i < num_tiles_h; ref_tile_row_i++ )
|
|
|
|
|
{
|
|
|
|
|
for ( int ref_tile_col_i = 0; ref_tile_col_i < num_tiles_w; ref_tile_col_i++ )
|
|
|
|
@ -389,8 +481,8 @@ void align_image_level( \
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
//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 );
|
|
|
|
|
// 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 );
|
|
|
|
|
// printf("\nRef img tile [%d, %d]\n", ref_tile_row_i, ref_tile_col_i );
|
|
|
|
|
// print_tile<uint16_t>( ref_img, curr_tile_size, ref_tile_row_start_idx_i, ref_tile_col_start_idx_i );
|
|
|
|
|
|
|
|
|
@ -410,21 +502,25 @@ void align_image_level( \
|
|
|
|
|
alt_tile_col_start_idx_i = 0;
|
|
|
|
|
if ( alt_tile_row_start_idx_i > alt_tile_row_idx_max )
|
|
|
|
|
{
|
|
|
|
|
int before = alt_tile_row_start_idx_i;
|
|
|
|
|
// int before = alt_tile_row_start_idx_i;
|
|
|
|
|
alt_tile_row_start_idx_i = alt_tile_row_idx_max;
|
|
|
|
|
// printf("@@ change start x from %d to %d\n", before, alt_tile_row_idx_max);
|
|
|
|
|
}
|
|
|
|
|
if ( alt_tile_col_start_idx_i > alt_tile_col_idx_max )
|
|
|
|
|
{
|
|
|
|
|
int before = alt_tile_col_start_idx_i;
|
|
|
|
|
// int before = alt_tile_col_start_idx_i;
|
|
|
|
|
alt_tile_col_start_idx_i = alt_tile_col_idx_max;
|
|
|
|
|
// printf("@@ change start y from %d to %d\n", before, alt_tile_col_idx_max );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Explicitly caching reference image tile
|
|
|
|
|
cv::Mat ref_img_tile_i = extract_ref_img_tile( ref_img, ref_tile_row_start_idx_i, ref_tile_col_start_idx_i );
|
|
|
|
|
cv::Mat alt_img_search_i = extract_alt_img_search( alt_img_pad, alt_tile_row_start_idx_i, alt_tile_col_start_idx_i );
|
|
|
|
|
|
|
|
|
|
// Because alternative image is padded with search radious.
|
|
|
|
|
// Using same coordinate with reference image will automatically considered search radious * 2
|
|
|
|
|
//printf("Alt image tile [%d, %d]-> start idx [%d, %d]\n", \
|
|
|
|
|
ref_tile_row_i, ref_tile_col_i, alt_tile_row_start_idx_i, alt_tile_col_start_idx_i );
|
|
|
|
|
// printf("Alt image tile [%d, %d]-> start idx [%d, %d]\n", \
|
|
|
|
|
// ref_tile_row_i, ref_tile_col_i, alt_tile_row_start_idx_i, alt_tile_col_start_idx_i );
|
|
|
|
|
// printf("\nAlt image tile [%d, %d]\n", ref_tile_row_i, ref_tile_col_i );
|
|
|
|
|
// print_tile<uint16_t>( alt_img_pad, curr_tile_size + 2 * search_radiou, alt_tile_row_start_idx_i, alt_tile_col_start_idx_i );
|
|
|
|
|
|
|
|
|
@ -436,16 +532,23 @@ void align_image_level( \
|
|
|
|
|
{
|
|
|
|
|
for ( int search_col_j = 0; search_col_j < ( search_radiou * 2 + 1 ); search_col_j++ )
|
|
|
|
|
{
|
|
|
|
|
//printf("\n--->tile at [%d, %d] search (%d, %d)\n", \
|
|
|
|
|
ref_tile_row_i, ref_tile_col_i, search_row_j - search_radiou, search_col_j - search_radiou );
|
|
|
|
|
// printf("\n--->tile at [%d, %d] search (%d, %d)\n", \
|
|
|
|
|
// ref_tile_row_i, ref_tile_col_i, search_row_j - search_radiou, search_col_j - search_radiou );
|
|
|
|
|
|
|
|
|
|
// 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, \
|
|
|
|
|
// alt_tile_row_start_idx_i + search_row_j, alt_tile_col_start_idx_i + search_col_j );
|
|
|
|
|
|
|
|
|
|
// unsigned long long distance_j = distance_func_ptr( ref_img_tile_i, alt_img_pad, \
|
|
|
|
|
// 0, 0, \
|
|
|
|
|
// alt_tile_row_start_idx_i + search_row_j, alt_tile_col_start_idx_i + search_col_j );
|
|
|
|
|
|
|
|
|
|
// TODO: currently distance is incorrect
|
|
|
|
|
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, \
|
|
|
|
|
alt_tile_row_start_idx_i + search_row_j, alt_tile_col_start_idx_i + search_col_j );
|
|
|
|
|
unsigned long long distance_j = distance_func_ptr( ref_img_tile_i, alt_img_search_i, \
|
|
|
|
|
0, 0, \
|
|
|
|
|
search_row_j, 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_radiou, search_col_j - search_radiou, distance_j, min_distance_i );
|
|
|
|
|
// 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_radiou, search_col_j - search_radiou, distance_j, min_distance_i );
|
|
|
|
|
|
|
|
|
|
// If this is smaller distance
|
|
|
|
|
if ( distance_j < min_distance_i )
|
|
|
|
@ -456,30 +559,30 @@ void align_image_level( \
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If same value, choose the one closer to the original tile location
|
|
|
|
|
// if ( distance_j == min_distance_i && min_distance_row_i != -1 && min_distance_col_i != -1 )
|
|
|
|
|
// {
|
|
|
|
|
// int prev_distance_row_2_ref = min_distance_row_i - search_radiou;
|
|
|
|
|
// int prev_distance_col_2_ref = min_distance_col_i - search_radiou;
|
|
|
|
|
// int curr_distance_row_2_ref = search_row_j - search_radiou;
|
|
|
|
|
// int curr_distance_col_2_ref = search_col_j - search_radiou;
|
|
|
|
|
if ( distance_j == min_distance_i && min_distance_row_i != -1 && min_distance_col_i != -1 )
|
|
|
|
|
{
|
|
|
|
|
int prev_distance_row_2_ref = min_distance_row_i - search_radiou;
|
|
|
|
|
int prev_distance_col_2_ref = min_distance_col_i - search_radiou;
|
|
|
|
|
int curr_distance_row_2_ref = search_row_j - search_radiou;
|
|
|
|
|
int curr_distance_col_2_ref = search_col_j - search_radiou;
|
|
|
|
|
|
|
|
|
|
// int prev_distance_2_ref_sqr = prev_distance_row_2_ref * prev_distance_row_2_ref + prev_distance_col_2_ref * prev_distance_col_2_ref;
|
|
|
|
|
// int curr_distance_2_ref_sqr = curr_distance_row_2_ref * curr_distance_row_2_ref + curr_distance_col_2_ref * curr_distance_col_2_ref;
|
|
|
|
|
int prev_distance_2_ref_sqr = prev_distance_row_2_ref * prev_distance_row_2_ref + prev_distance_col_2_ref * prev_distance_col_2_ref;
|
|
|
|
|
int curr_distance_2_ref_sqr = curr_distance_row_2_ref * curr_distance_row_2_ref + curr_distance_col_2_ref * curr_distance_col_2_ref;
|
|
|
|
|
|
|
|
|
|
// // previous min distance idx is farther away from ref tile start location
|
|
|
|
|
// if ( prev_distance_2_ref_sqr > curr_distance_2_ref_sqr )
|
|
|
|
|
// {
|
|
|
|
|
// // printf("@@@ Same distance %d, choose closer one (%d, %d) instead of (%d, %d)\n", \
|
|
|
|
|
// previous min distance idx is farther away from ref tile start location
|
|
|
|
|
if ( prev_distance_2_ref_sqr > curr_distance_2_ref_sqr )
|
|
|
|
|
{
|
|
|
|
|
// printf("@@@ Same distance %d, choose closer one (%d, %d) instead of (%d, %d)\n", \
|
|
|
|
|
// distance_j, search_row_j, search_col_j, min_distance_row_i, min_distance_col_i);
|
|
|
|
|
// min_distance_col_i = search_col_j;
|
|
|
|
|
// min_distance_row_i = search_row_j;
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
min_distance_col_i = search_col_j;
|
|
|
|
|
min_distance_row_i = search_row_j;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//printf("tile at (%d, %d) alignment (%d, %d)\n", \
|
|
|
|
|
ref_tile_row_i, ref_tile_col_i, min_distance_row_i, min_distance_col_i );
|
|
|
|
|
// printf("tile at (%d, %d) alignment (%d, %d)\n", \
|
|
|
|
|
// 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_col_i = prev_alignment_col_i + min_distance_col_i - search_radiou;
|
|
|
|
@ -516,38 +619,6 @@ void align_image_level( \
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void build_per_pyramid_reftiles_start( \
|
|
|
|
|
std::vector<std::vector<std::vector<std::pair<int, int>>>>& 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.at(0).size() );
|
|
|
|
|
|
|
|
|
|
// Every image pyramid level
|
|
|
|
|
for ( int level_i = 0; level_i < per_grayimg_pyramid.at(0).size(); level_i++ )
|
|
|
|
|
{
|
|
|
|
|
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 );
|
|
|
|
|
|
|
|
|
|
int num_tiles_h = level_i_img_h / (level_i_tile_size / 2) - 1;
|
|
|
|
|
int num_tiles_w = level_i_img_w / (level_i_tile_size / 2) - 1;
|
|
|
|
|
|
|
|
|
|
// Allocate memory
|
|
|
|
|
per_pyramid_reftiles_start.at( level_i ).resize( num_tiles_h, std::vector<std::pair<int, int>>( num_tiles_w ) );
|
|
|
|
|
|
|
|
|
|
for ( int tile_col_i = 0; tile_col_i < num_tiles_h; tile_col_i++ )
|
|
|
|
|
{
|
|
|
|
|
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_row_j * level_i_tile_size );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void align::process( const hdrplus::burst& burst_images, \
|
|
|
|
|
std::vector<std::vector<std::vector<std::pair<int, int>>>>& images_alignment )
|
|
|
|
@ -571,6 +642,8 @@ void align::process( const hdrplus::burst& burst_images, \
|
|
|
|
|
// exit(1);
|
|
|
|
|
|
|
|
|
|
per_grayimg_pyramid.resize( burst_images.num_images );
|
|
|
|
|
|
|
|
|
|
#pragma omp parallel for
|
|
|
|
|
for ( int img_idx = 0; img_idx < burst_images.num_images; ++img_idx )
|
|
|
|
|
{
|
|
|
|
|
// per_grayimg_pyramid[ img_idx ][ 0 ] is the original image
|
|
|
|
|