예제 #1
0
def render_image(img = None, spd = None, rfl = None, out = 'img_hyp', \
                 refspd = None, D = None, cieobs = _CIEOBS, \
                 cspace = 'ipt', cspace_tf = {},\
                 k_neighbours = 4, show = True,
                 verbosity = 0, show_ref_img = True,\
                 stack_test_ref = 12,\
                 write_to_file = None):
    """
    Render image under specified light source spd.
    
    Args:
        :img: 
            | None or str or ndarray with uint8 rgb image.
            | None load a default image.
        :spd: 
            | ndarray, optional
            | Light source spectrum for rendering
        :rfl: 
            | ndarray, optional
            | Reflectance set for color coordinate to rfl mapping.
        :out: 
            | 'img_hyp' or str, optional
            |  (other option: 'img_ren': rendered image under :spd:)
        :refspd:
            | None, optional
            | Reference spectrum for color coordinate to rfl mapping.
            | None defaults to D65 (srgb has a D65 white point)
        :D: 
            | None, optional
            | Degree of (von Kries) adaptation from spd to refspd. 
        :cieobs:
            | _CIEOBS, optional
            | CMF set for calculation of xyz from spectral data.
        :cspace:
            | 'ipt',  optional
            | Color space for color coordinate to rfl mapping.
        :cspace_tf:
            | {}, optional
            | Dict with parameters for xyz_to_cspace and cspace_to_xyz transform.
        :k_neighbours:
            | 4 or int, optional
            | Number of nearest neighbours for reflectance spectrum interpolation.
            | Neighbours are found using scipy.cKDTree
        :show: 
            | True, optional
            |  Show images.
        :verbosity:
            | 0, optional
            | If > 0: make a plot of the color coordinates of original and 
              rendered image pixels.
        :show_ref_img:
            | True, optional
            | True: shows rendered image under reference spd. False: shows
              original image.
        :write_to_file:
            | None, optional
            | None: do nothing, else: write to filename(+path) in :write_to_file:
        :stack_test_ref: 
            | 12, optional
            |   - 12: left (test), right (ref) format for show and imwrite
            |   - 21: top (test), bottom (ref)
            |   - 1: only show/write test
            |   - 2: only show/write ref
            |   - 0: show both, write test

    Returns:
        :returns: 
            | img_hyp, img_ren, 
            | ndarrays with hyperspectral image and rendered images 
    """

    # Get image:
    #imread = lambda x: plt.imread(x) #matplotlib.pyplot

    if img is not None:
        if isinstance(img, str):
            img = plt.imread(img)  # use matplotlib.pyplot's imread
    else:
        img = plt.imread(_HYPSPCIM_DEFAULT_IMAGE)

    # Convert to 2D format:
    rgb = img.reshape(img.shape[0] * img.shape[1], 3) * 1.0  # *1.0: make float
    rgb[rgb == 0] = _EPS  # avoid division by zero for pure blacks.

    # Get unique rgb values and positions:
    rgb_u, rgb_indices = np.unique(rgb, return_inverse=True, axis=0)

    # get Ref spd:
    if refspd is None:
        refspd = _CIE_ILLUMINANTS['D65'].copy()

    # Convert rgb_u to xyz and lab-type values under assumed refspd:
    xyz_wr = spd_to_xyz(refspd, cieobs=cieobs, relative=True)
    xyz_ur = colortf(rgb_u, tf='srgb>xyz')

    # Estimate rfl's for xyz_ur:
    rfl_est, xyzri = xyz_to_rfl(xyz_ur, rfl = rfl, out = 'rfl_est,xyz_est', \
                 refspd = refspd, D = D, cieobs = cieobs, \
                 cspace = cspace, cspace_tf = cspace_tf,\
                 k_neighbours = k_neighbours, verbosity = verbosity)

    # Get default test spd if none supplied:
    if spd is None:
        spd = _CIE_ILLUMINANTS['F4']

    # calculate xyz values under test spd:
    xyzti, xyztw = spd_to_xyz(spd, rfl=rfl_est, cieobs=cieobs, out=2)

    # Chromatic adaptation from test spd to refspd:
    if D is not None:
        xyzti = cat.apply(xyzti, xyzw1=xyztw, xyzw2=xyz_wr, D=D)

    # Convert xyzti under test spd to srgb:
    rgbti = colortf(xyzti, tf='srgb') / 255

    # Reconstruct original locations for rendered image rgbs:
    img_ren = rgbti[rgb_indices]
    img_ren.shape = img.shape  # reshape back to 3D size of original

    # For output:
    if show_ref_img == True:
        rgb_ref = colortf(xyzri, tf='srgb') / 255
        img_ref = rgb_ref[rgb_indices]
        img_ref.shape = img.shape  # reshape back to 3D size of original
        img_str = 'Rendered (under ref. spd)'
        img = img_ref
    else:
        img_str = 'Original'
        img = img / 255

    if (stack_test_ref > 0) | show == True:
        if stack_test_ref == 21:
            img_original_rendered = np.vstack(
                (img_ren, np.ones((4, img.shape[1], 3)), img))
            img_original_rendered_str = 'Rendered (under test spd)\n ' + img_str
        elif stack_test_ref == 12:
            img_original_rendered = np.hstack(
                (img_ren, np.ones((img.shape[0], 4, 3)), img))
            img_original_rendered_str = 'Rendered (under test spd) | ' + img_str
        elif stack_test_ref == 1:
            img_original_rendered = img_ren
            img_original_rendered_str = 'Rendered (under test spd)'
        elif stack_test_ref == 2:
            img_original_rendered = img
            img_original_rendered_str = img_str
        elif stack_test_ref == 0:
            img_original_rendered = img_ren
            img_original_rendered_str = 'Rendered (under test spd)'

    if write_to_file is not None:
        # Convert from RGB to BGR formatand write:
        #print('Writing rendering results to image file: {}'.format(write_to_file))
        with warnings.catch_warnings():
            warnings.simplefilter("ignore")
            imsave(write_to_file, img_original_rendered)

    if show == True:
        # show images using pyplot.show():
        plt.figure()
        plt.imshow(img_original_rendered)
        plt.title(img_original_rendered_str)
        plt.gca().get_xaxis().set_ticklabels([])
        plt.gca().get_yaxis().set_ticklabels([])

        if stack_test_ref == 0:
            plt.figure()
            plt.imshow(img_str)
            plt.title(img_str)
            plt.axis('off')

    if 'img_hyp' in out.split(','):
        # Create hyper_spectral image:
        rfl_image_2D = rfl_est[
            rgb_indices +
            1, :]  # create array with all rfls required for each pixel
        img_hyp = rfl_image_2D.reshape(img.shape[0], img.shape[1],
                                       rfl_image_2D.shape[1])

    # Setup output:
    if out == 'img_hyp':
        return img_hyp
    elif out == 'img_ren':
        return img_ren
    else:
        return eval(out)
    _CMF[cieobs]['M'] = M
    #return _CMF


