Find edges with NumPy 1D search in stencil like b&w image, e.g.
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
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.