Exemple #1
0
def process_images(img1, img2):
    """
	img1, img2:	input images in Image format

	return:		value representing how much the 2 images
				look similar
	"""

    #	get the size of original the image
    img_dim = img1.getbbox()

    #	invert the bit of the pixels
    img1_inv = ImageChops.invert(img1)
    img2_inv = ImageChops.invert(img2)

    #	get the object from the 2 images
    box1 = img1_inv.getbbox()
    box2 = img2_inv.getbbox()

    #	crop the object from the images
    img1_obj = img1_inv.crop(box1)
    img2_obj = img2_inv.crop(box2)

    #	resize the 2nd image according to the object of the 1st image
    img2_obj = img2_obj.resize((box1[2] - box1[0], box1[3] - box1[1]))

    #	enhance the simplicity of the objects (take an array and return an array)
    obj1_simple = enhance_contrast_percentile(np.array(img1_obj),
                                              disk(3),
                                              p0=.8,
                                              p1=.9)
    obj2_simple = enhance_contrast_percentile(np.array(img2_obj),
                                              disk(3),
                                              p0=.8,
                                              p1=.9)

    #	convert the objects from array to image
    img1_obj = Image.fromarray(obj1_simple)
    img2_obj = Image.fromarray(obj2_simple)

    #	invert the bit of the pixels of the 2nd image
    img2_obj = ImageChops.invert(img2_obj)

    #	generate a new image representing the one inside the other
    img_diff = ImageChops.invert(ImageChops.add_modulo(img1_obj, img2_obj))

    #	resize the new image into the old sizes
    img_diff = img_diff.resize(
        (img_dim[2] - img_dim[0], img_dim[3] - img_dim[1]))

    return np.count_nonzero(np.array(img_diff))
Exemple #2
0
def get_label(img,
              radius=20,
              selemSeg=npy.empty([1]),
              seg=False,
              max_size_th=1000,
              min_size_th=0,
              p0=0.7,
              sigma=None,
              iter=2,
              signal=None):
    '''
    Return the labeled image calculated from a radius disk
    :param img: input image
    :param radius: radius of the object to label
    :param seg: True if the segmented image is return
    :param max_size_th: Threshold on the maximum size
    :param p0: percentile for the segmentation
    :return: Labeled image
    '''
    #radius of the object to segment
    if npy.size(selemSeg) == 1:
        selemSeg = disk(radius)
    if sigma:
        img = filters.gaussian_filter(img, sigma)
    signal.emit({
        "msg": 'Segmentation:enhance constrast',
        "value": 0,
        "max": 100
    })
    img = rank.enhance_contrast_percentile(img, disk(3), p0=0.5, p1=1)
    signal.emit({"msg": 'Segmentation:threshold', "value": 16})
    Seg = rank.threshold_percentile(img, selemSeg, p0=p0)
    signal.emit({"msg": 'Segmentation:morphology', "value": 2 * 16})
    Seg = morphology.binary_fill_holes(Seg)
    Seg = morphology.binary_erosion(Seg, iterations=iter)
    Seg = morphology.binary_dilation(Seg, iterations=iter)
    Seg = morphology.binary_fill_holes(Seg)

    signal.emit({"msg": 'Segmentation:label', "value": 3 * 16})
    labels, nr_objects = mh.label(Seg)
    #too big
    signal.emit({"msg": 'Segmentation:delete big', "value": 4 * 16})
    sizes = mh.labeled.labeled_size(labels)
    too_big = npy.where(sizes > max_size_th)
    labels = mh.labeled.remove_regions(labels, too_big)

    #too small
    signal.emit({"msg": 'Segmentation:delete small', "value": 5 * 16})
    sizes = mh.labeled.labeled_size(labels)
    too_small = npy.where(sizes < min_size_th)
    labels = mh.labeled.remove_regions(labels, too_small)
    signal.emit({"msg": 'Segmentation finish', "value": 100})
    if seg:
        return labels, Seg
    return labels
        def check_all():
            selem = morphology.disk(1)
            refs = np.load(
                os.path.join(skimage.data_dir, "rank_filter_tests.npz"))

            assert_equal(refs["autolevel"], rank.autolevel(self.image, selem))
            assert_equal(refs["autolevel_percentile"],
                         rank.autolevel_percentile(self.image, selem))
            assert_equal(refs["bottomhat"], rank.bottomhat(self.image, selem))
            assert_equal(refs["equalize"], rank.equalize(self.image, selem))
            assert_equal(refs["gradient"], rank.gradient(self.image, selem))
            assert_equal(refs["gradient_percentile"],
                         rank.gradient_percentile(self.image, selem))
            assert_equal(refs["maximum"], rank.maximum(self.image, selem))
            assert_equal(refs["mean"], rank.mean(self.image, selem))
            assert_equal(refs["geometric_mean"],
                         rank.geometric_mean(self.image, selem)),
            assert_equal(refs["mean_percentile"],
                         rank.mean_percentile(self.image, selem))
            assert_equal(refs["mean_bilateral"],
                         rank.mean_bilateral(self.image, selem))
            assert_equal(refs["subtract_mean"],
                         rank.subtract_mean(self.image, selem))
            assert_equal(refs["subtract_mean_percentile"],
                         rank.subtract_mean_percentile(self.image, selem))
            assert_equal(refs["median"], rank.median(self.image, selem))
            assert_equal(refs["minimum"], rank.minimum(self.image, selem))
            assert_equal(refs["modal"], rank.modal(self.image, selem))
            assert_equal(refs["enhance_contrast"],
                         rank.enhance_contrast(self.image, selem))
            assert_equal(refs["enhance_contrast_percentile"],
                         rank.enhance_contrast_percentile(self.image, selem))
            assert_equal(refs["pop"], rank.pop(self.image, selem))
            assert_equal(refs["pop_percentile"],
                         rank.pop_percentile(self.image, selem))
            assert_equal(refs["pop_bilateral"],
                         rank.pop_bilateral(self.image, selem))
            assert_equal(refs["sum"], rank.sum(self.image, selem))
            assert_equal(refs["sum_bilateral"],
                         rank.sum_bilateral(self.image, selem))
            assert_equal(refs["sum_percentile"],
                         rank.sum_percentile(self.image, selem))
            assert_equal(refs["threshold"], rank.threshold(self.image, selem))
            assert_equal(refs["threshold_percentile"],
                         rank.threshold_percentile(self.image, selem))
            assert_equal(refs["tophat"], rank.tophat(self.image, selem))
            assert_equal(refs["noise_filter"],
                         rank.noise_filter(self.image, selem))
            assert_equal(refs["entropy"], rank.entropy(self.image, selem))
            assert_equal(refs["otsu"], rank.otsu(self.image, selem))
            assert_equal(refs["percentile"],
                         rank.percentile(self.image, selem))
            assert_equal(refs["windowed_histogram"],
                         rank.windowed_histogram(self.image, selem))
