def __call__(self, im): im_size = im.getSize() _ , im_morphm = ws.im_labelled_square_grid_points_v2( im_size, self._params["size"], 0) imout_smil = sp.Image("UINT16", im_size[0], im_size[1], im_size[2]) sp.copy(sp.MorphmInt(im_morphm), imout_smil) self.update_cache(im, imout_smil) return self._cache_seg
def __call__(self, imIn0): imIn = sp.Image(imIn0.getSize()[0]+2, imIn0.getSize()[1]+2) sp.copy(imIn0, imIn, 1, 1) # cette étape sert pour pouvoir éroder les pixels qui touchent le bord. se = uf.set_structuring_element(self._neighborhood, 1) im_bin = sp.Image(imIn) sp.test(imIn, 1, 0, im_bin) imwrk1= sp.Image(im_bin) # interior zone imwrk2 = sp.Image(im_bin) # contour zone (inside SP) sp.erode(im_bin, imwrk1, se) sp.sub(im_bin, imwrk1, imwrk2) sp.test(imwrk1, imIn, 0, imwrk1) sp.test(imwrk2, imIn, 0, imwrk2) histo1 = sp.histogram(imwrk1, im_bin) histo2 = sp.histogram(imwrk2, im_bin) list1 = uf.from_histogram_to_list(histo1, True) list2 = uf.from_histogram_to_list(histo2, True) #pdb.set_trace() print "list1: ", len(list1) print "list2: ", len(list2) if len(list2)==0 or len(list1)==0: imwrk1.showLabel() imwrk2.showLabel() #pdb.set_trace() return None else: return np.abs(np.std(list1) - np.std(list2))
def geodesicTopHatInv(imIn, se_neigh, se_size): imIn2 = sp.Image(imIn) sp.copy(imIn, imIn2) sp.inv(imIn2, imIn2) sp.test(imIn, imIn2, 0, imIn2) imOut = sp.Image(imIn) imwrk = geodesicOpening(imIn2, se_neigh, se_size) sp.sub(imIn2, imwrk, imOut) return imOut
def geodesicDilation(imIn, se_neigh, se_size): se = uf.set_structuring_element(se_neigh, 1) imOut = sp.Image(imIn) sp.copy(imIn, imOut) imwrk = sp.Image(imOut) for i in range(se_size): sp.dilate(imOut, imwrk, se) sp.test(imIn, imwrk, 0 , imOut ) return imOut
def geodesicErosion(imIn, se_neigh, se_size): se = uf.set_structuring_element(se_neigh, 1) imOut = sp.Image(imIn) sp.copy(imIn, imOut) imwrk = sp.Image(imOut) maxval = sp.maxVal(imIn) for _ in range(se_size): sp.test(imOut, imOut, maxval, imwrk) sp.erode(imwrk, imOut, se) sp.test(imIn, imOut, 0 , imOut ) return imOut
def image_enlargement(original_image, window_size, substitution_value=0): """ This function enables to create a enlarged image containing at its center the original image and filling the new boarders with a substitution value. Inputs: - original_image: original image (smil) - window_size (int): number of pixels (depth) to be added on the boarders of the original_image - substitution_value: how to fill the pixels added on the boarders (0 by default) Output: - enlarged_image: image of size [original_image.getSize()[0]+2*window_size, original_image.getSize()[1]+2*window_size] """ enlarged_image = sp.Image(original_image.getSize()[0]+2*window_size, original_image.getSize()[1]+2*window_size) sp.fill(enlarged_image, 0) sp.copy(original_image, enlarged_image, window_size, window_size) return enlarged_image
def __call__(self, im): if self.check_cache(im) is False: arrIn = np.zeros(( im.getSize()[0], im.getSize()[1], 3 )) if im.getTypeAsString()=="RGB": image_slices = sp.Image() sp.splitChannels(im, image_slices) for i in range(3): arrtmp = image_slices.getSlice(i) arrIn[:, :, i] = arrtmp.getNumArray() else: for i in range(3): arrIn[:, :, i] = im.getNumArray() region_labels = slic(np.uint8(arrIn), self._params["nb_regions"], self._params["m"]) imout = sp.Image(region_labels.shape[0], region_labels.shape[1]) arrOut = imout.getNumArray() for i in range(region_labels.shape[0]): for j in range(region_labels.shape[1]): arrOut[i, j] = region_labels[i, j] ## copie16 = sp.Image(imout, "UINT16") sp.copy(imout, copie16) self.update_cache(im, copie16) return self._cache_seg
def visu_TFPN(im_pred, im_GT): """ Enables to see the: - true positives in green - true negatives in white - false positives in red - false negatives in blue """ dic_color={'TP': [0, 255, 0], 'TN': [255, 255, 255], 'FP': [255, 0, 0], 'FN': [0, 0, 255] } sp.test(im_pred, 1, 0, im_pred) sp.test(im_GT, 1, 0, im_GT) imtmp = sp.Image(im_GT) iminv = sp.Image(im_GT) imTP = sp.Image(im_GT) imFN = sp.Image(im_GT) imTN = sp.Image(im_GT) imFP = sp.Image(im_GT) sp.test(im_pred == im_GT, 1, 0, imtmp) sp.test(im_pred == im_GT, 0, 1, iminv) sp.test(im_pred>0, imtmp, 0, imTP) sp.test(im_pred<1, iminv, 0, imFN) sp.test(im_GT<1, imtmp, 0, imTN) sp.test(im_GT<1, iminv, 0, imFP) imR = sp.Image(im_GT) imG = sp.Image(im_GT) imB = sp.Image(im_GT) sp.test(imTP, dic_color['TP'][0], 0, imR) sp.test(imTP, dic_color['TP'][1], 0, imG) sp.test(imTP, dic_color['TP'][2], 0, imB) sp.test(imFN, dic_color['FN'][0], imR, imR) sp.test(imFN, dic_color['FN'][1], imG, imG) sp.test(imFN, dic_color['FN'][2], imB, imB) sp.test(imTN, dic_color['TN'][0], imR, imR) sp.test(imTN, dic_color['TN'][1], imG, imG) sp.test(imTN, dic_color['TN'][2], imB, imB) sp.test(imFP, dic_color['FP'][0], imR, imR) sp.test(imFP, dic_color['FP'][1], imG, imG) sp.test(imFP, dic_color['FP'][2], imB, imB) imOut = sp.Image(imR, 'RGB') im_slices = sp.Image() sp.splitChannels(imOut, im_slices) sp.copy(imR, im_slices.getSlice(0)) sp.copy(imG, im_slices.getSlice(1)) sp.copy(imB, im_slices.getSlice(2)) sp.mergeChannels(im_slices, imOut) return imOut
def __call__(self, imIn, imOut): sp.copy(imIn, imOut) return
def __call__(self, imIn, imOut): imtmp = sp.Image(imOut) sp.copy(imIn, imtmp) apply_uniform_filter(imtmp, imOut, self._params["window_size"]) return
def __call__(self, imIn, imOut): imIn2 = sp.Image(imIn) sp.copy(imIn, imIn2) sp.inv(imIn2, imIn2) sp.topHat(imIn2, imOut, self._se) return
def copy_image(im): imOut = Image(im) smil.copy(im, imOut) return imOut
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
import smilPython as sp im = sp.Image("cells.png") imDist = sp.Image(im) imMask = sp.Image(im) imMark = sp.Image(im) imGeoDist = sp.Image(im) # create a marker image, the same as the original image except at # some point inside the "true" region, which is set to "0" nl = sp.HexSE() sp.distance(im, imDist, nl) sp.compare(imDist, "==", sp.maxVal(imDist), 0, im, imMark) # use the original image as the mask. sp.copy(im, imMask) sp.distanceGeodesic(imMark, imMask, imGeoDist, nl) imGeoDist.show() sp.maxVal(imGeoDist)
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