@ -566,6 +566,7 @@ std::pair<double, double> merge::getNoiseParams( int ISO, \
// TODO: 4.2 Temporal Denoising
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
@ -577,7 +578,7 @@ std::pair<double, double> merge::getNoiseParams( int ISO, \
//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 ;
@ -606,36 +607,53 @@ std::pair<double, double> merge::getNoiseParams( int ISO, \
//get the dft of the alternate image
//std::vector<cv::Mat> alternate_tiles_DFT;
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
// find the squared absolute difference across all the tiles
//std::vector<cv::Mat> tile_differences = reference_tiles_DFT - alternate_tiles_DFT_list;
std : : vector < cv : : Mat > A = tile_sq_asolute_diff / ( tile_sq_asolute_diff + noise_variance )
//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 > merged_image_tiles_fft = alternate_tiles_DFT_list + A * tile_differences ;
//use merged_image_tiles_fft into part 4.3
// 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 ) ;
}
*/
// TODO: 4.3 Spatial Denoising
// find the squared absolute difference across all the tiles
// 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 ;
//adding after here
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 ;
return merged_image_tiles_fft
}
std : : vector < cv : : Mat > spatial_denoise ( std : : vector < cv : : Mat > reference_tiles , std : : vector < cv : : Mat > reference_tiles_DFT , std : : vector < float > noise_varaince ) {
double spatial_factor = 1 ; //to be added
double spatial_noise_scaling = ( pow ( TILE_SIZE , 2 ) * ( 1.0 / 16 * 2 ) ) * spatial_factor ;
@ -644,52 +662,8 @@ std::pair<double, double> merge::getNoiseParams( int ISO, \
std : : vector < cv : : Mat > WienerCoeff = denoised_tiles * spatial_noise_scaling * noise_variance ;
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