grammar corrections
This commit is contained in:
parent
9e906d9e21
commit
6276b86a78
@ -5,44 +5,44 @@ Goal
|
|||||||
----
|
----
|
||||||
|
|
||||||
- In this tutorial, you will learn how to convert images from one color-space to another, like
|
- In this tutorial, you will learn how to convert images from one color-space to another, like
|
||||||
BGR \f$\leftrightarrow\f$ Gray, BGR \f$\leftrightarrow\f$ HSV etc.
|
BGR \f$\leftrightarrow\f$ Gray, BGR \f$\leftrightarrow\f$ HSV, etc.
|
||||||
- In addition to that, we will create an application which extracts a colored object in a video
|
- In addition to that, we will create an application to extract a colored object in a video
|
||||||
- You will learn following functions : **cv.cvtColor()**, **cv.inRange()** etc.
|
- You will learn the following functions: **cv.cvtColor()**, **cv.inRange()**, etc.
|
||||||
|
|
||||||
Changing Color-space
|
Changing Color-space
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
There are more than 150 color-space conversion methods available in OpenCV. But we will look into
|
There are more than 150 color-space conversion methods available in OpenCV. But we will look into
|
||||||
only two which are most widely used ones, BGR \f$\leftrightarrow\f$ Gray and BGR \f$\leftrightarrow\f$ HSV.
|
only two, which are most widely used ones: BGR \f$\leftrightarrow\f$ Gray and BGR \f$\leftrightarrow\f$ HSV.
|
||||||
|
|
||||||
For color conversion, we use the function cv.cvtColor(input_image, flag) where flag determines the
|
For color conversion, we use the function cv.cvtColor(input_image, flag) where flag determines the
|
||||||
type of conversion.
|
type of conversion.
|
||||||
|
|
||||||
For BGR \f$\rightarrow\f$ Gray conversion we use the flags cv.COLOR_BGR2GRAY. Similarly for BGR
|
For BGR \f$\rightarrow\f$ Gray conversion, we use the flag cv.COLOR_BGR2GRAY. Similarly for BGR
|
||||||
\f$\rightarrow\f$ HSV, we use the flag cv.COLOR_BGR2HSV. To get other flags, just run following
|
\f$\rightarrow\f$ HSV, we use the flag cv.COLOR_BGR2HSV. To get other flags, just run following
|
||||||
commands in your Python terminal :
|
commands in your Python terminal:
|
||||||
@code{.py}
|
@code{.py}
|
||||||
>>> import cv2 as cv
|
>>> import cv2 as cv
|
||||||
>>> flags = [i for i in dir(cv) if i.startswith('COLOR_')]
|
>>> flags = [i for i in dir(cv) if i.startswith('COLOR_')]
|
||||||
>>> print( flags )
|
>>> print( flags )
|
||||||
@endcode
|
@endcode
|
||||||
@note For HSV, Hue range is [0,179], Saturation range is [0,255] and Value range is [0,255].
|
@note For HSV, hue range is [0,179], saturation range is [0,255], and value range is [0,255].
|
||||||
Different software use different scales. So if you are comparing OpenCV values with them, you need
|
Different software use different scales. So if you are comparing OpenCV values with them, you need
|
||||||
to normalize these ranges.
|
to normalize these ranges.
|
||||||
|
|
||||||
Object Tracking
|
Object Tracking
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
Now we know how to convert BGR image to HSV, we can use this to extract a colored object. In HSV, it
|
Now that we know how to convert a BGR image to HSV, we can use this to extract a colored object. In HSV, it
|
||||||
is more easier to represent a color than in BGR color-space. In our application, we will try to extract
|
is easier to represent a color than in BGR color-space. In our application, we will try to extract
|
||||||
a blue colored object. So here is the method:
|
a blue colored object. So here is the method:
|
||||||
|
|
||||||
- Take each frame of the video
|
- Take each frame of the video
|
||||||
- Convert from BGR to HSV color-space
|
- Convert from BGR to HSV color-space
|
||||||
- We threshold the HSV image for a range of blue color
|
- We threshold the HSV image for a range of blue color
|
||||||
- Now extract the blue object alone, we can do whatever on that image we want.
|
- Now extract the blue object alone, we can do whatever we want on that image.
|
||||||
|
|
||||||
Below is the code which are commented in detail :
|
Below is the code which is commented in detail:
|
||||||
@code{.py}
|
@code{.py}
|
||||||
import cv2 as cv
|
import cv2 as cv
|
||||||
import numpy as np
|
import numpy as np
|
||||||
@ -80,18 +80,18 @@ Below image shows tracking of the blue object:
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
@note There are some noises in the image. We will see how to remove them in later chapters.
|
@note There is some noise in the image. We will see how to remove it in later chapters.
|
||||||
|
|
||||||
@note This is the simplest method in object tracking. Once you learn functions of contours, you can
|
@note This is the simplest method in object tracking. Once you learn functions of contours, you can
|
||||||
do plenty of things like find centroid of this object and use it to track the object, draw diagrams
|
do plenty of things like find the centroid of an object and use it to track the object, draw diagrams
|
||||||
just by moving your hand in front of camera and many other funny stuffs.
|
just by moving your hand in front of a camera, and other fun stuff.
|
||||||
|
|
||||||
How to find HSV values to track?
|
How to find HSV values to track?
|
||||||
--------------------------------
|
--------------------------------
|
||||||
|
|
||||||
This is a common question found in [stackoverflow.com](http://www.stackoverflow.com). It is very simple and
|
This is a common question found in [stackoverflow.com](http://www.stackoverflow.com). It is very simple and
|
||||||
you can use the same function, cv.cvtColor(). Instead of passing an image, you just pass the BGR
|
you can use the same function, cv.cvtColor(). Instead of passing an image, you just pass the BGR
|
||||||
values you want. For example, to find the HSV value of Green, try following commands in Python
|
values you want. For example, to find the HSV value of Green, try the following commands in a Python
|
||||||
terminal:
|
terminal:
|
||||||
@code{.py}
|
@code{.py}
|
||||||
>>> green = np.uint8([[[0,255,0 ]]])
|
>>> green = np.uint8([[[0,255,0 ]]])
|
||||||
@ -99,7 +99,7 @@ terminal:
|
|||||||
>>> print( hsv_green )
|
>>> print( hsv_green )
|
||||||
[[[ 60 255 255]]]
|
[[[ 60 255 255]]]
|
||||||
@endcode
|
@endcode
|
||||||
Now you take [H-10, 100,100] and [H+10, 255, 255] as lower bound and upper bound respectively. Apart
|
Now you take [H-10, 100,100] and [H+10, 255, 255] as the lower bound and upper bound respectively. Apart
|
||||||
from this method, you can use any image editing tools like GIMP or any online converters to find
|
from this method, you can use any image editing tools like GIMP or any online converters to find
|
||||||
these values, but don't forget to adjust the HSV ranges.
|
these values, but don't forget to adjust the HSV ranges.
|
||||||
|
|
||||||
@ -109,5 +109,5 @@ Additional Resources
|
|||||||
Exercises
|
Exercises
|
||||||
---------
|
---------
|
||||||
|
|
||||||
-# Try to find a way to extract more than one colored objects, for eg, extract red, blue, green
|
-# Try to find a way to extract more than one colored object, for example, extract red, blue, and green
|
||||||
objects simultaneously.
|
objects simultaneously.
|
||||||
|
|||||||
@ -5,24 +5,24 @@ Goals
|
|||||||
-----
|
-----
|
||||||
|
|
||||||
Learn to:
|
Learn to:
|
||||||
- Blur the images with various low pass filters
|
- Blur images with various low pass filters
|
||||||
- Apply custom-made filters to images (2D convolution)
|
- Apply custom-made filters to images (2D convolution)
|
||||||
|
|
||||||
2D Convolution ( Image Filtering )
|
2D Convolution ( Image Filtering )
|
||||||
----------------------------------
|
----------------------------------
|
||||||
|
|
||||||
As in one-dimensional signals, images also can be filtered with various low-pass filters(LPF),
|
As in one-dimensional signals, images also can be filtered with various low-pass filters (LPF),
|
||||||
high-pass filters(HPF) etc. LPF helps in removing noises, blurring the images etc. HPF filters helps
|
high-pass filters (HPF), etc. LPF helps in removing noise, blurring images, etc. HPF filters help
|
||||||
in finding edges in the images.
|
in finding edges in images.
|
||||||
|
|
||||||
OpenCV provides a function **cv.filter2D()** to convolve a kernel with an image. As an example, we
|
OpenCV provides a function **cv.filter2D()** to convolve a kernel with an image. As an example, we
|
||||||
will try an averaging filter on an image. A 5x5 averaging filter kernel will look like below:
|
will try an averaging filter on an image. A 5x5 averaging filter kernel will look like the below:
|
||||||
|
|
||||||
\f[K = \frac{1}{25} \begin{bmatrix} 1 & 1 & 1 & 1 & 1 \\ 1 & 1 & 1 & 1 & 1 \\ 1 & 1 & 1 & 1 & 1 \\ 1 & 1 & 1 & 1 & 1 \\ 1 & 1 & 1 & 1 & 1 \end{bmatrix}\f]
|
\f[K = \frac{1}{25} \begin{bmatrix} 1 & 1 & 1 & 1 & 1 \\ 1 & 1 & 1 & 1 & 1 \\ 1 & 1 & 1 & 1 & 1 \\ 1 & 1 & 1 & 1 & 1 \\ 1 & 1 & 1 & 1 & 1 \end{bmatrix}\f]
|
||||||
|
|
||||||
Operation is like this: keep this kernel above a pixel, add all the 25 pixels below this kernel,
|
The operation works like this: keep this kernel above a pixel, add all the 25 pixels below this kernel,
|
||||||
take its average and replace the central pixel with the new average value. It continues this
|
take the average, and replace the central pixel with the new average value. This operation is continued
|
||||||
operation for all the pixels in the image. Try this code and check the result:
|
for all the pixels in the image. Try this code and check the result:
|
||||||
@code{.py}
|
@code{.py}
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import cv2 as cv
|
import cv2 as cv
|
||||||
@ -47,20 +47,20 @@ Image Blurring (Image Smoothing)
|
|||||||
--------------------------------
|
--------------------------------
|
||||||
|
|
||||||
Image blurring is achieved by convolving the image with a low-pass filter kernel. It is useful for
|
Image blurring is achieved by convolving the image with a low-pass filter kernel. It is useful for
|
||||||
removing noises. It actually removes high frequency content (eg: noise, edges) from the image. So
|
removing noise. It actually removes high frequency content (eg: noise, edges) from the image. So
|
||||||
edges are blurred a little bit in this operation. (Well, there are blurring techniques which doesn't
|
edges are blurred a little bit in this operation (there are also blurring techniques which don't
|
||||||
blur the edges too). OpenCV provides mainly four types of blurring techniques.
|
blur the edges). OpenCV provides four main types of blurring techniques.
|
||||||
|
|
||||||
### 1. Averaging
|
### 1. Averaging
|
||||||
|
|
||||||
This is done by convolving image with a normalized box filter. It simply takes the average of all
|
This is done by convolving an image with a normalized box filter. It simply takes the average of all
|
||||||
the pixels under kernel area and replace the central element. This is done by the function
|
the pixels under the kernel area and replaces the central element. This is done by the function
|
||||||
**cv.blur()** or **cv.boxFilter()**. Check the docs for more details about the kernel. We should
|
**cv.blur()** or **cv.boxFilter()**. Check the docs for more details about the kernel. We should
|
||||||
specify the width and height of kernel. A 3x3 normalized box filter would look like below:
|
specify the width and height of the kernel. A 3x3 normalized box filter would look like the below:
|
||||||
|
|
||||||
\f[K = \frac{1}{9} \begin{bmatrix} 1 & 1 & 1 \\ 1 & 1 & 1 \\ 1 & 1 & 1 \end{bmatrix}\f]
|
\f[K = \frac{1}{9} \begin{bmatrix} 1 & 1 & 1 \\ 1 & 1 & 1 \\ 1 & 1 & 1 \end{bmatrix}\f]
|
||||||
|
|
||||||
@note If you don't want to use normalized box filter, use **cv.boxFilter()**. Pass an argument
|
@note If you don't want to use a normalized box filter, use **cv.boxFilter()**. Pass an argument
|
||||||
normalize=False to the function.
|
normalize=False to the function.
|
||||||
|
|
||||||
Check a sample demo below with a kernel of 5x5 size:
|
Check a sample demo below with a kernel of 5x5 size:
|
||||||
@ -85,12 +85,12 @@ Result:
|
|||||||
|
|
||||||
### 2. Gaussian Blurring
|
### 2. Gaussian Blurring
|
||||||
|
|
||||||
In this, instead of box filter, gaussian kernel is used. It is done with the function,
|
In this method, instead of a box filter, a Gaussian kernel is used. It is done with the function,
|
||||||
**cv.GaussianBlur()**. We should specify the width and height of kernel which should be positive
|
**cv.GaussianBlur()**. We should specify the width and height of the kernel which should be positive
|
||||||
and odd. We also should specify the standard deviation in X and Y direction, sigmaX and sigmaY
|
and odd. We also should specify the standard deviation in the X and Y directions, sigmaX and sigmaY
|
||||||
respectively. If only sigmaX is specified, sigmaY is taken as same as sigmaX. If both are given as
|
respectively. If only sigmaX is specified, sigmaY is taken as the same as sigmaX. If both are given as
|
||||||
zeros, they are calculated from kernel size. Gaussian blurring is highly effective in removing
|
zeros, they are calculated from the kernel size. Gaussian blurring is highly effective in removing
|
||||||
gaussian noise from the image.
|
Gaussian noise from an image.
|
||||||
|
|
||||||
If you want, you can create a Gaussian kernel with the function, **cv.getGaussianKernel()**.
|
If you want, you can create a Gaussian kernel with the function, **cv.getGaussianKernel()**.
|
||||||
|
|
||||||
@ -104,14 +104,14 @@ Result:
|
|||||||
|
|
||||||
### 3. Median Blurring
|
### 3. Median Blurring
|
||||||
|
|
||||||
Here, the function **cv.medianBlur()** takes median of all the pixels under kernel area and central
|
Here, the function **cv.medianBlur()** takes the median of all the pixels under the kernel area and the central
|
||||||
element is replaced with this median value. This is highly effective against salt-and-pepper noise
|
element is replaced with this median value. This is highly effective against salt-and-pepper noise
|
||||||
in the images. Interesting thing is that, in the above filters, central element is a newly
|
in an image. Interestingly, in the above filters, the central element is a newly
|
||||||
calculated value which may be a pixel value in the image or a new value. But in median blurring,
|
calculated value which may be a pixel value in the image or a new value. But in median blurring,
|
||||||
central element is always replaced by some pixel value in the image. It reduces the noise
|
the central element is always replaced by some pixel value in the image. It reduces the noise
|
||||||
effectively. Its kernel size should be a positive odd integer.
|
effectively. Its kernel size should be a positive odd integer.
|
||||||
|
|
||||||
In this demo, I added a 50% noise to our original image and applied median blur. Check the result:
|
In this demo, I added a 50% noise to our original image and applied median blurring. Check the result:
|
||||||
@code{.py}
|
@code{.py}
|
||||||
median = cv.medianBlur(img,5)
|
median = cv.medianBlur(img,5)
|
||||||
@endcode
|
@endcode
|
||||||
@ -122,19 +122,19 @@ Result:
|
|||||||
### 4. Bilateral Filtering
|
### 4. Bilateral Filtering
|
||||||
|
|
||||||
**cv.bilateralFilter()** is highly effective in noise removal while keeping edges sharp. But the
|
**cv.bilateralFilter()** is highly effective in noise removal while keeping edges sharp. But the
|
||||||
operation is slower compared to other filters. We already saw that gaussian filter takes the a
|
operation is slower compared to other filters. We already saw that a Gaussian filter takes the
|
||||||
neighbourhood around the pixel and find its gaussian weighted average. This gaussian filter is a
|
neighbourhood around the pixel and finds its Gaussian weighted average. This Gaussian filter is a
|
||||||
function of space alone, that is, nearby pixels are considered while filtering. It doesn't consider
|
function of space alone, that is, nearby pixels are considered while filtering. It doesn't consider
|
||||||
whether pixels have almost same intensity. It doesn't consider whether pixel is an edge pixel or
|
whether pixels have almost the same intensity. It doesn't consider whether a pixel is an edge pixel or
|
||||||
not. So it blurs the edges also, which we don't want to do.
|
not. So it blurs the edges also, which we don't want to do.
|
||||||
|
|
||||||
Bilateral filter also takes a gaussian filter in space, but one more gaussian filter which is a
|
Bilateral filtering also takes a Gaussian filter in space, but one more Gaussian filter which is a
|
||||||
function of pixel difference. Gaussian function of space make sure only nearby pixels are considered
|
function of pixel difference. The Gaussian function of space makes sure that only nearby pixels are considered
|
||||||
for blurring while gaussian function of intensity difference make sure only those pixels with
|
for blurring, while the Gaussian function of intensity difference makes sure that only those pixels with
|
||||||
similar intensity to central pixel is considered for blurring. So it preserves the edges since
|
similar intensities to the central pixel are considered for blurring. So it preserves the edges since
|
||||||
pixels at edges will have large intensity variation.
|
pixels at edges will have large intensity variation.
|
||||||
|
|
||||||
Below samples shows use bilateral filter (For details on arguments, visit docs).
|
The below sample shows use of a bilateral filter (For details on arguments, visit docs).
|
||||||
@code{.py}
|
@code{.py}
|
||||||
blur = cv.bilateralFilter(img,9,75,75)
|
blur = cv.bilateralFilter(img,9,75,75)
|
||||||
@endcode
|
@endcode
|
||||||
@ -142,7 +142,7 @@ Result:
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
See, the texture on the surface is gone, but edges are still preserved.
|
See, the texture on the surface is gone, but the edges are still preserved.
|
||||||
|
|
||||||
Additional Resources
|
Additional Resources
|
||||||
--------------------
|
--------------------
|
||||||
|
|||||||
@ -4,7 +4,7 @@ Geometric Transformations of Images {#tutorial_py_geometric_transformations}
|
|||||||
Goals
|
Goals
|
||||||
-----
|
-----
|
||||||
|
|
||||||
- Learn to apply different geometric transformation to images like translation, rotation, affine
|
- Learn to apply different geometric transformations to images, like translation, rotation, affine
|
||||||
transformation etc.
|
transformation etc.
|
||||||
- You will see these functions: **cv.getPerspectiveTransform**
|
- You will see these functions: **cv.getPerspectiveTransform**
|
||||||
|
|
||||||
@ -12,7 +12,7 @@ Transformations
|
|||||||
---------------
|
---------------
|
||||||
|
|
||||||
OpenCV provides two transformation functions, **cv.warpAffine** and **cv.warpPerspective**, with
|
OpenCV provides two transformation functions, **cv.warpAffine** and **cv.warpPerspective**, with
|
||||||
which you can have all kinds of transformations. **cv.warpAffine** takes a 2x3 transformation
|
which you can perform all kinds of transformations. **cv.warpAffine** takes a 2x3 transformation
|
||||||
matrix while **cv.warpPerspective** takes a 3x3 transformation matrix as input.
|
matrix while **cv.warpPerspective** takes a 3x3 transformation matrix as input.
|
||||||
|
|
||||||
### Scaling
|
### Scaling
|
||||||
@ -21,8 +21,8 @@ Scaling is just resizing of the image. OpenCV comes with a function **cv.resize(
|
|||||||
purpose. The size of the image can be specified manually, or you can specify the scaling factor.
|
purpose. The size of the image can be specified manually, or you can specify the scaling factor.
|
||||||
Different interpolation methods are used. Preferable interpolation methods are **cv.INTER_AREA**
|
Different interpolation methods are used. Preferable interpolation methods are **cv.INTER_AREA**
|
||||||
for shrinking and **cv.INTER_CUBIC** (slow) & **cv.INTER_LINEAR** for zooming. By default,
|
for shrinking and **cv.INTER_CUBIC** (slow) & **cv.INTER_LINEAR** for zooming. By default,
|
||||||
interpolation method used is **cv.INTER_LINEAR** for all resizing purposes. You can resize an
|
the interpolation method **cv.INTER_LINEAR** is used for all resizing purposes. You can resize an
|
||||||
input image either of following methods:
|
input image with either of following methods:
|
||||||
@code{.py}
|
@code{.py}
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import cv2 as cv
|
import cv2 as cv
|
||||||
@ -38,13 +38,13 @@ res = cv.resize(img,(2*width, 2*height), interpolation = cv.INTER_CUBIC)
|
|||||||
@endcode
|
@endcode
|
||||||
### Translation
|
### Translation
|
||||||
|
|
||||||
Translation is the shifting of object's location. If you know the shift in (x,y) direction, let it
|
Translation is the shifting of an object's location. If you know the shift in the (x,y) direction and let it
|
||||||
be \f$(t_x,t_y)\f$, you can create the transformation matrix \f$\textbf{M}\f$ as follows:
|
be \f$(t_x,t_y)\f$, you can create the transformation matrix \f$\textbf{M}\f$ as follows:
|
||||||
|
|
||||||
\f[M = \begin{bmatrix} 1 & 0 & t_x \\ 0 & 1 & t_y \end{bmatrix}\f]
|
\f[M = \begin{bmatrix} 1 & 0 & t_x \\ 0 & 1 & t_y \end{bmatrix}\f]
|
||||||
|
|
||||||
You can take make it into a Numpy array of type np.float32 and pass it into **cv.warpAffine()**
|
You can take make it into a Numpy array of type np.float32 and pass it into the **cv.warpAffine()**
|
||||||
function. See below example for a shift of (100,50):
|
function. See the below example for a shift of (100,50):
|
||||||
@code{.py}
|
@code{.py}
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import cv2 as cv
|
import cv2 as cv
|
||||||
@ -61,7 +61,7 @@ cv.destroyAllWindows()
|
|||||||
@endcode
|
@endcode
|
||||||
**warning**
|
**warning**
|
||||||
|
|
||||||
Third argument of the **cv.warpAffine()** function is the size of the output image, which should
|
The third argument of the **cv.warpAffine()** function is the size of the output image, which should
|
||||||
be in the form of **(width, height)**. Remember width = number of columns, and height = number of
|
be in the form of **(width, height)**. Remember width = number of columns, and height = number of
|
||||||
rows.
|
rows.
|
||||||
|
|
||||||
@ -76,7 +76,7 @@ Rotation of an image for an angle \f$\theta\f$ is achieved by the transformation
|
|||||||
\f[M = \begin{bmatrix} cos\theta & -sin\theta \\ sin\theta & cos\theta \end{bmatrix}\f]
|
\f[M = \begin{bmatrix} cos\theta & -sin\theta \\ sin\theta & cos\theta \end{bmatrix}\f]
|
||||||
|
|
||||||
But OpenCV provides scaled rotation with adjustable center of rotation so that you can rotate at any
|
But OpenCV provides scaled rotation with adjustable center of rotation so that you can rotate at any
|
||||||
location you prefer. Modified transformation matrix is given by
|
location you prefer. The modified transformation matrix is given by
|
||||||
|
|
||||||
\f[\begin{bmatrix} \alpha & \beta & (1- \alpha ) \cdot center.x - \beta \cdot center.y \\ - \beta & \alpha & \beta \cdot center.x + (1- \alpha ) \cdot center.y \end{bmatrix}\f]
|
\f[\begin{bmatrix} \alpha & \beta & (1- \alpha ) \cdot center.x - \beta \cdot center.y \\ - \beta & \alpha & \beta \cdot center.x + (1- \alpha ) \cdot center.y \end{bmatrix}\f]
|
||||||
|
|
||||||
@ -84,7 +84,7 @@ where:
|
|||||||
|
|
||||||
\f[\begin{array}{l} \alpha = scale \cdot \cos \theta , \\ \beta = scale \cdot \sin \theta \end{array}\f]
|
\f[\begin{array}{l} \alpha = scale \cdot \cos \theta , \\ \beta = scale \cdot \sin \theta \end{array}\f]
|
||||||
|
|
||||||
To find this transformation matrix, OpenCV provides a function, **cv.getRotationMatrix2D**. Check
|
To find this transformation matrix, OpenCV provides a function, **cv.getRotationMatrix2D**. Check out the
|
||||||
below example which rotates the image by 90 degree with respect to center without any scaling.
|
below example which rotates the image by 90 degree with respect to center without any scaling.
|
||||||
@code{.py}
|
@code{.py}
|
||||||
img = cv.imread('messi5.jpg',0)
|
img = cv.imread('messi5.jpg',0)
|
||||||
@ -101,11 +101,11 @@ See the result:
|
|||||||
### Affine Transformation
|
### Affine Transformation
|
||||||
|
|
||||||
In affine transformation, all parallel lines in the original image will still be parallel in the
|
In affine transformation, all parallel lines in the original image will still be parallel in the
|
||||||
output image. To find the transformation matrix, we need three points from input image and their
|
output image. To find the transformation matrix, we need three points from the input image and their
|
||||||
corresponding locations in output image. Then **cv.getAffineTransform** will create a 2x3 matrix
|
corresponding locations in the output image. Then **cv.getAffineTransform** will create a 2x3 matrix
|
||||||
which is to be passed to **cv.warpAffine**.
|
which is to be passed to **cv.warpAffine**.
|
||||||
|
|
||||||
Check below example, and also look at the points I selected (which are marked in Green color):
|
Check the below example, and also look at the points I selected (which are marked in green color):
|
||||||
@code{.py}
|
@code{.py}
|
||||||
img = cv.imread('drawing.png')
|
img = cv.imread('drawing.png')
|
||||||
rows,cols,ch = img.shape
|
rows,cols,ch = img.shape
|
||||||
@ -130,7 +130,7 @@ See the result:
|
|||||||
For perspective transformation, you need a 3x3 transformation matrix. Straight lines will remain
|
For perspective transformation, you need a 3x3 transformation matrix. Straight lines will remain
|
||||||
straight even after the transformation. To find this transformation matrix, you need 4 points on the
|
straight even after the transformation. To find this transformation matrix, you need 4 points on the
|
||||||
input image and corresponding points on the output image. Among these 4 points, 3 of them should not
|
input image and corresponding points on the output image. Among these 4 points, 3 of them should not
|
||||||
be collinear. Then transformation matrix can be found by the function
|
be collinear. Then the transformation matrix can be found by the function
|
||||||
**cv.getPerspectiveTransform**. Then apply **cv.warpPerspective** with this 3x3 transformation
|
**cv.getPerspectiveTransform**. Then apply **cv.warpPerspective** with this 3x3 transformation
|
||||||
matrix.
|
matrix.
|
||||||
|
|
||||||
|
|||||||
@ -4,13 +4,13 @@ Image Thresholding {#tutorial_py_thresholding}
|
|||||||
Goal
|
Goal
|
||||||
----
|
----
|
||||||
|
|
||||||
- In this tutorial, you will learn Simple thresholding, Adaptive thresholding and Otsu's thresholding.
|
- In this tutorial, you will learn simple thresholding, adaptive thresholding and Otsu's thresholding.
|
||||||
- You will learn the functions **cv.threshold** and **cv.adaptiveThreshold**.
|
- You will learn the functions **cv.threshold** and **cv.adaptiveThreshold**.
|
||||||
|
|
||||||
Simple Thresholding
|
Simple Thresholding
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
Here, the matter is straight forward. For every pixel, the same threshold value is applied.
|
Here, the matter is straight-forward. For every pixel, the same threshold value is applied.
|
||||||
If the pixel value is smaller than the threshold, it is set to 0, otherwise it is set to a maximum value.
|
If the pixel value is smaller than the threshold, it is set to 0, otherwise it is set to a maximum value.
|
||||||
The function **cv.threshold** is used to apply the thresholding.
|
The function **cv.threshold** is used to apply the thresholding.
|
||||||
The first argument is the source image, which **should be a grayscale image**.
|
The first argument is the source image, which **should be a grayscale image**.
|
||||||
@ -65,11 +65,11 @@ Adaptive Thresholding
|
|||||||
|
|
||||||
In the previous section, we used one global value as a threshold.
|
In the previous section, we used one global value as a threshold.
|
||||||
But this might not be good in all cases, e.g. if an image has different lighting conditions in different areas.
|
But this might not be good in all cases, e.g. if an image has different lighting conditions in different areas.
|
||||||
In that case, adaptive thresholding thresholding can help.
|
In that case, adaptive thresholding can help.
|
||||||
Here, the algorithm determines the threshold for a pixel based on a small region around it.
|
Here, the algorithm determines the threshold for a pixel based on a small region around it.
|
||||||
So we get different thresholds for different regions of the same image which gives better results for images with varying illumination.
|
So we get different thresholds for different regions of the same image which gives better results for images with varying illumination.
|
||||||
|
|
||||||
Additionally to the parameters described above, the method cv.adaptiveThreshold three input parameters:
|
In addition to the parameters described above, the method cv.adaptiveThreshold takes three input parameters:
|
||||||
|
|
||||||
The **adaptiveMethod** decides how the threshold value is calculated:
|
The **adaptiveMethod** decides how the threshold value is calculated:
|
||||||
- cv.ADAPTIVE_THRESH_MEAN_C: The threshold value is the mean of the neighbourhood area minus the constant **C**.
|
- cv.ADAPTIVE_THRESH_MEAN_C: The threshold value is the mean of the neighbourhood area minus the constant **C**.
|
||||||
@ -168,8 +168,8 @@ Result:
|
|||||||
|
|
||||||
### How does Otsu's Binarization work?
|
### How does Otsu's Binarization work?
|
||||||
|
|
||||||
This section demonstrates a Python implementation of Otsu's binarization to show how it works
|
This section demonstrates a Python implementation of Otsu's binarization to show how it actually
|
||||||
actually. If you are not interested, you can skip this.
|
works. If you are not interested, you can skip this.
|
||||||
|
|
||||||
Since we are working with bimodal images, Otsu's algorithm tries to find a threshold value (t) which
|
Since we are working with bimodal images, Otsu's algorithm tries to find a threshold value (t) which
|
||||||
minimizes the **weighted within-class variance** given by the relation:
|
minimizes the **weighted within-class variance** given by the relation:
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user