Home > other >  Edge finding with Numpy
Edge finding with Numpy

Time:10-25

Find edges with NumPy 1D search in stencil like b&w image, e.g. img

Not sure how to loop through 1D arrays to create a bool mask properly. Looked through quite a few numpy resources & stack which didn't cover explicitly this kind of basic operation.

Any tips appreciated. Here's the pseudocode.

#Pseudocode for 1D array search.
nrows, ncols = img.shape[:2]
nrows = nrows-1     #avoid index error
ncols = ncols-1

    # i 1 pixel index wanted here
outedges_row = (img[nrows][i] == 0) & (img[nrows][i 1] == 255)  
outedges_col = (img[ncols][i] == 0) & (img[ncols][i 1] == 255)

    # i pixel index wanted here
inedges_row = (img[nrows][i] == 255) & (img[nrows][i 1] == 0)
inedges_col = (img[ncols][i] == 255) & (img[ncols][i 1] == 0)

    # display outline of shapes
edges = np.unique(outedges_row & outedges_col & inedges_col & inedges_row)
img2 = np.copy(img)
img2[edges]
cv.imshow('',img2)

Even a very simple outline of the shape would be very valuable learning for my purposes.

Edit: Expected output enter image description here

CodePudding user response:

An "edge" pixel is characterized by a simple property: it is black and at least one of its neighbors is white (you can choose between the 4- or 8- connected neighbors).

This is fairly simple to implement. On the sides of the image, consider that "outer" pixels are white.

CodePudding user response:

The typical method for edge detection is to take a "derivative" or to convolve with an "edge detection kernel" (e.g. Sobel, Laplacian of Gaussian, ...).

For instance, this gives a very simple horizontal derivative:

# kernel: (-1, 1)
dx = img[:, 1:] - img[:, :-1]

Second order operator:

# kernel: (-1, 2, -1)
dx = -img[:, 2:]   2 * img[:, 1:-1] - img[:, :-2]

...which incidentally creates a map of all the vertical edges.

Since this is for a B&W image, you may follow up with a thresholding operation on the result, e.g. "edge if > 1".


Typical Laplacian of Gaussian kernel:

edge = (
    0 * img[:-2, :-2]    -1 * img[:-2, 1:-1]     0 * img[:-2, 2:]   
   -1 * img[1:-1, :-2]    4 * img[1:-1, 1:-1]   -1 * img[1:-1, 2:]  
    0 * img[2:, :-2]     -1 * img[2:, 1:-1]      0 * img[2:, 2:]  
)

If you're not restricted to linear operators, you can even do stuff like edges = abs(dx) abs(dy)... just be careful of phase shifts.

  • Related