Beispiel #1
0
def _focusing(X, phi, Na, Nr, ftshift=False, isfft=True):
    d = X.dim()
    sizea, sizer = [1] * d, [1] * d
    returns = []
    if Na is not None:
        pa = phi[0]
        sizea[0], sizea[-3], sizea[-1] = pa.size(0), pa.size(1), 2
        epa = th.stack((th.cos(pa), -th.sin(pa)), dim=-1)
        epa = epa.reshape(sizea)

        if isfft:
            X = ts.fft(X, axis=-3, shift=ftshift)
        X = ts.ebemulcc(X, epa)
        X = ts.ifft(X, axis=-3, shift=ftshift)
        returns.append(pa.data)

    if Nr is not None:
        if Na is None:
            pr = phi[0]
        else:
            pr = phi[1]
        sizer[0], sizer[-2], sizer[-1] = pr.size(0), pr.size(1), 2
        epr = th.stack((th.cos(pr), -th.sin(pr)), dim=-1)
        epr = epr.reshape(sizer)

        if isfft:
            X = ts.fft(X, axis=-2, shift=ftshift)
        X = ts.ebemulcc(X, epr)
        X = ts.ifft(X, axis=-2, shift=ftshift)
        returns.append(pr.data)
    return [X] + returns
Beispiel #2
0
def phase_correction(x, phi, nsub=None, axis=-2, ftshift=True):

    if th.is_complex(x):
        # N, Na, Nr = x.size(0), x.size(-2), x.size(-1)
        cplxflag = True
    elif x.size(-1) == 2:
        # N, Na, Nr = x.size(0), x.size(-3), x.size(-2)
        x = th.view_as_complex(x)
        cplxflag = False
    else:
        raise TypeError(
            'x is complex and should be in complex or real represent formation!'
        )
    if axis == -2 or axis == 1:  # azimuth
        axis = -2
    if axis == -1 or axis == 2:  # range
        axis = -1

    if x.dim() == 2:
        x = x.unsqueeze(0)
    if phi.dim() == 1:
        phi = phi.unsqueeze(0)
    if phi.size(-1) != 1:
        phi = phi.unsqueeze(-1)
        phi = phi.unsqueeze(-1)

    N, Na, Nr = x.size()
    Nx = x.size(axis)
    pshape = [1, 1, 1]
    pshape[0] = N
    pshape[axis] = Nx
    phi = phi.reshape(pshape)

    if nsub is None:
        nsub = Nx

    # X = ts.fft(SI, axis=axis, shift=ftshift)
    # X = X * np.exp(-1j * phi)
    # SI = ts.ifft(X, axis=axis, shift=ftshift)
    xc = x.clone().detach()
    d = xc.dim()
    for n in range(0, Nx, nsub):
        idx = ts.sl(d, axis, range(n, n + nsub))
        xsub = x[idx]
        phisub = phi[idx]
        Xsub = ts.fft(xsub, axis=axis, shift=ftshift)
        xc[idx] = ts.ifft(Xsub * th.exp(-1j * phisub),
                          axis=axis,
                          shift=ftshift)
    if not cplxflag:
        xc = th.view_as_real(xc)
    return xc
Beispiel #3
0
    def focus(self, X, pa=None, pr=None):
        # X --> N-1-Na-Nr-2
        # pa --> N-Na
        # pr --> N-Nr

        if pa is None and pr is None:
            return X

        if pa is not None:
            X = ts.fft(X, nfft=None, axis=2, norm=False)
            pa = pa.reshape(pa.size(0), 1, int(pa.numel() / pa.size(0)), 1)
            epa = th.stack((th.cos(pa), th.sin(pa)), dim=-1)
            X = ts.ebemulcc(X, epa)
        if pr is not None:
            X = ts.fft(X, nfft=None, axis=3, norm=False)
            pr = pr.reshape(pr.size(0), 1, 1, int(pr.numel() / pr.size(0)))
            epr = th.stack((th.cos(pr), th.sin(pr)), dim=-1)
            X = ts.ebemulcc(X, epr)
        if pa is not None:
            X = ts.ifft(X, nfft=None, axis=2, norm=False)
        if pr is not None:
            X = ts.ifft(X, nfft=None, axis=3, norm=False)

        return X
