@ -203,7 +203,76 @@ namespace hdrplus
}
// TODO: 4.2 Temporal Denoising
std : : vector < cv : : Mat > temporal_denoised_tiles = temporal_denoise ( reference_tiles , reference_tiles_DFT , noise_varaince )
// TODO: 4.3 Spatial Denoising
////adding after here
std : : vector < cv : : Mat > spatial_denoised_tiles = spatial_denoise ( reference_tiles , reference_tiles_DFT , noise_varaince )
//apply the cosineWindow2D over the merged_channel_tiles_spatial and reconstruct the image
//reference_tiles = spatial_denoised_tiles; //now reference tiles are temporally and spatially denoised
////
// Apply IFFT on reference tiles (frequency to spatial)
std : : vector < cv : : Mat > denoised_tiles ;
for ( auto dft_tile : reference_tiles_DFT ) {
cv : : Mat denoised_tile ;
cv : : dft ( dft_tile , denoised_tile , cv : : DFT_INVERSE | cv : : DFT_REAL_OUTPUT ) ;
denoised_tile . convertTo ( denoised_tile , CV_16U ) ;
denoised_tiles . push_back ( denoised_tile ) ;
}
reference_tiles = denoised_tiles ;
// 4.4 Cosine Window Merging
// Process tiles through 2D cosine window
std : : vector < cv : : Mat > windowed_tiles ;
for ( auto tile : reference_tiles ) {
windowed_tiles . push_back ( cosineWindow2D ( tile ) ) ;
}
// Merge tiles
return mergeTiles ( windowed_tiles , channel_image . rows , channel_image . cols ) ;
}
//Helper function to get the channels from the input image
std : : vector < ushort > getChannels ( cv : : Mat input_image ) {
std : : vector < ushort > channels [ 4 ] ;
for ( int y = 0 ; y < input_image . rows ; + + y ) {
for ( int x = 0 ; x < input_image . cols ; + + x ) {
if ( y % 2 = = 0 ) {
if ( x % 2 = = 0 ) {
channels [ 0 ] . push_back ( input_image . at < ushort > ( y , x ) ) ;
}
else {
channels [ 1 ] . push_back ( input_image . at < ushort > ( y , x ) ) ;
}
}
else {
if ( x % 2 = = 0 ) {
channels [ 2 ] . push_back ( input_image . at < ushort > ( y , x ) ) ;
}
else {
channels [ 3 ] . push_back ( input_image . at < ushort > ( y , x ) ) ;
}
}
}
}
return channels ;
}
//we should be getting the individual channel in the same place where we call the processChannel function with the reference channel in its arguments
std : : vector < cv : : Mat > temporal_denoise ( std : : vector < cv : : Mat > reference_tiles , std : : vector < cv : : Mat > reference_tiles_DFT , std : : vector < float > noise_varaince ) {
//goal: temporially denoise using the weiner filter
//input:
//1. array of 2D dft tiles of the reference image
@ -215,7 +284,7 @@ namespace hdrplus
//tile_size = TILE_SIZE;
/*
double temporal_factor = 8.0 //8 by default
double temporal_noise_scaling = ( pow ( TILE_SIZE , 2 ) * ( 1.0 / 16 * 2 ) ) * temporal_factor ;
@ -248,32 +317,49 @@ namespace hdrplus
std : : vector < cv : : Mat > tile_differences = reference_tiles_DFT - alternate_tiles_DFT_list ;
std : : vector < cv : : Mat > tile_sq_asolute_diff = tile_differences ; //squared absolute difference is tile_differences.real**2 + tile_differnce.imag**2; //also tile_dist
//std::vector<cv::Mat> tile_differences = reference_tiles_DFT - alternate_tiles_DFT_list;
//find reference_tiles_DFT - alternate_tiles_DFT_list
std : : vector < std : : vector < cv : : Mat > > tile_difference_list ; //list of tile differences
for ( auto individual_alternate_tile_DFT : alternate_tiles_DFT_list ) {
std : : vector < cv : : Mat > single_tile_difference = reference_tiles_DFT - individual_alternate_tile_DFT ;
tile_difference_list . push_back ( single_tile_difference ) ;
}
// std::vector<cv::Mat> tile_sq_asolute_diff = tile_differences; //squared absolute difference is tile_differences.real**2 + tile_differnce.imag**2; //also tile_dist
std : : vector < cv : : Mat > tile_sq_asolute_diff = tile_differences ; //squared absolute difference is tile_differences.real**2 + tile_differnce.imag**2; //also tile_dist
//get the real and imaginary components
/*
std : : vector < std : : vector < cv : : Mat > > absolute_difference_list ;
for ( auto individual_difference : tile_difference_list ) {
for ( int i = 0 ; i < individual_difference . rows ; i + + ) {
std : : complex < double > * row_ptr = tile_sq_asolute_diff . ptr < std : : complex < double > > ( i ) ;
for ( int j = 0 ; j < individual_difference . cols * individual_difference . channels ( ) ; j + + ) {
row_ptr = math . pow ( individual_difference . at < std : : complex < double > > ( i , j ) . real ( ) , 2 ) + math . pow ( individual_difference . at < std : : complex < double > > ( i , j ) . imag ( ) , 2 ) ; //.real and .imag
}
}
//std::vector<cv::Mat> single_tile_difference = individual_difference.at<std::complex<double>>(0,0).real(); //.real and .imag
absolute_difference_list . push_back ( single_tile_difference ) ;
}
*/
//find the squared absolute difference across all the tiles
std : : vector < cv : : Mat > A = tile_sq_asolute_diff / ( tile_sq_asolute_diff + noise_variance )
std : : vector < cv : : Mat > merged_image_tiles_fft = alternate_tiles_DFT_list + A * tile_differences ;
//use merged_image_tiles_fft into part 4.3
return merged_image_tiles_fft
}
// TODO: 4.3 Spatial Denoising
// Apply IFFT on reference tiles (frequency to spatial)
std : : vector < cv : : Mat > denoised_tiles ;
for ( auto dft_tile : reference_tiles_DFT ) {
cv : : Mat denoised_tile ;
cv : : dft ( dft_tile , denoised_tile , cv : : DFT_INVERSE | cv : : DFT_REAL_OUTPUT ) ;
denoised_tile . convertTo ( denoised_tile , CV_16U ) ;
denoised_tiles . push_back ( denoised_tile ) ;
}
reference_tiles = denoised_tiles ;
std : : vector < cv : : Mat > spatial_denoise ( std : : vector < cv : : Mat > reference_tiles , std : : vector < cv : : Mat > reference_tiles_DFT , std : : vector < float > noise_varaince ) {
//adding after here
double spatial_factor = 1 ; //to be added
double spatial_noise_scaling = ( pow ( TILE_SIZE , 2 ) * ( 1.0 / 16 * 2 ) ) * spatial_factor ;
@ -283,51 +369,7 @@ namespace hdrplus
merged_channel_tiles_spatial = reference_tiles * spatial_tile_dist / ( spatial_tile_dist + WienerCoeff )
//apply the cosineWindow2D over the merged_channel_tiles_spatial and reconstruct the image
*/
// 4.4 Cosine Window Merging
// Process tiles through 2D cosine window
std : : vector < cv : : Mat > windowed_tiles ;
for ( auto tile : reference_tiles ) {
windowed_tiles . push_back ( cosineWindow2D ( tile ) ) ;
}
// Merge tiles
return mergeTiles ( windowed_tiles , channel_image . rows , channel_image . cols ) ;
}
//Helper function to get the channels from the input image
std : : vector < ushort > getChannels ( cv : : Mat input_image ) {
std : : vector < ushort > channels [ 4 ] ;
for ( int y = 0 ; y < input_image . rows ; + + y ) {
for ( int x = 0 ; x < input_image . cols ; + + x ) {
if ( y % 2 = = 0 ) {
if ( x % 2 = = 0 ) {
channels [ 0 ] . push_back ( input_image . at < ushort > ( y , x ) ) ;
}
else {
channels [ 1 ] . push_back ( input_image . at < ushort > ( y , x ) ) ;
}
}
else {
if ( x % 2 = = 0 ) {
channels [ 2 ] . push_back ( input_image . at < ushort > ( y , x ) ) ;
}
else {
channels [ 3 ] . push_back ( input_image . at < ushort > ( y , x ) ) ;
}
}
}
}
return channels ;
}
//we should be getting the individual channel in the same place where we call the processChannel function with the reference channel in its arguments
} // namespace hdrplus