1

I basically have multiple binary images, each containing one connected component. These connected components were retrieved from an image, meaning that if all connected components were to be drawn into a single image file, there would be no empty spaces, and no overlapping connected components. I am looking for a fast way to extract the edge pixels from the connected components. The connected components are currently saved in a single image, where a number i at position (x,y) corresponds to the i-th connected component. Since there are a lot of connected components with the maximum number i beeing in the range of 400-2000, i am looking for a fast way to get the edge pixels of each component. Here is an image to illustrate what i expect from the algorithm: Example

I am aware that there are a few edge detection algorithms, but they deal with grayscale images and won't be any good for small objects in big images at a big amount of images. Any suggestions?

S. Wenzel
  • 81
  • 5

1 Answers1

1

This can be solved using morphological operations and minimum/maximum filters more specifically. The speed should be acceptable since the whole image needs to be processed only twice, irrespective of the number of components.

The biggest part of the following code is just for generating an example image. The relevant lines for obtaining the borders are indicated below:

# imports
import numpy as np
import scipy as sp
import scipy.ndimage

# size of test image
L=50    
# number of components
I=20    
# auxiliary array
array=np.zeros((I,L,L))

# for each component
for i in range(I):

    # draw random coordinates
    x,y=sp.random.randint(0,L,size=2)

    # set coordinate in auxiliary array to index of i-th component
    array[i,x,y]=i

    # create 'box' around coordinate
    array[i]=sp.ndimage.maximum_filter(array[i],size=20)

# create actual test image from auxiliary array
image=np.nanmax(array,axis=0)

# RELEVANT LINES: check if pixel belongs to border
imax=(sp.ndimage.maximum_filter(image,size=3)!=image)
imin=(sp.ndimage.minimum_filter(image,size=3)!=image)
icomb=np.logical_or(imax,imin)

# keep only pixels of original image at borders
edges=np.where(icomb,image,np.nan)

David
  • 1,909
  • 1
  • 20
  • 32