1

Through some help here, I have come up with a function that seems to apply the sobel derivative to an image in the X direction F(x,y) = F(x+1,y) - F(x,y) I can't use any OpenCV functions and I need the 2D output array to be 1 column shorter than the 2D input array.

However, I can't figure out why this is still not returning an output array that is 1 column shorter. Can someone spot the issue and/or tell me if this is on the right track? Thanks much.

output = input[:-1,:]

r,c = input.shape

for i in range(0, r - 1):
    output[i] = np.abs(input[i+1] - input[i])

return output
yodish
  • 733
  • 2
  • 10
  • 28

2 Answers2

1

You can use numpy's diff() function. See its doc here.

And a code snippet to illustrate its use:

import numpy as np
a = np.ones([5, 4])
b = np.diff(a, axis=1)

the result b is a (5, 3) array full of zeros.

If you want to keep your loop, you can do:

r,c = input.shape
output = np.zeros([r-1, c])

for i in range(0, r - 1):
    output[i] = np.abs(input[i+1] - input[i])

print output

Edit: 'mathematical' x corresponds to the second axis (vertical), and y to the first axis (horizontal). So to obtain F(x+1, y) - F(x, y), you must do:

r,c = input.shape
output = np.zeros([r, c -1])

for j in range(0, c - 1):
    output[:, j] = np.abs(input[:, j+1] - input[:, j])

print output
P. Camilleri
  • 12,664
  • 7
  • 41
  • 76
  • M. Massias, I appreciate the help but I need to stick to this simple looping, for now. – yodish Sep 18 '15 at 12:19
  • @yodish In your unit test, the [1] shapes should be equal (same number of columns), and the [0] shapes must be 1 away (1 less line for output), right ? You are not asserting that. – P. Camilleri Sep 18 '15 at 12:28
  • M. Massias, Thank you, I will try that out as soon as I can, hopefully that a solves this issue. I also need to create a function that applies the sobel derivative in the Y direction `F(x,y) = F(x,y+1) - F(x,y)`, (subtracting rows) you wouldn't happen to have an idea how to loop through and do this, would you? – yodish Sep 18 '15 at 12:29
  • M. Massias, I need to create 2 functions (which i've layed out) and I've been provided 2 unit tests. I'm thinking I may have them switched. – yodish Sep 18 '15 at 12:30
  • Yes, I think you did. You want to keep the same number of columns, and you are not asserting that. – P. Camilleri Sep 18 '15 at 12:31
  • Going in the X direction (subtracting columns) I do want [1] to be one less column for output, since the calculation cannot be performed on the last column. That much I know. Going in the Y direction (subtracting rows), the [0] should be one less row for the output (for the same reason). – yodish Sep 18 '15 at 12:40
  • @yodish I've eddited my post, careful with the confusion between the order of axes in math and in np. – P. Camilleri Sep 18 '15 at 12:54
  • I've had (x,y) drilled into me over the years and i'm now senile and confused. I appreciate the help M. Massias. – yodish Sep 18 '15 at 12:56
  • Thank you for the second example as well! – yodish Sep 18 '15 at 13:02
0

I'm not sure if you mean to create the output array like that. You're creating output as a reference to a subarray of input, so if you modify input you also modify output or vice versa. See:

Numpy array assignment with copy

That said, running the code snippet you provided with input = np.ones([5,5]), and printing output.shape after the return, I get (4,5), which seems to be what you want?

Community
  • 1
  • 1
  • I will add copy to the array assignment. Yes, when I run this on it's own it's giving me the `.size` i'm looking for, but when I run this unit test against it, it is claiming the size does not equal -1 `self.assertEqual(type(test_output), type(self.testInput)) self.assertEqual(test_output.shape[0], self.testInput.shape[0]) self.assertEqual(test_output.shape[1], self.testInput.shape[1] - 1)` – yodish Sep 18 '15 at 12:15