HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Finding a zero crossing in a matrix

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
zeromatrixcrossingfinding

Problem

I am trying create an algorithm for finding the zero crossing (check that the signs of all the entries around the entry of interest are not the same) in a two dimensional matrix, as part of implementing the Laplacian of Gaussian edge detection filter for a class, but I feel like I'm fighting against Numpy instead of working with it.

import numpy as np

range_inc = lambda start, end: range(start, end+1)

# Find the zero crossing in the l_o_g image
# Done in the most naive way possible
def z_c_test(l_o_g_image):
    print(l_o_g_image)
    z_c_image = np.zeros(l_o_g_image.shape)
    for i in range(1, l_o_g_image.shape[0] - 1):
        for j in range(1, l_o_g_image.shape[1] - 1):
            neg_count = 0
            pos_count = 0
            for a in range_inc(-1, 1):
                for b in range_inc(-1, 1):
                    if a != 0 and b != 0:
                        print("a ", a, " b ", b)
                        if l_o_g_image[i + a, j + b]  0:
                            pos_count += 1
                            print("pos")
                        else:
                            print("zero")

            # If all the signs around the pixel are the same
            # and they're not all zero
            # then it's not a zero crossing and an edge. 
            # Otherwise, copy it to the edge map.
            z_c = ((neg_count > 0) and (pos_count > 0))

            if z_c:
                print("True for", i, ",", j)
                print("pos ", pos_count, " neg ", neg_count)
                z_c_image[i, j] = 1

    return z_c_image


Here is the test cases it should pass:

```
test1 = np.array([[0,0,1], [0,0,0], [0,0,0]])
test2 = np.array([[0,0,1], [0,0,0], [0,0,-1]])
test3 = np.array([[0,0,0], [0,0,-1], [0,0,0]])
test4 = np.array([[0,0,0], [0,0,0], [0,0,0]])
true_result = np.array([[0,0,0], [0,1,0], [0,0,0]])
false_result = np.array([[0,0,0], [0,0,0], [0,0,0]])

real_result1 = z_c_test(test1)
real_result2 = z_c_test(test2)
real_result3 = z_c_

Solution

Here's concise method to get the coordinates of the zero-crossings that seems to work according to my tests :

def zcr(x, y):
    return x[numpy.diff(numpy.sign(y)) != 0]


Some simple test case :

>>> zcr(numpy.array([0, 1, 2, 3, 4, 5, 6, 7]), [1, 2, 3, -1, -2, 3, 4, -4])
array([2, 4, 6])


This is 2d only, but I believe it is easy to adapt to more dimensions.

Code Snippets

def zcr(x, y):
    return x[numpy.diff(numpy.sign(y)) != 0]
>>> zcr(numpy.array([0, 1, 2, 3, 4, 5, 6, 7]), [1, 2, 3, -1, -2, 3, 4, -4])
array([2, 4, 6])

Context

StackExchange Code Review Q#45458, answer score: 7

Revisions (0)

No revisions yet.