Re-marking overlapping segments located in adjacent numpy 2-d blocks (no outlines)

I have a numpy 2-d array that I split into several numpy 2-d blocks. All blocks have the same shape. On these blocks, I sedimented the K-mid with the scikit-learn module. The edges of each block overlap (each block has one row / column overlap with an adjacent block). I want the overlapping segments in two adjacent blocks to have the same value. My current code can be downloaded here .

Image of blocks and their position in the original image:

Image blocks

Blocks in python code

blockNW=np.array([[ 0.,  0.,  0.,  0.,  5.],
   [ 0.,  0.,  4.,  5.,  5.],
   [ 0.,  4.,  4.,  5.,  2.],
   [ 0.,  4.,  5.,  5.,  2.],
   [ 5.,  5.,  2.,  2.,  2.]])

blockNE=np.array([[ 1.,  18.,  18.,  18.,  6.],
   [ 1.,  18.,  7.,  6.,  6.],
   [ 3.,  7.,  7.,  7.,  6.],
   [ 3.,  3.,  3.,  7.,  7.],
   [ 3.,  3.,  7.,  7.,  7.]])

blockSW=np.array([[ 8., 8.,  8.,  10.,  10.],
   [ 8.,  8.,  9.,  10.,  10.],
   [ 8.,  8.,  9.,  9.,  10.],
   [ 8.,  8.,  8.,  9.,  10.],
   [ 8.,  8.,  9.,  9.,  11.]])

blockSE=np.array([[ 12., 12.,  12., 12.,  12.],
   [ 12., 12.,  12., 12.,  13.],
   [ 12., 12.,  12.,  13.,  13.],
   [ 12., 12.,  13.,  13.,  13.],
   [ 12., 13.,  13.,  13.,  13.]])

blocksStacked=np.array([blockNW,blockNE,blockSW,blockSE])

I want to connect overlapping segments. For this, I would like to use as few loops as possible, because they slow down the code. My current steps:

import math
import numpy as np
from scipy import ndimage,stats

n_blocks,blocksize = np.shape(blocksStacked)[0],np.shape(blocksStacked)[1]
# shape of original image
out_shp = (8,8)
# horizontal and vertical blocks
horizontal_blocks=math.ceil(out_shp[1]/float(blocksize))
vertical_blocks=math.ceil(out_shp[0]/float(blocksize))
# numpy 2_d array in the shape of the image with an unique ID for each block
blockindex=np.arange(horizontal_blocks*vertical_blocks).reshape(-1,horizontal_blocks)

Lock index

enter image description here

def find_neighbours(values,neighbourslist):
    '''function to find the index of neighbouring blocks'''
    mode=stats.mode(values)
    if mode.count>1:
        values=np.delete(values,np.where(values==mode[0]))
    else:
        values=np.delete(values,np.where(values==np.median(values)))
    neighbourslist.append(values)
    return 0 

#Locate overlapping rows and columns per block
neighbourlist=[]
kernel=np.array([[0,1,0],[1,1,1],[0,1,0]],dtype='uint8')
_ =ndimage.generic_filter(blockindex, find_neighbours, footprint=kernel,extra_arguments=(neighbourlist,))

#output (block 0 has neighbours 1 and 2, etc.):
>>> neighbourlist
[array([ 1.,  2.]), array([ 0.,  3.]), array([ 0.,  3.]), array([ 1.,  2.])]

( , ).

# First I create masks to select overlapping rows or columns:
upmask=np.ones((blocksize,blocksize),dtype=bool)
upmask[1:,:]=0
downmask=np.ones((blocksize,blocksize),dtype=bool)
downmask[:-1,:]=0
rightmask=np.ones((blocksize,blocksize),dtype=bool)
rightmask[:,:-1]=0
leftmask=np.ones((blocksize,blocksize),dtype=bool)
leftmask[:,1:]=0

