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()
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