示例#1
0
class SphericalHarmonic:
    def __init__(self, input_, copy_=True, max_l=None, norm=4):
        """
        Projects `input_` to its spherical harmonics basis up to degree `max_l`.
        
        norm = 4 means orthonormal harmonics.
        For more details, please see https://shtools.oca.eu/shtools/pyshexpanddh.html
        """

        if copy_:
            self.spatial = input_.copy()
        else:
            self.spatial = input_

        if not isinstance(self.spatial, EnvironmentMap):
            self.spatial = EnvironmentMap(self.spatial, 'LatLong')

        if self.spatial.format_ != "latlong":
            self.spatial = self.spatial.convertTo("latlong")

        self.norm = norm

        self.coeffs = []
        for i in range(self.spatial.data.shape[2]):
            self.coeffs.append(
                SHExpandDH(self.spatial.data[:, :, i],
                           norm=norm,
                           sampling=2,
                           lmax_calc=max_l))

    def reconstruct(self, height=None, max_l=None, clamp_negative=True):
        """
        :height: height of the reconstructed image
        :clamp_negative: Remove reconstructed values under 0
        """

        retval = []
        for i in range(len(self.coeffs)):
            retval.append(
                MakeGridDH(self.coeffs[i],
                           norm=self.norm,
                           sampling=2,
                           lmax=height,
                           lmax_calc=max_l))

        retval = np.asarray(retval).transpose((1, 2, 0))

        if clamp_negative:
            retval = np.maximum(retval, 0)

        return retval
示例#2
0
class SphericalHarmonic:
    def __init__(self, input_, copy_=True, max_l=None, norm=4):
        """
        Projects `input_` to its spherical harmonics basis up to degree `max_l`.
        
        norm = 4 means orthonormal harmonics.
        For more details, please see https://shtools.oca.eu/shtools/pyshexpanddh.html
        """

        if copy_:
            self.spatial = input_.copy()
        else:
            self.spatial = input_

        if not isinstance(self.spatial, EnvironmentMap):
            self.spatial = EnvironmentMap(self.spatial, 'LatLong')

        if self.spatial.format_ != "latlong":
            self.spatial = self.spatial.convertTo("latlong")

        self.norm = norm

        #from cffi import FFI
        #ffi = FFI()
        #ffi.cdef("""
        #    void generateAssociatedLegendreFactors(const float N, float *data_out, const float * nodes, const unsigned int num_nodes);
        #""")
        #if os.name == 'nt':
        #    C = ffi.dlopen(os.path.join(os.path.dirname(os.path.realpath(__file__)), "spharm_tools.dll"))
        #else:
        #    C = ffi.dlopen(os.path.join(os.path.dirname(os.path.realpath(__file__)), "spharm_tools.so"))
        self.coeffs = []
        for i in range(self.spatial.data.shape[2]):
            self.coeffs.append(
                SHExpandDH(self.spatial.data[:, :, i],
                           norm=norm,
                           sampling=2,
                           lmax_calc=max_l))

    def reconstruct(self, height=None, max_l=None, clamp_negative=True):
        """
        :height: height of the reconstructed image
        :clamp_negative: Remove reconstructed values under 0
        """

        retval = []
        for i in range(len(self.coeffs)):
            retval.append(
                MakeGridDH(self.coeffs[i],
                           norm=self.norm,
                           sampling=2,
                           lmax=height,
                           lmax_calc=max_l))

        retval = np.asarray(retval).transpose((1, 2, 0))

        if clamp_negative:
            retval = np.maximum(retval, 0)

        #original fork return here !
        #return retval

        # nodes = []
        # weights = []
        # for d in range(1, degrees + 2):
        #     x, y = np.polynomial.legendre.leggauss(d)
        #     nodes.extend(x)
        #     weights.extend(y)

        retval = np.zeros((int((2 * (degrees + 1) + 1)**2 / 8), ch),
                          dtype=np.complex128)

        P, nodes = _getP(envmap, degrees)
        print(degrees, P.shape)

        # Gauss-Legendre / Gauss-Chebyshev quadrature to speed up?
        # Perform in C
        # for j in range(envmap.data.shape[1]):
        #     for k in range(ch):
        #         #fmi = np.interp(nodes, np.linspace(-np.pi/2, np.pi/2, fm.shape[0]), np.squeeze(fm[:,j,k]))
        #         i = 0
        #         for l in range(degrees + 1):
        #             for m in range(0, l + 1):
        #                 retval[l,m,k] += fm * P[l,m]
        #                 i += 1

        import operator
        i = 0
        for l in tqdm(range(degrees + 1)):
            for m in range(0, l + 1):
                #coef = np.sqrt(( (2.*l+1.) / (4.*np.pi) ) * ( 1. / (functools.reduce(operator.mul, range(l-m+1, l+m+1), 1)) ) )
                for c in range(ch):
                    #retval[i,c] = np.nansum(coef*P[:,i]*np.squeeze(fm[:,m,c]))
                    retval[i, c] = np.nansum(P[:, i] * np.squeeze(fm[:, m, c]))
                    #import pdb; pdb.set_trace()
                    #retval[i,c] = np.nansum(coef*P[:,i]*np.exp(1j*m*theta.ravel())*envmap.data.reshape([-1,ch])[:,c])
                    #retval[i,c] = np.nansum(coef*ref[:,i]*np.exp(-1j*m*(theta).ravel())*f[:,c])
                #print("2: ", coef*P[:,i]*np.exp(1j*m*theta.ravel())*f[:,c])
                i += 1

        #import pdb; pdb.set_trace()

        from matplotlib import pyplot as plt
        #plt.scatter(nodes_cos, ref); plt.show()

        return retval
示例#3
0
    elif reduction_type == 'right':
        retval[_triangleRightSide(degrees)] = coeffs
        for i in set(range(
            (degrees + 1)**2)) - set(_triangleRightSide(degrees)):
            l = np.sqrt(i).astype('int')
            m = abs((l) - (i - l**2))
            retval[i] = (-1)**m * np.conj(retval[l**2 + l + m])
        return retval


if __name__ == '__main__':
    from matplotlib import pyplot as plt

    e = EnvironmentMap('envmap.exr', 'angular')
    e.resize((64, 64))
    e.convertTo('latlong')

    se = SphericalHarmonic(e)

    err = []
    from tqdm import tqdm
    for i in tqdm(range(32)):
        recons = se.reconstruct(max_l=i)
        err.append(np.sum((recons - e.data)**2))

    plt.plot(err)

    plt.figure()
    plt.imshow(recons)
    plt.show()