opencv image gradient sobel Scharr Laplacian edge detection Canny

The smoothing process introduced by Gaussian smoothing, bilateral smoothing, mean smoothing, and median smoothing can be regarded as the "low-pass filtering" of the image. It will filter out the "high-frequency" part of the image, making the image look smoother, and the image Gradient can be regarded as "high-pass filtering" on the image, which will filter out the low-frequency parts of the image in order to highlight the sudden changes in the image.
1.sobel
Insert image description here

The Sobel gradient will have gradients in the x and y directions. The gradient in the x direction is 2 times the pixel value on the right side of the point plus the sum of the upper right and lower right pixel values ​​minus 2 times the pixel value on the left plus the upper left and lower left pixel values. The gradient value of this point has nothing to do with itself, but is only related to the pixel values ​​on its left and right sides. The gradient in the y direction is related to the pixel values ​​in the up and down directions.

dst = cv2.Sobel(src, ddepth, dx, dy[, dst[, ksize[, scale[, delta[, borderType]]]]])

src: source image;
ddepth: target image depth;
dx: derivation order in x direction;
dy: derivation order in y direction;
dst: target image;
ksize: kernel size, the documentation states that it must be 1,3,5 , one of 7, but experiments can show that it should be a positive odd number less than 31; if it is -1, it means scharr filtering;
scale: scaling ratio, the default is 1;
delta: overlay value, the default is 0;
borderType: border filling type;

2. Scharr
The Scharr transform can be regarded as the Sobel transform using the Scharr kernel. It is an improved Sobel transform. It also distinguishes between the x and y directions and calculates the gradient separately.
dst = cv2.Scharr(src, ddepth, dx, dy[, dst[, scale[, delta[, borderType]]]])
src: source image;
ddepth: target image depth;
dx: derivation order in x direction;
dy: derivation order in y direction;
dst: target image;
scale: scaling ratio, default is 1;
delta: superposition value, default is 0;
borderType: border filling type;
note that Scharr() has no ksize parameter because the size of Scharr kernel is fixed at 3×3.

先设置dx=1,dy=0计算x方向的梯度,再设置dy=1,dx=0计算y方向的梯度,为了避免出现饱和运算,
dtype设置的是比源图像数据类型CV_8U更高的CV_16S,然后将结果用convertScaleAbs()转换回
CV_8U(np.unit8)类型,最后用addWeighted()将x和y方向的梯度图加权相加。
grad_x = cv2.Scharr(img_src,cv2.CV_16S,1,0)
grad_y = cv2.Scharr(img_src,cv2.CV_16S,0,1)
abs_grad_x = cv2.convertScaleAbs(grad_x)
abs_grad_y = cv2.convertScaleAbs(grad_y)
grad = cv2.addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0)

3. Laplacian
Laplacian transformation is to find the second derivative of the image. The following figure shows two 3×3 size kernels. Here ksize is the input parameter name of Laplacian(): Laplacian() transformation does not need to distinguish between the x and y directions of the image for calculation
Insert image description here
. Gradient, you can also see from the two kernels in the figure above that their x and y directions are symmetrical.
In the Laplacian() transformation, ksize must be a positive odd number less than 31, but when ksize is equal to 1, the size of the kernel is not 1, and its actual size is still 3×3. This can be seen from the source code When ksize=1, it is actually a 3×3 size kernel containing 9 elements:

dst = cv2.Laplacian(src, ddepth[, dst[, ksize[, scale[, delta[, borderType]]]]])

src: source image;
ddepth: target image depth;
dst: target image;
ksize: kernel size, a positive odd number less than 31; if it is 1, it is still a 3×3 kernel;
scale: scaling ratio, the default is 1;
delta: Overlay value, default is 0;
borderType: border filling type;
There is no dx or dy parameter in Laplacian transformation, because Laplacian is the second derivative of the image.

From the running results, we can see that the larger the ksize in Laplacian(), the richer the gradient information, which is the same as the Sobel transform. In addition, at the same ksize, comparing the second-order Sobel transform and the Laplacian transform, the gradient information obtained by the Laplacian transform is more obvious.