def af_ffo(g, w=None, p=2, niter=10, eta=0.5, tol=1e-2, ftshift=False):

    if p < 1:
        raise ValueError('p should be larger than 1!')

    G = ts.fft(g, axis=-3, shift=ftshift)
    Na, Nr = G.size(-3), G.size(-2)
    d = G.dim()
    wshape = [1] * d
    wshape[-3] = Na

    if w is None:
        w = th.ones(wshape, device=G.device, dtype=G.dtype)

    if eta is None:
        eta = ts.PI / 2.

    phi0, i = 1e3, 0
    phi = th.zeros(wshape, device=G.device, dtype=G.dtype)
    diff = th.ones(wshape, device=G.device, dtype=G.dtype)
    # print(i, niter, (phi - phi0).sum(), tol)
    # print(w.shape)
    while (i < niter and (phi - phi0).abs().sum() > tol):
        phi0 = phi
        while (diff.abs().sum() > tol):
            Gabs = th.sqrt(G[..., 0]**2 + G[..., 1]**2).unsqueeze(-1)
            # print(Gabs.shape, w.shape)
            gamman = th.sum(w * Gabs, axis=-3, keepdim=True)
            print(gamman.min(), gamman.max(), "===")
            # print(gamman.shape, w.shape, Gabs.shape)
            Dphi = (w * p * th.sum((gamman ** (p - 1)) *  Gabs, axis=-2, keepdim=True) / 2.) / \
              (-w * w * p * (p - 1) * th.sum((gamman ** (p - 2)) * (Gabs ** 2), axis=-2, keepdim=True) / 4.)

            # print(Dphi.shape)
            diff = eta * Dphi
            phi = phi - diff
            epa = th.cat((th.cos(phi), th.sin(phi)), axis=-1)
            G = ts.ebemulcc(G, epa)
            print(Dphi.min(), Dphi.max())
            print(diff.min(), diff.max())
            print(phi.min(), phi.max())
        i += 1
        eta /= 2.
        print(i, eta)

    g = ts.ifft(G, axis=-3, shift=ftshift)
    return g
def af_ffo_sm(x,
              p=2,
              niter=10,
              delta=None,
              toli=1e-2,
              tolo=1e-2,
              ftshift=True,
              islog=False):
    """Stage-by-Stage minimum entropy

    [1] Morrison Jr, Robert Lee; Autofocus, Entropy-based (2002): Entropy-based autofocus for synthetic aperture radar.

    Parameters
    ----------
    x : Tensor
       Corrupt complex SAR image. N-Na-Nr(complex) or N-Na-Nr-2(real)
    niter : int, optional
       The number of iteration (the default is 10)
    delta : {float or None}, optional
       The change step (the default is None (i.e. PI))
    toli : int, optional
       Tolerance error for inner loop (the default is 1e-2)
    tolo : int, optional
       Tolerance error for outer loop (the default is 1e-2)
    ftshift : bool, optional
       Shift the zero frequency to center? (the default is True)
    islog : bool, optional
       Print log information? (the default is False)
    """

    if delta is None:
        delta = ts.PI

    if th.is_complex(x):
        x = th.view_as_real(x)
        cplxflag = True
    elif x.size(-1) == 2:
        cplxflag = False
    else:
        raise TypeError(
            'x is complex and should be in complex or real represent formation!'
        )

    d = x.dim()
    N, Na, Nr = x.size(0), x.size(-3), x.size(-2)

    wshape = [1] * d
    wshape[-3] = Na

    X = ts.fft(x, axis=-3, shift=ftshift)
    phio = th.zeros(wshape, device=x.device, dtype=x.dtype)
    ephi = th.cat((th.cos(phio), th.sin(phio)), dim=-1)
    # print(wshape, phio.min(), phio.max(), ephi.min(), ephi.max())
    So = __fdnorm(ts.ebemulcc(X, ephi), p)
    ii, io, Soi0, Soo0 = 0, 0, 1e13, 1e13
    print(ii, So, Soi0, Soo0)
    while (ii < niter):
        Soo0 = So
        while True:
            Soi0 = So
            print(ii, "===", d)
            for a in range(Na):
                phi1, phi2 = phio.clone().detach(), phio.clone().detach()
                for n in range(N):
                    print(n, N, Na, a, delta)
                    phi1[n, a] += delta
                    phi2[n, a] -= delta
                ephi1 = th.cat((th.cos(phi1), -th.sin(phi1)), dim=-1)
                S1 = __fdnorm(ts.ebemulcc(X, ephi1), p)
                ephi2 = th.cat((th.cos(phi2), -th.sin(phi2)), dim=-1)
                S2 = __fdnorm(ts.ebemulcc(X, ephi2), p)
                print(phi1.shape, phi2.shape, ephi1.shape, ephi2.shape, "]]]")
                print(N, S1, S2, So, S1 - S2, th.sum(ephi1 - ephi2),
                      th.sum(phi1 - phi2))
                if S1 > So:
                    So = S1
                    phio = phi1.clone().detach()
                    print("111")
                elif S2 > So:
                    print("222")
                    So = S2
                    phio = phi2.clone().detach()
                print(Soi0, So, S1, S2, abs(So - Soi0), io, "+++")
            if abs(So - Soi0) < toli and io > niter:
                break
            io += 1
        print(ii, delta, abs(So - Soo0), tolo,
              abs(So - Soo0) < tolo, So, Soo0, "So")
        print(ii, delta, abs(So - Soi0), tolo,
              abs(So - Soi0) < toli, So, Soi0, "So")
        if abs(So - Soo0) > tolo:
            ii += 1
            delta /= 2.
        else:
            break
    ephi = th.cat((th.cos(phio), th.sin(phio)), dim=-1)
    return ts.ifft(ts.ebemulcc(X, ephi)), ephi