# Now loop through all blocks and neighbours and select the overlapping rows/columsn
for i in range(n_blocks):
    n_neighbours = len(neighbourlist[i])
    block=blocksStacked[i,:,:]
    for j in range(n_neighbours):
        neighborindex=neighbourlist[i][j]
        block_neighbour=blocksStacked[neighborindex,:,:]
        if i+1==neighborindex:
            blockvals=block[rightmask]
            neighbourvals=block_neighbour[leftmask]
        elif i-1==neighborindex:
            blockvals=block[leftmask]
            neighbourvals=block_neighbour[rightmask]
        elif i+horizontal_blocks==neighborindex:
            blockvals=block[downmask]
            neighbourvals=block_neighbour[upmask]
        elif i-horizontal_blocks==neighborindex:
            blockvals=block[upmask]
            neighbourvals=block_neighbour[downmask]

numpy 1d, . :

>>> blockvals
array([5., 5., 2., 2., 2.])
>>> neighbourvals
array([1., 1., 3., 3., 3.])

, :

blockNW=np.array([[ 0.,  0.,  0.,  0.,  5.],
   [ 0.,  0.,  4.,  5.,  5.],
   [ 0.,  4.,  4.,  5.,  2.],
   [ 0.,  4.,  5.,  5.,  2.],
   [ 5.,  5.,  2.,  2.,  2.]])

blockNE=np.array([[ 5.,  18.,  18.,  18.,  6.],
   [ 5.,  18.,  7.,  6.,  6.],
   [ 2.,  7.,  7.,  7.,  6.],
   [ 2.,  2.,  2.,  7.,  7.],
   [ 2.,  2.,  7.,  7.,  7.]])

, ?

, , ?

:

  • 100%, . , 70%,

:

enter image description here

for-loops :

from scipy.stats import itemfreq

# Locate and re-label overlapping segments
for k in range(len(np.unique(blockvals))):
    #Iterate over each value in the overlapping row/column of the block
    blockval=np.unique(blockvals)[k]
    #count of blockval
    block_val_count=len(blockvals[np.where(blockvals==blockval)])
    #Select values in neighbour on the same location
    overlap=neighbourvals[np.where(blockvals==blockval)]
    overlapfreq=itemfreq(overlap)
    #select neighboring value which overlaps the most
    neighval_overlap_count= np.max(overlapfreq[:,1])
    neighval=overlapfreq[np.where(overlapfreq[:,1]==neighval_overlap_count),0][0]
    # count occurence of selected neighboring value
    neigh_val_count=len(neighbourvals[np.where(neighbourvals==neighval)])
    #If overlap is more than 70% relabel the neigboring value to the value in the block
    thresh=0.7
    if (neighval_overlap_count/float(neigh_val_count)>=thresh) and (neighval_overlap_count/float(block_val_count)>=thresh):   
        blocksStacked[neighborindex,:,:,][np.where(blocksStacked[neighborindex,:,:]==neighval)]=blockval



#output
>>> blocksStacked
array([[[  0.,   0.,   0.,   0.,   5.],
    [  0.,   0.,   4.,   5.,   5.],
    [  0.,   4.,   4.,   5.,   2.],
    [  0.,   4.,   5.,   5.,   2.],
    [  5.,   5.,   2.,   2.,   2.]],

   [[  5.,  18.,  18.,  18.,   6.],
    [  5.,  18.,   7.,   6.,   6.],
    [  2.,   7.,   7.,   7.,   6.],
    [  2.,   2.,   2.,   7.,   7.],
    [  2.,   2.,   7.,   7.,   7.]],

   [[  8.,   8.,   8.,  10.,  10.],
    [  8.,   8.,   9.,  10.,  10.],
    [  8.,   8.,   9.,   9.,  10.],
    [  8.,   8.,   8.,   9.,  10.],
    [  8.,   8.,   9.,   9.,  11.]],

   [[ 10.,  10.,  10.,  10.,  10.],
    [ 10.,  10.,  10.,  10.,  13.],
    [ 10.,  10.,  10.,  13.,  13.],
    [ 10.,  10.,  13.,  13.,  13.],
    [ 10.,  13.,  13.,  13.,  13.]]])
+4

All Articles