def threshold_with_enhance(im, ker_ksize=20, p0=0.1, p1=.45):
    """

    Args:
        im: fingerprint image
        ker_ksize: disk kernel size
        p0: first parameter
        p1: second parameter

    Use  enhance contrast percentile for getting binary inv
    Returns: binary fingeprint image

    """
    disk_ker = disk(ker_ksize)
    enh_im = enhance_contrast_percentile(im, disk_ker, p0=p0, p1=p1)
    thresh = cv.threshold(enh_im, 0, 255, cv.THRESH_BINARY)[1]

    return thresh
def check_all():
    np.random.seed(0)
    image = np.random.rand(25, 25)
    selem = morphology.disk(1)
    refs = np.load(os.path.join(skimage.data_dir, "rank_filter_tests.npz"))

    assert_equal(refs["autolevel"], rank.autolevel(image, selem))
    assert_equal(refs["autolevel_percentile"], rank.autolevel_percentile(image, selem))
    assert_equal(refs["bottomhat"], rank.bottomhat(image, selem))
    assert_equal(refs["equalize"], rank.equalize(image, selem))
    assert_equal(refs["gradient"], rank.gradient(image, selem))
    assert_equal(refs["gradient_percentile"], rank.gradient_percentile(image, selem))
    assert_equal(refs["maximum"], rank.maximum(image, selem))
    assert_equal(refs["mean"], rank.mean(image, selem))
    assert_equal(refs["mean_percentile"], rank.mean_percentile(image, selem))
    assert_equal(refs["mean_bilateral"], rank.mean_bilateral(image, selem))
    assert_equal(refs["subtract_mean"], rank.subtract_mean(image, selem))
    assert_equal(refs["subtract_mean_percentile"], rank.subtract_mean_percentile(image, selem))
    assert_equal(refs["median"], rank.median(image, selem))
    assert_equal(refs["minimum"], rank.minimum(image, selem))
    assert_equal(refs["modal"], rank.modal(image, selem))
    assert_equal(refs["enhance_contrast"], rank.enhance_contrast(image, selem))
    assert_equal(refs["enhance_contrast_percentile"], rank.enhance_contrast_percentile(image, selem))
    assert_equal(refs["pop"], rank.pop(image, selem))
    assert_equal(refs["pop_percentile"], rank.pop_percentile(image, selem))
    assert_equal(refs["pop_bilateral"], rank.pop_bilateral(image, selem))
    assert_equal(refs["sum"], rank.sum(image, selem))
    assert_equal(refs["sum_bilateral"], rank.sum_bilateral(image, selem))
    assert_equal(refs["sum_percentile"], rank.sum_percentile(image, selem))
    assert_equal(refs["threshold"], rank.threshold(image, selem))
    assert_equal(refs["threshold_percentile"], rank.threshold_percentile(image, selem))
    assert_equal(refs["tophat"], rank.tophat(image, selem))
    assert_equal(refs["noise_filter"], rank.noise_filter(image, selem))
    assert_equal(refs["entropy"], rank.entropy(image, selem))
    assert_equal(refs["otsu"], rank.otsu(image, selem))
    assert_equal(refs["percentile"], rank.percentile(image, selem))
    assert_equal(refs["windowed_histogram"], rank.windowed_histogram(image, selem))
