A bit more complex filter: the overall height standard deviation is taken into account
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
real(kind=R8), | intent(inout), | dimension(1:long, 1:larg) | :: | tab |
2D array |
|
integer(kind=I4), | intent(in) | :: | long |
2D array length |
||
integer(kind=I4), | intent(in) | :: | larg |
2D array width |
||
integer(kind=I4), | intent(in) | :: | snb |
patch number along a direction |
||
integer(kind=I4), | intent(in) | :: | kernel |
kernel size |
||
real(kind=R8), | intent(in) | :: | sig |
error std |
||
logical(kind=I4), | intent(in) | :: | omp |
if multithreading |
subroutine median_filter(tab, long, larg, snb, kernel, sig, omp) !================================================================================================ !! A bit more complex filter: the overall height standard deviation is taken into account !------------------------------------------------------------------------------------------------ implicit none integer(kind=I4), intent(in ) :: long !! *2D array length* integer(kind=I4), intent(in ) :: larg !! *2D array width* integer(kind=I4), intent(in ) :: snb !! *patch number along a direction* integer(kind=I4), intent(in ) :: kernel !! *kernel size* logical(kind=I4), intent(in ) :: omp !! *if multithreading* real (kind=R8), intent(in ) :: sig !! *error std* real (kind=R8), intent(inout), dimension(1:long, 1:larg) :: tab !! *2D array* integer(kind=I4) :: i, j, k real(kind=R8) :: md integer(kind=I4), dimension(1:snb + 1) :: li, lj real(kind=R8), dimension(1:snb * snb) :: ect real(kind=R8), allocatable, dimension(:,:) :: tab_tmp1, tab_tmp2 type( moment_stat ) :: mx_smooth allocate( tab_tmp1(1:long, 1:larg) ) allocate( tab_tmp2(1:long, 1:larg) ) ! first determine the difference between the input surface and a median filtered one tab_tmp1(1:long, 1:larg) = tab(1:long, 1:larg) call median_smooth( tab = tab_tmp1(1:long, 1:larg), & ! kernel = kernel, & ! long = long, & ! larg = larg, & ! omp = omp ) ! tab_tmp2(1:long, 1:larg) = tab(1:long, 1:larg) - tab_tmp1(1:long, 1:larg) ! bounds when patching domain li(1) = 1 ; li(snb + 1) = long lj(1) = 1 ; lj(snb + 1) = larg do i = 2, snb li(i) = li(i - 1) + int( real(long, kind=R8)/snb, kind=I4 ) lj(i) = lj(i - 1) + int( real(larg, kind=R8)/snb, kind=I4 ) enddo k = 0 do j = 1, snb do i = 1, snb call calc_moments( tab = reshape( tab_tmp2( li(i):li(i + 1) - 1, lj(j):lj(j + 1) - 1 ), & ! [( li(i) - li(i + 1) ) * ( lj(j) - lj(j + 1) )] ), & ! mx = mx_smooth, & ! nb_mom = 2 ) ! k = k +1 ect(k) = mx_smooth%si enddo enddo call calc_median( tab = ect( 1:snb*snb ), & ! md = md ) ! call calc_moments( tab = reshape( tab_tmp2(1:long, 1:larg), & ! [long * larg] ), & ! mx = mx_smooth, & ! nb_mom = 2 ) ! where( abs(tab_tmp2(1:long, 1:larg) -mx_smooth%mu) > sig*md ) tab(1:long, 1:larg) = tab_tmp1(1:long, 1:larg) deallocate( tab_tmp1, tab_tmp2 ) return endsubroutine median_filter