~paparazzi-uav/paparazzi/v5.0-manual

« back to all changes in this revision

Viewing changes to sw/ext/opencv_bebop/opencv/doc/py_tutorials/py_imgproc/py_gradients/py_gradients.markdown

  • Committer: Paparazzi buildbot
  • Date: 2016-05-18 15:00:29 UTC
  • Revision ID: felix.ruess+docbot@gmail.com-20160518150029-e8lgzi5kvb4p7un9
Manual import commit 4b8bbb730080dac23cf816b98908dacfabe2a8ec from v5.0 branch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
Image Gradients {#tutorial_py_gradients}
 
2
===============
 
3
 
 
4
Goal
 
5
----
 
6
 
 
7
In this chapter, we will learn to:
 
8
 
 
9
-   Find Image gradients, edges etc
 
10
-   We will see following functions : **cv2.Sobel()**, **cv2.Scharr()**, **cv2.Laplacian()** etc
 
11
 
 
12
Theory
 
13
------
 
14
 
 
15
OpenCV provides three types of gradient filters or High-pass filters, Sobel, Scharr and Laplacian.
 
16
We will see each one of them.
 
17
 
 
18
### 1. Sobel and Scharr Derivatives
 
19
 
 
20
Sobel operators is a joint Gausssian smoothing plus differentiation operation, so it is more
 
21
resistant to noise. You can specify the direction of derivatives to be taken, vertical or horizontal
 
22
(by the arguments, yorder and xorder respectively). You can also specify the size of kernel by the
 
23
argument ksize. If ksize = -1, a 3x3 Scharr filter is used which gives better results than 3x3 Sobel
 
24
filter. Please see the docs for kernels used.
 
25
 
 
26
### 2. Laplacian Derivatives
 
27
 
 
28
It calculates the Laplacian of the image given by the relation,
 
29
\f$\Delta src = \frac{\partial ^2{src}}{\partial x^2} + \frac{\partial ^2{src}}{\partial y^2}\f$ where
 
30
each derivative is found using Sobel derivatives. If ksize = 1, then following kernel is used for
 
31
filtering:
 
32
 
 
33
\f[kernel = \begin{bmatrix} 0 & 1 & 0 \\ 1 & -4 & 1 \\ 0 & 1 & 0  \end{bmatrix}\f]
 
34
 
 
35
Code
 
36
----
 
37
 
 
38
Below code shows all operators in a single diagram. All kernels are of 5x5 size. Depth of output
 
39
image is passed -1 to get the result in np.uint8 type.
 
40
@code{.py}
 
41
import cv2
 
42
import numpy as np
 
43
from matplotlib import pyplot as plt
 
44
 
 
45
img = cv2.imread('dave.jpg',0)
 
46
 
 
47
laplacian = cv2.Laplacian(img,cv2.CV_64F)
 
48
sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=5)
 
49
sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=5)
 
50
 
 
51
plt.subplot(2,2,1),plt.imshow(img,cmap = 'gray')
 
52
plt.title('Original'), plt.xticks([]), plt.yticks([])
 
53
plt.subplot(2,2,2),plt.imshow(laplacian,cmap = 'gray')
 
54
plt.title('Laplacian'), plt.xticks([]), plt.yticks([])
 
55
plt.subplot(2,2,3),plt.imshow(sobelx,cmap = 'gray')
 
56
plt.title('Sobel X'), plt.xticks([]), plt.yticks([])
 
57
plt.subplot(2,2,4),plt.imshow(sobely,cmap = 'gray')
 
58
plt.title('Sobel Y'), plt.xticks([]), plt.yticks([])
 
59
 
 
60
plt.show()
 
61
@endcode
 
62
Result:
 
63
 
 
64
![image](images/gradients.jpg)
 
65
 
 
66
One Important Matter!
 
67
---------------------
 
68
 
 
69
In our last example, output datatype is cv2.CV_8U or np.uint8. But there is a slight problem with
 
70
that. Black-to-White transition is taken as Positive slope (it has a positive value) while
 
71
White-to-Black transition is taken as a Negative slope (It has negative value). So when you convert
 
72
data to np.uint8, all negative slopes are made zero. In simple words, you miss that edge.
 
73
 
 
74
If you want to detect both edges, better option is to keep the output datatype to some higher forms,
 
75
like cv2.CV_16S, cv2.CV_64F etc, take its absolute value and then convert back to cv2.CV_8U.
 
76
Below code demonstrates this procedure for a horizontal Sobel filter and difference in results.
 
77
@code{.py}
 
78
import cv2
 
79
import numpy as np
 
80
from matplotlib import pyplot as plt
 
81
 
 
82
img = cv2.imread('box.png',0)
 
83
 
 
84
# Output dtype = cv2.CV_8U
 
85
sobelx8u = cv2.Sobel(img,cv2.CV_8U,1,0,ksize=5)
 
86
 
 
87
# Output dtype = cv2.CV_64F. Then take its absolute and convert to cv2.CV_8U
 
88
sobelx64f = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=5)
 
89
abs_sobel64f = np.absolute(sobelx64f)
 
90
sobel_8u = np.uint8(abs_sobel64f)
 
91
 
 
92
plt.subplot(1,3,1),plt.imshow(img,cmap = 'gray')
 
93
plt.title('Original'), plt.xticks([]), plt.yticks([])
 
94
plt.subplot(1,3,2),plt.imshow(sobelx8u,cmap = 'gray')
 
95
plt.title('Sobel CV_8U'), plt.xticks([]), plt.yticks([])
 
96
plt.subplot(1,3,3),plt.imshow(sobel_8u,cmap = 'gray')
 
97
plt.title('Sobel abs(CV_64F)'), plt.xticks([]), plt.yticks([])
 
98
 
 
99
plt.show()
 
100
@endcode
 
101
Check the result below:
 
102
 
 
103
![image](images/double_edge.jpg)
 
104
 
 
105
Additional Resources
 
106
--------------------
 
107
 
 
108
Exercises
 
109
---------