def __call__(self, original_image): dic_sp_val = SPCSOperator.__call__(self, original_image) vals = np.array([]) cache_blobs = False X_feature_t = np.array([]) for elem in dic_sp_val.keys(): if self._uc == "superpixel": image_sp = self._spp_method(original_image) blobs = sp.computeBlobs(image_sp) list_vals = [] # if cache_blobs == False: # blobs = sp.computeBlobs(dic_sp_val[elem]) # cache_blobs = True the_vals = sp.measMinVals(dic_sp_val[elem], blobs) for lbl in blobs.keys(): list_vals +=[int(the_vals[lbl])] array_vals = np.array(list_vals) elif self._uc == "pixel": array_vals = np.ravel(dic_sp_val[elem].getNumArray()) else: raise TypeError("uc (string) should be equal to superpixel or pixel") X_feature_t = uf.my_concatenation(X_feature_t, array_vals) return X_feature_t
def one_min_per_grid_cell(im_cells_lbl, blobs, im_labelled_minima, se): """ Enables to select the best marker of each cell of the grid. Input: im_cells_lbl (UINT16): image of labelled cells. blobs: definition of each connected component im_labelled_minima (UINT16): image of markers candidates labelled with their ranking for some given criterium (e.g. surfacic extinction), i.e. "1" is the best. se: structuring element. """ ## Selection of the marker with the best ranking in each cell: imtmp = sp.Image(im_cells_lbl) sp.test(im_labelled_minima, im_labelled_minima, 65335, im_labelled_minima) minVals = sp.measMinVals(im_labelled_minima, blobs) sp.applyLookup(im_cells_lbl, minVals, imtmp) sp.compare(im_labelled_minima, "==", imtmp, im_labelled_minima, 0, im_labelled_minima) ## Selection of only one marker if several met the previous requirement in the same cell: sp.label(im_labelled_minima, imtmp, se) blobs2 = sp.computeBlobs(im_labelled_minima) maxVals = sp.measMaxVals(imtmp, blobs) sp.applyLookup(im_cells_lbl, maxVals, im_labelled_minima) sp.compare(imtmp, "==", im_labelled_minima, imtmp, 0, imtmp) sp.test(im_cells_lbl, imtmp, 0, im_labelled_minima) return
def one_min_per_grid_cell(im_cells_lbl, blobs, im_labelled_minima, se): """ Enables to select the best marker of each cell of the grid. Input: im_cells_lbl (UINT16): image of labelled cells. blobs: definition of each connected component im_labelled_minima (UINT32): image of markers candidates labelled with their ranking for some given criterium (e.g. surfacic extinction), i.e. "1" is the best. se: structuring element. """ ## Selection of the marker with the best ranking in each cell: imtmp = sp.Image_UINT32(im_cells_lbl.getSize()[0], im_cells_lbl.getSize()[1]) num_max = np.int(np.power(2, 32)-1) sp.test(im_labelled_minima, im_labelled_minima, num_max , im_labelled_minima) minVals = sp.measMinVals(im_labelled_minima, blobs) sp.applyLookup(im_cells_lbl, minVals, imtmp) sp.compare(im_labelled_minima, "==", imtmp, im_labelled_minima, 0, im_labelled_minima) ## Selection of only one marker if several met the previous requirement in the same cell: sp.label(im_labelled_minima, imtmp, se) blobs2 = sp.computeBlobs(im_labelled_minima) maxVals = sp.measMaxVals(imtmp, blobs) sp.applyLookup(im_cells_lbl, maxVals, im_labelled_minima) sp.compare(imtmp, "==", im_labelled_minima, imtmp, 0, imtmp) sp.test(im_cells_lbl, imtmp, 0, im_labelled_minima) return
def apply_with_integrator(vals_map, spp_lab, integrator_code): """ Permet de calculer la valeur intégrée de chaque superpixel et de créer l'image de superpixels associée. """ im_out = sp.Image(spp_lab) blobs = sp.computeBlobs(spp_lab) myLUT = sp.Map_UINT16_UINT16() if integrator_code == "mean" or integrator_code == "std": if integrator_code == "mean": choice = 0 else: choice = 1 for lbl in blobs.keys(): myLUT[lbl] = int(vals_map[lbl][choice]) else: for lbl in blobs.keys(): myLUT[lbl] = int(vals_map[lbl]) sp.applyLookup(spp_lab, myLUT, im_out) return im_out
def __call__(self, original_image): """ Output: dictionnaire contenant pour chaque canal choisi l'image de superpixels, avec une seule valeur par superpixel. """ image_sp = self._spp_method(original_image) blobs = sp.computeBlobs(image_sp) dict_integrator = { "mean": sp.measMeanVals, "std": sp.measMeanVals, "mode": sp.measModeVals, "min": sp.measMinVals, "max": sp.measMaxVals, "vol": sp.measVolumes, } ### dic_im_res={} if original_image.getTypeAsString()=="RGB": if self._channels_list == None: self._channels_list = [0,1,2] image_slices = sp.Image() sp.splitChannels(original_image, image_slices) image_transformed = sp.Image(image_slices.getSlice(0)) for i in self._channels_list: self._operator_functor(image_slices.getSlice(i), image_transformed) vals_map = dict_integrator[self._integrator](image_transformed, blobs) im_out = apply_with_integrator(vals_map, image_sp, self._integrator) dic_im_res[i] = im_out elif original_image.getTypeAsString()=="UINT8" or original_image.getTypeAsString()=="UINT16": self._channels_list = [0] image_transformed = sp.Image(original_image) self._operator_functor(original_image, image_transformed) vals_map = dict_integrator[self._integrator](image_transformed, blobs) im_out = apply_with_integrator(vals_map, image_sp, self._integrator) dic_im_res[0] = im_out else: raise TypeError('pb') return dic_im_res
import smilPython as sp import numpy as np from numpy import linalg as la # get image imIn = sp.Image("https://smil.cmm.minesparis.psl.eu/images/tools.png") # labelize input image imThr = sp.Image(imIn) sp.topHat(imIn, imThr, sp.hSE(20)) sp.threshold(imThr, imThr) imLbl = sp.Image(imIn, "UINT16") sp.label(imThr, imLbl) # compute blobs and get their data blobs = sp.computeBlobs(imLbl) central = True inertia = sp.blobsInertiaMatrix(imIn, blobs, central) barys = sp.blobsBarycenter(imIn, blobs) nshape = (2, 2) if imIn.getDimension() == 3: nshape = (3, 3) for k in inertia.keys(): print("=" * 64) s = "" for v in barys[k]: s += " {:6.1f}".format(v) print("Blob label : {:3d} - Barycenter :{:}".format(k, s)) # Smil returns inertia matrix as a vector. Reshape it.
def __call__(self, original_image): """ Plusieurs étapes: 1) calculer les superpixels de l'image originale 2) calculer le dictionnaire des imagettes de superpixels 3) appliquer l'opérateur sur chacune de ces imagettes 4) intégrer sur le superpixel pour n'avoir qu'une seule valeur (si besoin) --> inclus dans l'opérateur 5) calculer la nouvelle image entière des superpixels, où cette fois-ci la valeur de chaque SP n'est pas son label mais celle calculée en 4. [Note: plusieurs images si plusieurs cannaux sélectionnés dans channels_list. Output: dictionnaire de ces images finales.] --> output plut^ot un dictionnaire car pas besoin des images. Ouput: dic_inter: un dictionnaire tel que: - chaque clé est un numéro de superpixel ex: i - chaque valeur est un dictionnaire associé au superpixel i, contenant pour chaque cannal j (clés) la valeur du feature. """ ### Etape 1: calcul des SP image_sp = self._spp_method(original_image) blobs = sp.computeBlobs(image_sp) barys = sp.measBarycenters(image_sp, blobs) ### Etape 2 : cacul du dictionnaire intermédiaire ### Inititation listes: if original_image.getTypeAsString()=="RGB": if self._channels_list == None: self._channels_list = [0,1,2] elif original_image.getTypeAsString()=="UINT8" or original_image.getTypeAsString()=="UINT16": self._channels_list = [0] else: raise TypeError('pb') dic_final = {} for i in self._channels_list: dic_final[i] = [] ## cette liste contiendra la valeur pour chaque superpixel ### dic_inter = {} nb_sp = len(blobs.keys()) ## nombre de superpixels bboxes_coord = sp.measBoundBoxes(image_sp) ## dictionnary of coordinates of the two points (top left, bottom right) of each bounding box. sim_sp = sp.Image(image_sp)## pour garder temporairement l'imagette du superpixel for elem in range(nb_sp): elem += 1 sp.crop(image_sp, bboxes_coord[elem][0], bboxes_coord[elem][1], bboxes_coord[elem][2] - bboxes_coord[elem][0] + 1, bboxes_coord[elem][3] - bboxes_coord[elem][1] + 1, sim_sp) sp.subNoSat(sim_sp, elem, sim_sp) sp.test(sim_sp, 0, 65535, sim_sp) ## imagette masque du superpixel i # sim_sp.save('imagettes/bin_mask_'+str(elem)+'.png') # if sim_sp.getSize()[0] == 1 and sim_sp.getSize()[1] == 1 : # print "sup_" + str(elem) +"pos_" + str(bboxes_coord[elem][0]) + "_" + str(bboxes_coord[elem][1]) # image_sp.save("essais/sup_" + str(elem) +"pos_" + str(bboxes_coord[elem][0]) + "_" + str(bboxes_coord[elem][1]) + "_SP.png") # original_image.save("essais/sup_" + str(elem) +"pos_" + str(bboxes_coord[elem][0]) + "_" + str(bboxes_coord[elem][1]) + "_orig.png") if original_image.getTypeAsString()=="RGB": image_slices = sp.Image() sp.splitChannels(original_image, image_slices) dic_orig_slices={} for i in self._channels_list: sim_orig_slice= sp.Image(image_slices.getSlice(i)) sp.crop(image_slices.getSlice(i), bboxes_coord[elem][0], bboxes_coord[elem][1], bboxes_coord[elem][2] - bboxes_coord[elem][0] + 1, bboxes_coord[elem][3] - bboxes_coord[elem][1] + 1, sim_orig_slice) sp.add(sim_orig_slice, 1, sim_orig_slice) sp.test(sim_sp>0, sim_orig_slice, 0, sim_orig_slice) dic_orig_slices[i] = sim_orig_slice #sim_orig_slice.save('imagettes/orig_slice_'+str(i)+'_for_sup_'+str(elem)+'.png') elif original_image.getTypeAsString()=="UINT8" or original_image.getTypeAsString()=="UINT16": dic_orig_slices={} sim_orig_slice= sp.Image(original_image) sp.crop(original_image, bboxes_coord[elem][0], bboxes_coord[elem][1], bboxes_coord[elem][2] - bboxes_coord[elem][0] + 1, bboxes_coord[elem][3] - bboxes_coord[elem][1] + 1, sim_orig_slice) sp.add(sim_orig_slice, 1, sim_orig_slice) sp.test(sim_sp>0, sim_orig_slice, 0, sim_orig_slice) dic_orig_slices[0] = sim_orig_slice dic_inter[elem] = (sim_sp, dic_orig_slices, barys[elem]) ### Etape 3: application de l'opérateur sur chaque imagette: dic_elem_val_={} for i in self._channels_list: dic_final[i] += [self._operator_functor(dic_orig_slices[i])] return dic_final
def __call__(self, original_image): """ Plusieurs étapes: 1) calculer les superpixels de l'image originale 2) calculer le dictionnaire des imagettes de superpixels 3) appliquer l'opérateur sur chacune de ces imagettes 4) intégrer sur le superpixel pour n'avoir qu'une seule valeur (si besoin) --> inclus dans l'opérateur 5) calculer la nouvelle image entière des superpixels, où cette fois-ci la valeur de chaque SP n'est pas son label mais celle calculée en 4. [Note: plusieurs images si plusieurs cannaux sélectionnés dans channels_list. Output: dictionnaire de ces images finales.] --> output plut^ot un dictionnaire car pas besoin des images. Ouput: dic_inter: un dictionnaire tel que: - chaque clé est un numéro de superpixel ex: i - chaque valeur est un dictionnaire associé au superpixel i, contenant pour chaque cannal j (clés) la valeur du feature. """ ### Etape 1: calcul des SP image_sp = self._spp_method(original_image) blobs = sp.computeBlobs(image_sp) barys = sp.measBarycenters(image_sp, blobs) ### Etape 2 : cacul du dictionnaire intermédiaire ### Inititation listes: if original_image.getTypeAsString()=="RGB": if self._channels_list == None: self._channels_list = [0,1,2] elif original_image.getTypeAsString()=="UINT8" or original_image.getTypeAsString()=="UINT16": self._channels_list = [0] else: raise TypeError('pb') dic_final = {} #for i in self._channels_list: # dic_final[i] = [] ## cette liste contiendra la valeur pour chaque superpixel ### dic_inter = {} nb_sp = len(blobs.keys()) ## nombre de superpixels bboxes_coord = sp.measBoundBoxes(image_sp) ## dictionnary of coordinates of the two points (top left, bottom right) of each bounding box. sim_sp = sp.Image(image_sp)## pour garder temporairement l'imagette du superpixel for elem in range(nb_sp): elem += 1 sp.crop(image_sp, bboxes_coord[elem][0], bboxes_coord[elem][1], bboxes_coord[elem][2] - bboxes_coord[elem][0] + 1, bboxes_coord[elem][3] - bboxes_coord[elem][1] + 1, sim_sp) sp.subNoSat(sim_sp, elem, sim_sp) sp.test(sim_sp, 0, 65535, sim_sp) ## imagette masque du superpixel i # sim_sp.save('imagettes/bin_mask_'+str(elem)+'.png') # if sim_sp.getSize()[0] == 1 and sim_sp.getSize()[1] == 1 : # print "sup_" + str(elem) +"pos_" + str(bboxes_coord[elem][0]) + "_" + str(bboxes_coord[elem][1]) # image_sp.save("essais/sup_" + str(elem) +"pos_" + str(bboxes_coord[elem][0]) + "_" + str(bboxes_coord[elem][1]) + "_SP.png") # original_image.save("essais/sup_" + str(elem) +"pos_" + str(bboxes_coord[elem][0]) + "_" + str(bboxes_coord[elem][1]) + "_orig.png") if original_image.getTypeAsString()=="RGB": image_slices = sp.Image() sp.splitChannels(original_image, image_slices) dic_orig_slices={} for i in self._channels_list: sim_orig_slice= sp.Image(image_slices.getSlice(i)) sp.crop(image_slices.getSlice(i), bboxes_coord[elem][0], bboxes_coord[elem][1], bboxes_coord[elem][2] - bboxes_coord[elem][0] + 1, bboxes_coord[elem][3] - bboxes_coord[elem][1] + 1, sim_orig_slice) sp.add(sim_orig_slice, 1, sim_orig_slice) sp.test(sim_sp>0, sim_orig_slice, 0, sim_orig_slice) dic_orig_slices[i] = sim_orig_slice #sim_orig_slice.save('imagettes/orig_slice_'+str(i)+'_for_sup_'+str(elem)+'.png') elif original_image.getTypeAsString()=="UINT8" or original_image.getTypeAsString()=="UINT16": dic_orig_slices={} sim_orig_slice= sp.Image(original_image) sp.crop(original_image, bboxes_coord[elem][0], bboxes_coord[elem][1], bboxes_coord[elem][2] - bboxes_coord[elem][0] + 1, bboxes_coord[elem][3] - bboxes_coord[elem][1] + 1, sim_orig_slice) sp.add(sim_orig_slice, 1, sim_orig_slice) sp.test(sim_sp>0, sim_orig_slice, 0, sim_orig_slice) dic_orig_slices[0] = sim_orig_slice dic_inter[elem] = (sim_sp, dic_orig_slices, barys[elem]) ### Etape 3: application de l'opérateur sur chaque imagette: dic_elem_val_={} for i in self._channels_list: # TODO: would be better to check a feature list with memory feats_from_op = None for op in self._operator_functors: # todo: remove _ feature_name = op.get_name()+"_"+self._spp_method.get_name()+"_for_channel_" + str(i) if not feature_name in dic_final: dic_final[feature_name] = [] dic_final[feature_name].append(op(dic_orig_slices[i], feats_from_op)) feats_from_op = op.feats # the list of all features (channel is hard coded in the feature names) features = self.get_name() # get a matrix nb_features x nb_superpixels with all feature values Xsp = np.array([dic_final[x] for x in features]) if self._uc == "pixel": # get a vector with a concatenation of all lines of the superpixel image (label image) # the -1 comes from the fact that the label image starts with 1. indices = np.ravel(image_sp.getNumArray()) - 1 # we simply slice Xsp to get the final pixel features X = Xsp[:,indices] else: # in case we want to classify superpixels, the initial matrix was fine. X = Xsp return X
import smilPython as sp im = sp.Image("balls.png") iml = sp.Image(im) # this is just a binary image - no need to segment sp.label(im, iml) iml.showLabel() # create blobs structure blobs = sp.computeBlobs(iml) # evaluate some measures : areas = sp.blobsArea(blobs) barys = sp.blobsBarycenter(im, blobs) # print areas and barycenters of each region print("{:3s} - {:>6s} - {:>13s}".format("ID", "Area", "Barycenter")) for k in blobs.keys(): bary = barys[k] print("{:3d} - {:6.0f} - {:6.0f} {:6.0f}".format(k, areas[k], bary[0], bary[1]))
def demo_m_waterpixels(imin, step, d_weight, filter_ori): """ Compute m-waterpixels, i.e. superpixels based on the watershed transformation. Flooding starts form the best minimum of each cell of a regular grid. The gradient used to be flooded is regularized using the distance function to these minima. Cells of the grid are chosen here to be squares. Input : imin (image UINT8): original image, to be segmented into superpixels step (UINT8) : grid step, i.e. distance between two cell centers of the grid d_weight (UINT8) : constant to be multiplied with function distance before addition to gradient image. If d_weight <=0, then only the gradient is taken into account. filter_ori (BOOLEAN) : do we filter the input image? Output: image (UINT16) : labelled superpixels image (UINT8) : distance weighted gradient function image (UINT16) : minima used in the computation """ ##----------------------------------------------------------------------------------------- ##----------------------------------------------------------------------------------------- # Connexity: basicse = sp.CrossSE() gridse = sp.SquSE() # Ori filtering if filter_ori is True: my_area_filtering(imin, step*step/16) # Gradient computation im_grad = my_gradient(imin, basicse, True) ## Pool of working images: imwrk0 = sp.Image(im_grad) imwrk1 = sp.Image(im_grad, "UINT16") imwrk2 = sp.Image(im_grad, "UINT16") # Compute cell centers and cells size = imin.getSize() im_markers, im_cells = im_labelled_square_grid_points(size, step, step/6) ##----------------------------------------------------------------------------------------- ##----------------------------------------------------------------------------------------- ## Choice of the markers : one per grid cell ##----------------------------------------------------------------------------------------- ##----------------------------------------------------------------------------------------- # Step 1 : Computation of the minima of the gradient im_minima = sp.Image(im_grad) sp.minima(im_grad, im_minima, basicse) #Step 2 : Imposing minimum distance between minima (= Removing minima candidates which fall on cell margins ) sp.test(im_cells, im_minima, 0, imwrk0) sp.label(imwrk0, imwrk1, basicse) #Step 3 : Evaluation of the importance of minima ( = computation of their surfacic extinction) im_minima_val = sp.Image(imwrk1) sp.watershedExtinction( im_grad, imwrk1, im_minima_val, "a", basicse) # Step 4 : Taking back at value 2 the minima of null-volumic extinction sp.test( imwrk0, 2, 0, imwrk2) sp.test( im_minima_val, im_minima_val, imwrk2, im_minima_val ) # Step 5 : Coping with the potential absence of minimum in cells (= choosing the minimum value inside this cell as its marker if necessary) imwrk00=sp.Image(imwrk0) blobs = sp.computeBlobs(im_cells) sp.test(im_cells, im_grad, 0, imwrk00) minVals = sp.measMinVals(imwrk00, blobs) sp.applyLookup(im_cells, minVals, imwrk0) sp.test(imwrk00==imwrk0, 1, 0, imwrk1) maxVals = sp.measMaxVals(im_minima_val, blobs) sp.applyLookup(im_cells, maxVals, imwrk2) sp.test(imwrk2, im_minima_val, imwrk1, im_minima_val) # Step 6 : Selection of one marker per cell one_min_per_grid_cell(im_cells, blobs, im_minima_val, basicse) ##----------------------------------------------------------------------------------------- ##----------------------------------------------------------------------------------------- ## Spatial regularization of the gradient ##----------------------------------------------------------------------------------------- ##----------------------------------------------------------------------------------------- #Step 1 : Computation of the distance function to the markers immask = sp.Image(im_markers, "UINT8") sp.test(im_minima_val, 0, 1, immask) imdist = sp.Image(immask, "UINT8") sp.dist(immask, imdist, gridse) #Step 2 : Adding the distance function to the gradient if d_weight > 0: weight = d_weight * float(2)/step sp.mul(imdist, weight, imdist) sp.add(imdist, im_grad, im_grad) ##----------------------------------------------------------------------------------------- ##----------------------------------------------------------------------------------------- ## Superpixel segmentation : watershed transformation, flooding from selected minima on the regularized gradient ##----------------------------------------------------------------------------------------- ##----------------------------------------------------------------------------------------- sp.copy(im_minima_val, imwrk1) sp.label(imwrk1, im_minima_val, basicse) imout = sp.Image(im_minima_val) sp.basins(im_grad, im_minima_val, imout, basicse) ##----------------------------------------------------------------------------------------- ##----------------------------------------------------------------------------------------- return imout, im_grad, im_minima_val
def demo_m_waterpixels(imin, step, d_weight, filter_ori): """ Compute m-waterpixels, i.e. superpixels based on the watershed transformation. Flooding starts form the best minimum of each cell of a regular grid. The gradient used to be flooded is regularized using the distance function to these minima. Cells of the grid are chosen here to be squares. Input : imin (image UINT8): original image, to be segmented into superpixels step (UINT8) : grid step, i.e. distance between two cell centers of the grid d_weight (UINT8) : constant to be multiplied with function distance before addition to gradient image. If d_weight <=0, then only the gradient is taken into account. filter_ori (BOOLEAN) : do we filter the input image? Output: image (UINT16) : labelled superpixels image (UINT8) : distance weighted gradient function image (UINT16) : minima used in the computation """ ##----------------------------------------------------------------------------------------- ##----------------------------------------------------------------------------------------- # Connexity: basicse = sp.CrossSE() gridse = sp.SquSE() # Ori filtering if filter_ori is True: my_area_filtering(imin, step*step/16) # Gradient computation im_grad = my_gradient(imin, basicse, True) ## Pool of working images: imwrk0 = sp.Image(im_grad) imwrk1 = sp.Image_UINT32(im_grad.getSize()[0], im_grad.getSize()[1]) #imwrk2 = sp.Image(im_grad, "UINT16") imwrk2 = sp.Image_UINT32(im_grad.getSize()[0], im_grad.getSize()[1]) imwrk3 = sp.Image(im_grad, "UINT16") imwrk4 = sp.Image(im_grad, "UINT16") # Compute cell centers and cells size = imin.getSize() im_markers, im_cells = im_labelled_square_grid_points(size, step, step/6) ##----------------------------------------------------------------------------------------- ##----------------------------------------------------------------------------------------- ## Choice of the markers : one per grid cell ##----------------------------------------------------------------------------------------- ##----------------------------------------------------------------------------------------- # Step 1 : Computation of the minima of the gradient im_minima = sp.Image(im_grad) sp.minima(im_grad, im_minima, basicse) #Step 2 : Imposing minimum distance between minima (= Removing minima candidates which fall on cell margins ) sp.test(im_cells, im_minima, 0, imwrk0) sp.label(imwrk0, imwrk1, basicse) #Step 3 : Evaluation of the importance of minima ( = computation of their surfacic extinction) im_minima_val = sp.Image_UINT32(imwrk1) sp.watershedExtinction( im_grad, imwrk1, im_minima_val, "a", basicse) # Step 4 : Taking back at value 2 the minima of null-volumic extinction sp.test( imwrk0, 2, 0, imwrk2) sp.test( im_minima_val, im_minima_val, imwrk2, im_minima_val ) # Step 5 : Coping with the potential absence of minimum in cells (= choosing the minimum value inside this cell as its marker if necessary) imwrk00=sp.Image(imwrk0) blobs = sp.computeBlobs(im_cells) sp.test(im_cells, im_grad, 0, imwrk00) minVals = sp.measMinVals(imwrk00, blobs) sp.applyLookup(im_cells, minVals, imwrk0) sp.test(imwrk00==imwrk0, 1, 0, imwrk1) maxVals = sp.measMaxVals(im_minima_val, blobs) sp.applyLookup(im_cells, maxVals, imwrk2) sp.test(imwrk2, im_minima_val, imwrk1, im_minima_val) # Step 6 : Selection of one marker per cell one_min_per_grid_cell(im_cells, blobs, im_minima_val, basicse) ##----------------------------------------------------------------------------------------- ##----------------------------------------------------------------------------------------- ## Spatial regularization of the gradient ##----------------------------------------------------------------------------------------- ##----------------------------------------------------------------------------------------- #Step 1 : Computation of the distance function to the markers immask = sp.Image(im_markers, "UINT8") sp.test(im_minima_val, 0, 1, immask) imdist = sp.Image(immask, "UINT8") sp.dist(immask, imdist, gridse) #Step 2 : Adding the distance function to the gradient if d_weight > 0: weight = d_weight * float(2)/step if im_grad.getTypeAsString()!=imdist.getTypeAsString(): imdist2 = sp.Image(imdist, "UINT16") sp.copy(imdist, imdist2) sp.mul(imdist2, weight, imdist2) sp.add(imdist2, im_grad, im_grad) else: sp.mul(imdist, weight, imdist) sp.add(imdist, im_grad, im_grad) ##----------------------------------------------------------------------------------------- ##----------------------------------------------------------------------------------------- ## Superpixel segmentation : watershed transformation, flooding from selected minima on the regularized gradient ##----------------------------------------------------------------------------------------- ##----------------------------------------------------------------------------------------- # sp.copy(im_minima_val, imwrk1) # sp.label(imwrk1, im_minima_val, basicse) # imout = sp.Image(im_minima_val) # sp.basins(im_grad, im_minima_val, imout, basicse) sp.copy(im_minima_val, imwrk3) sp.label(imwrk3, imwrk4, basicse) imout = sp.Image(imwrk4) sp.basins(im_grad, imwrk4, imout, basicse) ##----------------------------------------------------------------------------------------- ##----------------------------------------------------------------------------------------- return imout, im_grad, im_minima_val