ax3.axis('off')
ax3.set_adjustable('box-forced')

ax4.imshow(enh[200:350, 350:450], cmap=plt.cm.gray)
ax4.axis('off')
ax4.set_adjustable('box-forced')

######################################################################
# The percentile version of the local morphological contrast enhancement uses
# percentile *p0* and *p1* instead of the local minimum and maximum.

from skimage.filters.rank import enhance_contrast_percentile

noisy_image = img_as_ubyte(data.camera())

penh = enhance_contrast_percentile(noisy_image, disk(5), p0=.1, p1=.9)

fig, ax = plt.subplots(2, 2, figsize=[10, 7], sharex='row', sharey='row')
ax1, ax2, ax3, ax4 = ax.ravel()

ax1.imshow(noisy_image, cmap=plt.cm.gray)
ax1.set_title('Original')

ax2.imshow(penh, cmap=plt.cm.gray)
ax2.set_title('Local percentile morphological\n contrast enhancement')

ax3.imshow(noisy_image[200:350, 350:450], cmap=plt.cm.gray)

ax4.imshow(penh[200:350, 350:450], cmap=plt.cm.gray)

for ax in ax.ravel():
def mac_det(fi, mp_threshold, patch_threshold, percb, percc, tcr, ds,px, plot=True, morph=False, testing=True):
    """
    Function for detecting macropores (cracks & biopores) to analyse their spatial arrangement & 
    matrix interaction
    
    Line 133:162 are adapted from the preprocessor of the echoRD-model by C. Jackisch. 
    For further informations see: https://github.com/cojacoo/echoRD_model/tree/master/echoRD
    file "macropore_ini.py"
    
    Parameters
    ----------
    fi : input image ( in .png-format, either as rgb or rgba image)
    mp_threshold : lower limit[0] for removing small patches, 
        upper limit [1] for seperating cracks from other objects
    patch_threshold : min [0] and max [1] of the desired patch size limits
    percb : value up to which percentile grey values among to biopores 
        (0.125 shows good results for brighter soil matrix)
    percc : lower [0] & upper [1] percentile for crack contrast enhancement
    tcr : value up to which percentile grey values among to cracks
    ds : disk size for morphological opening
    px : actual length of one pixel in input image [mm]
    plot : True/False: whether results should be plotted (default: True)
    morph : if True the morphology of detected biopores will be plotted, otherwise pores are displayed as 
            scatterplot and distinguished whether stained or not (default: False)
    testing = if True no distances are calculated and only the detected macropores are plotted to reduce 
        computing time threshold adjustment (default), otherwise all distances are computed
    
    Output
    ------
    Dictionary with following keys:
    'biopores' : labeled biopores
    'biopores_centroidxy' : x/y-coordinates of detected biopores
    'biopores_stained_centroidxy' : x/y-coordinates of detected stained biopores
    'biopores_area' : area of detected biopores (number of pixels)
    'biopores_diameter' : diameter of detected biopores (diameter of circle with same area [mm])
    'cracks' : labeled cracks
    'distance_matrix_biopore' : distance of each image pixel to nearest biopore [mm]
    'distance_matrix_stained_biopore' : distance of each image to nearest stained biopore [mm]
    'biopore_matrix_interaction' : distance of pixels from stained patches including at least one 
               biopore to nearest stained biopore [mm] (estimation of biopore-matrix interaction)
    'stained_patches' : labeled blue-stained patches
    'patches_with_biopores' : detected blue-stained patches including at least one biopore
    'table' : summary table with number and main propertiesd of detected biopores
    'stained_index' : index of stained biopores
    'unstained_index' : index of unstained biopores
    
    """
    
    im_raw = snd.imread(fi)   # load image   
    sim = np.shape(im_raw)
    if sim[2]==4:
        imrgb=im_raw[:,:,:3]
    else:
        imrgb=im_raw
    imhsv = rgb2hsv(imrgb)   # convert RGB image to HSV color-space
    img = imhsv[:,:,2]       # extract value channel
    im = img_as_float(imrgb) # load image as float for detection of stained patches
    sim = np.shape(im)       # extract dimensions of input image
    
    
    # biopore detection
    # morphological reconstruction for detecting holes inside the picture (according to general example 
    # "filling holes and detecting peaks" from scikit-image)
    seed = np.copy(img)
    seed[1:-1, 1:-1] = img.max()
    mask = img

    filled = reconstruction(seed, mask, method='erosion')
    holes=img-filled
    
    # rescale and extract biopores
    holes_resc=rescale_intensity(holes,out_range=(0.0,1))

    thresh=np.percentile(holes_resc,percb)
    holes_resc[holes_resc>thresh]=1 
    holes_resc[holes_resc<thresh]=0

    bp_lab=label(holes_resc,neighbors=8, background=1)
    bp_lab[bp_lab==-1]=0

    # remove objects smaller than threshold
    bp_lab_clean = morphology.remove_small_objects(bp_lab, min_size=mp_threshold[0])
    
    
    # crack detection
    # enhance contrast for dark spots
    cr_ecp=enhance_contrast_percentile(img, disk(3), p0=percc[0], p1=percc[1])
    threshcr=np.percentile(cr_ecp,tcr)
    cr_ecp[cr_ecp>threshcr]=255 
    cr_ecp[cr_ecp<threshcr]=1

    # morphological opening for bridging small gaps and remove small white pixels
    cr_ecpo=opening(cr_ecp, disk(ds))
    cr_lab=label(cr_ecpo,neighbors=8, background=255)
    cr_lab[cr_lab==-1]=0

    # remove objects smaller than threshold
    cr_label = morphology.remove_small_objects(cr_lab, min_size=mp_threshold[1])
    
    # remove biopores inside labeled cracks
    bp_label=bp_lab_clean-cr_label.dot(100)
    bp_label[bp_label<0]=0
    
    
    # detect and label blue stained patches
    # calculate difference of channels to extract blue stained patches
    dim=abs(im[:,:,1]-im[:,:,0])
    
    # discard low contrasts
    dim[dim<0.2]=0.0

    # filter to local maxima for further segmentation
    # process segmentation according to sobel function of skimage
    image_max = snd.maximum_filter(dim, size=5, mode='constant')

    elevation_map = sobel(dim)

    markers = np.zeros_like(dim)
    markers[image_max < 0.1] = 2
    markers[image_max > 0.2] = 1

    segmentation = morphology.watershed(elevation_map, markers)

    segmentation = snd.binary_fill_holes(1-(segmentation-1))

    # clean patches below theshold
    patches_cleaned = morphology.remove_small_objects(segmentation, patch_threshold[0])
    labeled_patches = label(patches_cleaned)
    sizes = np.bincount(labeled_patches.ravel())[1:] #first entry (background) discarded

    # reanalyse for large patches and break them by means of watershed segmentation
    idx=np.where(sizes>patch_threshold[1])[0]+1
    labeled_patches_large=labeled_patches*0
    idy=np.in1d(labeled_patches,idx).reshape(np.shape(labeled_patches))
    labeled_patches_large[idy]=labeled_patches[idy]
    distance = snd.distance_transform_edt(labeled_patches_large)
    footp=int(np.round(np.sqrt(patch_threshold[1])/100)*100)
    local_maxi = peak_local_max(distance, indices=False, footprint=np.ones((footp, footp)),labels=labeled_patches_large)
    markers = snd.label(local_maxi)[0]
    labels_broken_large = morphology.watershed(-distance, markers, mask=labeled_patches_large)
    labeled_patches[idy]=labels_broken_large[idy]+np.max(labeled_patches)
    
    
    # measure regionproperties of biopores
    meas_bp=measure.regionprops(bp_label, intensity_image=None)

    bp_labels = np.unique(bp_label)[1:]
    
    bp_centroidx = bp_labels.astype(np.float64)
    bp_centroidy = bp_labels.astype(np.float64)
    bp_area = bp_labels.astype(np.float64)
    bp_diameter = bp_labels.astype(np.float64)
    
    # extract regionprops for each labeled biopore
    for i in np.arange(len(bp_labels)):
        bp_centroidx[i], bp_centroidy[i]=meas_bp[i]['centroid']
        bp_area[i]=meas_bp[i]['area']*px
        bp_diameter[i]=meas_bp[i]['equivalent_diameter']*px
        
    bp_centroidxy = np.stack((bp_centroidx,bp_centroidy), axis=-1)
    
    
    # extract biopores inside stained areas = "stained biopores"
    stain_info=np.zeros(len(bp_centroidxy))
    rbp_centroidxy=np.around(bp_centroidxy).astype(int)

    for i in np.arange(len(bp_centroidxy)):
        if labeled_patches[rbp_centroidxy[i,0],rbp_centroidxy[i,1]]>0:
            stain_info[i]=1
        else:
            stain_info[i]=2
    
    stained=np.where(stain_info==1)
    unstained=np.where(stain_info==2)
    
    # select value of stained patches including an biopore
    bp_stained=np.around(bp_centroidxy[stained]).astype(int)
    label_value=np.zeros(len(bp_stained)).astype(int)

    for i in np.arange(len(bp_stained)):
        label_value[i]=labeled_patches[bp_stained[i,0], bp_stained[i,1]]
    
    # remove labeled patches without any biopore
    label_withbp=np.copy(labeled_patches)

    for i in np.arange(len(label_value)):
        label_withbp[label_withbp==label_value[i]]=-1

    label_withbp[label_withbp!=-1]=0
    label_withbp[label_withbp==-1]=1
    
    
    # distance calculations
    if testing==False:
        # Compute Euclidian distance for each pixel to nearest biopore
        m_bp_dist = np.zeros((sim[0],sim[1]))

        for i in np.arange(sim[0]):
            for j in np.arange(sim[1]):
                matrixp1=[i,j]
                m_bp_dist[i,j]=spatial.KDTree(bp_centroidxy).query(matrixp1,p=2)[0]
    
        # compute Euclidian distance for each pixel to nearest stained biopore
        m_stbp_dist=np.zeros((sim[0],sim[1]))

        for i in np.arange(sim[0]):
            for j in np.arange(sim[1]):
                matrixp1=[i,j]
                m_stbp_dist[i,j]=spatial.KDTree(bp_centroidxy[stained]).query(matrixp1,p=2)[0]
    
        # compute Euclidian distance to nearest stained biopore for each pixel of stained areas including a biopore ~ biopore-matrix interaction
        stp_stbp_dist = np.zeros((sim[0],sim[1]))

        for i in np.arange(sim[0]):
            for j in np.arange(sim[1]):
                if label_withbp[i,j]!=0:
                    matrixp3=[i,j]
                    stp_stbp_dist[i,j,]=spatial.KDTree(bp_centroidxy[stained]).query(matrixp3,p=2)[0]
            
                else:
                    stp_stbp_dist[i,j]=np.nan
    
    # table for output
    sbp_diameter=bp_diameter[stained]
            
    t1='All biopores','Stained biopores','Cracks'
    t2=len(bp_diameter),len(sbp_diameter), len(np.unique(cr_label)[1:])
    t3 = len(bp_diameter[bp_diameter<2]),len(sbp_diameter[sbp_diameter<2]),np.nan
    t4 = len(bp_diameter[bp_diameter>=6]),len(sbp_diameter[sbp_diameter>=6]),np.nan
    t5 =len(bp_diameter[bp_diameter>=2]),len(sbp_diameter[sbp_diameter>=2]),np.nan

    attr=[t1,t2,t3,np.subtract(t5,t4),t4]
    mc_t=Table(attr,names=('Properties','Sum','<2mm','2-6mm','>6mm'),meta=None)
    
    
    # plot results
    if plot==True:
        #colors for plot
        from matplotlib.colors import ListedColormap
        ghostwhite=(248/255,248/255,255/255)
        blue=(31/255,119/255,180/255)
        cmap=ListedColormap([ghostwhite, blue])

        if testing==False:  
            # flatten arrays for kernel density estimate plot
            m_bp_distall = np.ravel(m_bp_dist*px)
            m_stbp_distall = np.ravel(m_stbp_dist*px)
            stp_stbp_distall = np.ravel(stp_stbp_dist*px)

            #plot
            sns.set_style('white')
            plt.figure(figsize=(15,3))
            ax1=plt.subplot(141)
            plt.imshow(imrgb)
            plt.axis('off')
            plt.title('Input image')
        
            plt.subplot(142, sharex=ax1, sharey=ax1)
            plt.imshow(labeled_patches, vmin=0, vmax=1, cmap=cmap)
            plt.imshow(imrgb, alpha=0.5)
            if morph==True:
                plt.imshow(bp_label, vmin=0, vmax=1,cmap='binary', alpha=0.5)
            else:
                plt.scatter(bp_centroidxy[unstained][:,1],bp_centroidxy[unstained][:,0] ,color='black', s=10,label='unstained')
                plt.scatter(bp_centroidxy[stained][:,1], bp_centroidxy[stained][:,0] ,color='red', s=15, label='stained')
                plt.legend(bbox_to_anchor=[1,0], ncol=2)
            plt.axis('off')
            plt.title('Labeled patches & Biopores')
     
            plt.subplot(143, sharex=ax1, sharey=ax1)
            plt.imshow(cr_label,vmin=0, vmax=1,cmap='binary')
            plt.imshow(labeled_patches, vmin=0, vmax=1,cmap=cmap, alpha=0.5)
            plt.imshow(imrgb, alpha=0.2)
            plt.axis('off')
            plt.title('Labeled patches & Cracks')
        
            plt.subplot(144)
            sns.kdeplot(m_bp_distall, cut=0, label='All pores')
            if len(stained[0])>0:
                sns.kdeplot(m_stbp_distall, cut=0, label='Stained pores' ,alpha=0.5)
                sns.kdeplot(stp_stbp_distall[~np.isnan(stp_stbp_distall)], cut=0, label='Biopore-matrix interaction' ,alpha=0.5)
            plt.title('Frequency distribution of calculated distances')
        
            plt.show()
        
            print(mc_t)
        else:
            #plot
            sns.set_style('white')
            plt.figure(figsize=(15,4))
            ax1=plt.subplot(131)
            plt.imshow(imrgb)
            plt.axis('off')
            plt.title('Input image')
        
            plt.subplot(132, sharex=ax1, sharey=ax1)
            plt.imshow(labeled_patches, vmin=0, vmax=1, cmap=cmap)
            plt.imshow(imrgb, alpha=0.5)
            if morph==True:
                plt.imshow(bp_label, vmin=0, vmax=1,cmap='binary', alpha=0.5)
            else:
                plt.scatter(bp_centroidxy[unstained][:,1],bp_centroidxy[unstained][:,0] ,color='black', s=10,label='unstained')
                plt.scatter(bp_centroidxy[stained][:,1], bp_centroidxy[stained][:,0] ,color='red', s=15, label='stained')
                plt.legend(bbox_to_anchor=[1,0], ncol=2)
            plt.axis('off')
            plt.title('Labeled patches & Biopores')
     
            plt.subplot(133, sharex=ax1, sharey=ax1)
            plt.imshow(cr_label,vmin=0, vmax=1,cmap='binary')
            plt.imshow(labeled_patches, vmin=0, vmax=1,cmap=cmap, alpha=0.5)
            plt.imshow(imrgb, alpha=0.2)
            plt.axis('off')
            plt.title('Labeled patches & Cracks')
        
            plt.show()
        
            print(mc_t)
    
    
    # results for output
    mc_res={}
    mc_res['biopores'],mc_res['cracks'], mc_res['stained_patches'],mc_res['patches_with_biopores']=bp_label, cr_label, labeled_patches, label_withbp
    mc_res['biopores_centroidxy'], mc_res['biopores_stained_centroidxy']=bp_centroidxy, bp_centroidxy[stained]
    mc_res['biopores_area'], mc_res['biopores_diameter']=bp_area, bp_diameter
    if testing==False:
        mc_res['distance_matrix_biopore'], mc_res['distance_matrix_stained_biopore'], mc_res['biopore_matrix_interaction']=m_bp_dist*px, m_stbp_dist*px, stp_stbp_dist*px
    mc_res['table']=mc_t
    mc_res['stained_index'], mc_res['unstained_index']=stained, unstained
    
    return mc_res