Beispiel #6
0
def defocus(x, pa=None, pr=None, isfft=True, ftshift=True):
    r"""Defocus image with given phase error

    Defocus image in azimuth by

    .. math::
        Y(k, n_r)=\sum_{n_a=0}^{N_a-1} X(n_a, n_r) \exp \left(j \varphi_{n_a}\right) \exp \left(-j \frac{2 \pi}{N_a} k n_a\right)

    where, :math:`\varphi_{n_a}` is the estimated azimuth phase error of the :math:`n_a`-th azimuth line, :math:`y(k, n_r)` is
    the focused pixel.

    The defocus method in range is the same as azimuth.

    Args:
        x (Tensor): Focused image data :math:`{\mathbf X} \in{\mathbb C}^{N\times N_c\times N_a\times N_r}` or
            :math:`{\mathbf X} \in{\mathbb R}^{N\times N_a\times N_r\times 2}` or
            :math:`{\mathbf X} \in{\mathbb R}^{N\times N_c\times N_a\times N_r\times 2}`.
        pa (Tensor, optional): Defocus parameters in azimuth, phase error in rad unit. (the default is None, not focus)
        pr (Tensor, optional): Defocus parameters in range, phase error in rad unit. (the default is None, not focus)
        isfft (bool, optional): Is need do fft (the default is True)
        ftshift (bool, optional): Is shift zero frequency to center when do fft/ifft/fftfreq (the default is True)

    Returns:
        (Tensor): A tensor of defocused images.

    Raises:
        TypeError: :attr:`x` is complex and should be in complex or real represent formation!
    """

    if type(x) is not th.Tensor:
        x = th.tensor(x)

    if th.is_complex(x):
        # N, Na, Nr = x.size(0), x.size(-2), x.size(-1)
        x = th.view_as_real(x)
        crepflag = True
    elif x.size(-1) == 2:
        # N, Na, Nr = x.size(0), x.size(-3), x.size(-2)
        crepflag = False
    else:
        raise TypeError('x is complex and should be in complex or real represent formation!')

    d = x.dim()
    sizea, sizer = [1] * d, [1] * d

    if pa is not None:
        sizea[0], sizea[-3], sizea[-1] = pa.size(0), pa.size(1), 2
        epa = th.stack((th.cos(pa), th.sin(pa)), dim=-1)
        epa = epa.reshape(sizea)

        if isfft:
            x = ts.fft(x, axis=-3, shift=ftshift)
        x = ts.ebemulcc(x, epa)
        x = ts.ifft(x, axis=-3, shift=ftshift)

    if pr is not None:
        sizer[0], sizer[-2], sizer[-1] = pr.size(0), pr.size(1), 2
        epr = th.stack((th.cos(pr), th.sin(pr)), dim=-1)
        epr = epr.reshape(sizer)

        if isfft:
            x = ts.fft(x, axis=-2, shift=ftshift)
        x = ts.ebemulcc(x, epr)
        x = ts.ifft(x, axis=-2, shift=ftshift)

    if crepflag:
        x = th.view_as_complex(x)

    return x
Beispiel #7
0
 def imaging(self, Xc):
     if self.Na is not None:
         Xc = ts.ifft(Xc, axis=-3, shift=self.ftshift)
     if self.Nr is not None:
         Xc = ts.ifft(Xc, axis=-2, shift=self.ftshift)
     return Xc