#Laplacian
grad_lap = cv2.Laplacian(img_src,cv2.CV_16S,ksize=1)
abs_grad_lap1 = cv2.convertScaleAbs(grad_lap)
grad_lap = cv2.Laplacian(img_src,cv2.CV_16S,ksize=3)
abs_grad_lap3 = cv2.convertScaleAbs(grad_lap)
grad_lap = cv2.Laplacian(img_src,cv2.CV_16S,ksize=5)
abs_grad_lap5 = cv2.convertScaleAbs(grad_lap)
#二阶Sobel
grad_x = cv2.Sobel(img_src, cv2.CV_16S, 2, 0, ksize=3)
grad_y = cv2.Sobel(img_src, cv2.CV_16S, 0, 2, ksize=3)
abs_grad_x = cv2.convertScaleAbs(grad_x)
abs_grad_y = cv2.convertScaleAbs(grad_y)
abs_grad_sobel = cv2.addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0)

Edge Detection Canny

The image gradient reflects the change process of the image pixel value, regardless of the size of the change, so the Sobel and Laplacian transformation results in a multi-level grayscale image. Edge detection can also be seen as an extension of the image gradient, but edge detection pays more attention to the "edge" part of the image. The parts with smaller changes in the image gradient will be ignored, and only the parts with larger changes are retained.

Canny edge detection has the advantages of low error rate, good edge point positioning, and single edge point response. The canny edge detection algorithm consists of the following steps:

1) Smooth the input image with a Gaussian filter;
2) Calculate the gradient magnitude image and angular direction;
3) Apply non-maximum suppression to the gradient magnitude image;
4) Detect and connect edges with dual thresholding and join analysis.

第一种接口
edges=cv2.Canny(image, threshold1, threshold1[, edges[, apertureSize[, L2gradient]]])

image: 8-bit source image, which can be single channel or multi-channel;
threshold1: hysteresis threshold 1;
threshold2: hysteresis threshold 2, and threshold1 have no size requirements, the function will adjust the exchange internally;
edges: target image, binary image;
apertureSize: kernel Size, default is 3;
L2gradient: whether to use L2 paradigm. If set to True, the square and square root of the gradient in two directions are used when calculating the gradient. If set to False, the sum of the absolute values ​​of the gradient in two directions is used. ;

2种接口形式如下:
edges=cv2.Canny(dx, dy, threshold1, threshold2[, edges[, L2gradient]])

dx: 16-bit (CV_16SC1 or CV_16SC3) x-direction gradient image of the source
image; dy: 16-bit (CV_16SC1 or CV_16SC3) y-direction gradient image of the source image;
threshold1: hysteresis threshold 1;
threshold2: hysteresis threshold 2;
edges: target image;
L2gradient : Whether to use L2 paradigm. If set to True, the square and square root of the two directional gradients are used when calculating the gradient. If set to False, the sum of the absolute values ​​of the two directional gradients is used;

The second interface form has the same effect as the first one to implement edge detection. The second form needs to first calculate the gradient of the image in the x and y directions, so the kernel size for calculating the gradient is not needed in the second interface. .

Ksize difference

img_edge3 = cv2.Canny(img_src,20,100,apertureSize=3)
img_edge5 = cv2.Canny(img_src,20,100,apertureSize=5)
img_edge7 = cv2.Canny(img_src,20,100,apertureSize=7) 

For the same threshold value, the larger the ksize, the more edge details. This is the same as the image gradient calculation effect of Sobel(), Scharr(), and Laplacian().

threshold width

img_edge3 = cv2.Canny(img_src,50,60,apertureSize=3)
img_edge5 = cv2.Canny(img_src,50,120,apertureSize=3)
img_edge7 = cv2.Canny(img_src,50,240,apertureSize=3) 

When the ksize is the same, the smaller the difference between threshold1 and threshold2, the more edge details.

Guess you like

Origin blog.csdn.net/aqiangdeba/article/details/129776861