-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update edges.py #5552
base: main
Are you sure you want to change the base?
Update edges.py #5552
Conversation
This is issue scikit-image#5491 and the main problem was a function only generating kernel size of 3x3 now I added more kernel_size now kernel size can grow up to 31x31 all odd numbers this issue is all about laplacian operator for edge detection
Hello @themnvrao76! Thanks for opening this PR. We checked the lines you've touched for PEP 8 issues, and found:
|
a = np.zeros((ksize, ksize)) | ||
a[int(ksize/2), int(ksize/2)] = 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code is 2D only. For nD support it would need to be
a = np.zeros((ksize,) * image.ndim)
a[(ksize // 2,) * image.ndim] = 1
However, I Don't think you need the variables a
or x
at all.
I think you can just apply generic_laplace
directly to image. This will be more efficient than forming a n-dimensional kernels.
Using output = ndi.convolve1d(image, deriv_kernel, axis=0) + ndi.convolve1d(image, deriv_kernel, axis=1) which should be more efficient than explicitly forming the equivalent 2D kernel and calling convolve once with that. Note that it is also different than chained 1D convolution like: output = ndi.convolve1d(ndi.convolve1d(image, deriv_kernel, axis=0), deriv_kernel, axis=1)) |
x=[generic_laplace(a, d2, extra_arguments = (k_size(ksize),))] | ||
x=np.repeat(x,3,0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What was the purpose of this repeat by 3 along the first axis? Why do we want a kernel of size (3, ksize, ksize)
?
This is a good start, but will need a bit of revision before it is ready to merge. I think what OpenCV's Laplacian does is substantially different than this and we need to decide the approach we want to use. Thanks for taking this on @themnvrao76! |
Actually, on closer inspection OpenCV's import cv2
import numpy as np
for ksize in [1, 3, 5, 7, 9]:
if ksize == 1:
# Special case in OpenCV (ksize=1 gives a different 3x3 kernel)
a = np.zeros((3, 3), dtype=np.uint8)
a[1, 1] = 1
else:
a = np.zeros((ksize, ksize), dtype=np.uint8)
a[ksize // 2, ksize // 2] = 1
kernel = cv2.Laplacian(a, cv2.CV_16S, ksize=ksize, borderType=cv2.BORDER_CONSTANT)
print(f"kernel (ksize={ksize})=\n{kernel}\n") gives
For all cases except the special case of ksize=1, this turns out to be equivalent to: 1.) getting separable 0th and 2nd order difference kernels for a given ksize ksize = 5
deriv0, deriv2 = cv2.getDerivKernels(0, 2, ksize)
deriv0 = np.squeeze(deriv0)
deriv2 = np.squeeze(deriv2)
print(f"0th derivative, ksize={ksize} : {deriv0}")
print(f"2nd derivative, ksize={ksize} : {deriv2}")
and then a = np.zeros((ksize, ksize))
a[ksize // 2, ksize // 2] = 1
# smooth along axis 0, second derivative along axis 1
out = ndi.convolve1d(ndi.convolve1d(a, deriv0, axis=0), deriv2, axis=1)
# smooth along axis 1, second derivative along axis 0
out += ndi.convolve1d(ndi.convolve1d(a, deriv2, axis=0), deriv0, axis=1) Here The difference between |
param=[1,-2,1] | ||
return param | ||
else: | ||
return np.convolve(k_size(ksize-2),[1,-2,1]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Repeated convolution with [-1, 2, -1] was a mistake in my initial description of the issue. Each time we repeat the convolution we are taking another two derivatives! What we want is a ksize (central) finite different approximation to the 2nd derivative.
There are some specific cases (and a general algorithm) listed here:
https://en.wikipedia.org/wiki/Finite_difference_coefficient#Central_finite_difference
but OpenCV seems to be using a different approximation. We don't necessarily need to match OpenCV, though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
okay thanks i will do more research and change it
This fixes #5491 and the main problem was a function only generating kernel size of 3x3 now I added more kernel_size now kernel size can grow up to 31x31 all odd numbers this issue is all about laplacian operator for edge detection
Description
Checklist
./doc/examples
(new features only)./benchmarks
, if your changes aren't covered by anexisting benchmark
For reviewers
later.
__init__.py
.doc/release/release_dev.rst
.