if __name__ == '__main__':

    outcmf = 'lms'

    out = outcmf + ',trans_lens,trans_macula,sens_photopig,LMSa'
    LMS, trans_lens, trans_macula, sens_photopig, LMSa = cie2006cmfsEx(out=out)

    plt.figure()
    plt.plot(LMS[0], LMS[1], color='r', linestyle='--')
    plt.plot(LMS[0], LMS[2], color='g', linestyle='--')
    plt.plot(LMS[0], LMS[3], color='b', linestyle='--')
    plt.title('cie2006cmfsEx(...)')
    plt.show()

    out = outcmf + ',var_age,vAll'

    LMS_All, var_age, vAll = genMonteCarloObs(n_obs=10,
                                              fieldsize=10,
                                              list_Age=[32],
                                              out=out)
    plt.figure()
    plt.plot(LMS_All[0], LMS_All[1], color='r', linestyle='-')
    plt.plot(LMS_All[0], LMS_All[2], color='g', linestyle='-')
    plt.plot(LMS_All[0], LMS_All[3], color='b', linestyle='-')
    plt.title('genMonteCarloObs(...)')
    plt.show()
예제 #3
0
def demo_opt(f, args=(), xrange=None, options={}):
    """
    DEMO_OPT: Multi-objective optimization using the DEMO
    This function uses the Differential Evolution for Multi-objective 
    Optimization (a.k.a. DEMO) to solve a multi-objective problem. The 
    result is a set of nondominated points that are (hopefully) very close
    to the true Pareto front.

    Args:
      :f: 
          | handle to objective function.
          | The output must be, for each point, a column vector of size m x 1, 
          | with m > 1 the number of objectives.
      :args: (), optional
          | Input arguments required for f.
      :xrange: None, optional
          | ndarray with lower and upperbounds.
          | If n is the dimension, it will be a n x 2 matrix, such that the 
          | first column contains the lower bounds, 
          | and the second, the upper bounds.
          | None defaults to no bounds ( [-Inf, Inf] ndarray).
      :options: 
          | None, optional
          | dict with internal parameters of the algorithm.
          | None initializes default values.
          | keys:
          | - 'F': the scale factor to be used in the mutation (default: 0.5);
          | - 'CR': the crossover factor used in the recombination (def.: 0.3);
          | - 'mu': the population size (number of individuals) (def.: 100);
          | - 'kmax': maximum number of iterations (def.: 300);
          | - 'display': 'on' to display the population while the algorithm is
          |         being executed, and 'off' to not (default: 'off');
          | If any of the parameters is not set, the default ones are used
          | instead.

    Returns: fopt, xopt
          :fopt: the m x mu_opt ndarray with the mu_opt best objectives
          :xopt: the n x mu_opt ndarray with the mu_opt best individuals
    """

    # Initialize the parameters of the algorithm with values contained in dict:
    options = init_options(options=options)

    # Initial considerations
    n = xrange.shape[0]  #dimension of the problem
    P = {'x': np.random.rand(n, options['mu'])}  #initial decision variables
    P['f'] = fobjeval(f, P['x'], args,
                      xrange)  #evaluates the initial population
    m = P['f'].shape[0]  #number of objectives
    k = 0  #iterations counter

    # Beginning of the main loop
    Pfirst = P.copy()
    axh = None
    while (k <= options['kmax']):
        # Plot the current population (if desired):
        if options['display'] == True:
            if (k == 0) & (m < 4):
                fig = plt.gcf()
                fig.show()
                fig.canvas.draw()
            if m == 2:
                #              fig = plt.figure()
                axh = plt.axes()
                plt.plot(P['f'][0], P['f'][1], 'o')
                plt.title('Objective values during the execution')
                plt.xlabel('f_1')
                plt.ylabel('f_2')
                fig.canvas.draw()
                del axh.lines[0]
            elif m == 3:
                #              fig = plt.figure()
                axh = plt.axes(projection='3d')
                #              print(P['f'])
                axh.plot3D(P['f'][0], P['f'][1], P['f'][2], 'o')
                plt.title('Objective values during the execution')
                axh.set_xlabel('f_1')
                axh.set_ylabel('f_2')
                axh.set_zlabel('f_3')
                fig.canvas.draw()
                plt.pause(0.01)
                del axh.lines[0]

        # Perform the variation operation (mutation and recombination):
        O = {'x': mutation(P['x'], options)}  #mutation
        O['x'] = recombination(P['x'].copy(), O['x'], options)  #recombination
        O['x'] = repair(
            O['x'])  #assure the offspring do not cross the search limits
        O['f'] = fobjeval(f, O['x'], args,
                          xrange)  #compute objective functions

        # Selection and updates
        P = selection(P, O, options)

        print('Iteration #{:1.0f} of {:1.0f}'.format(k, options['kmax']))
        k += 1

    # Return the final population:
    # First, unnormalize it
    Xmin = xrange[:,
                  0][:,
                     None]  # * np.ones(options['mu']) #replicate lower bound
    Xmax = xrange[:,
                  1][:,
                     None]  # * np.ones(options['mu']) #replicate upper limit
    Xun = (Xmax - Xmin) * P['x'] + Xmin

    # Then, return the nondominated front:
    ispar = ndset(P['f'])
    fopt = P['f'][:, ispar]
    xopt = Xun[:, ispar]

    return fopt, xopt