Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
O
opencv
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
opencv
Commits
bc18fb48
Commit
bc18fb48
authored
Aug 20, 2017
by
tribta
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Tutorial Smoothing Images
parent
5f6ce6f4
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
348 additions
and
76 deletions
+348
-76
gausian_median_blur_bilateral_filter.markdown
...eral_filter/gausian_median_blur_bilateral_filter.markdown
+86
-27
table_of_content_imgproc.markdown
doc/tutorials/imgproc/table_of_content_imgproc.markdown
+2
-0
Smoothing.cpp
samples/cpp/tutorial_code/ImgProc/Smoothing/Smoothing.cpp
+52
-49
Smoothing.java
samples/java/tutorial_code/ImgProc/Smoothing/Smoothing.java
+101
-0
smoothing.py
samples/python/tutorial_code/imgProc/Smoothing/smoothing.py
+107
-0
No files found.
doc/tutorials/imgproc/gausian_median_blur_bilateral_filter/gausian_median_blur_bilateral_filter.markdown
View file @
bc18fb48
Smoothing Images {#tutorial_gausian_median_blur_bilateral_filter}
================
@next_tutorial{tutorial_erosion_dilatation}
Goal
----
In this tutorial you will learn how to apply diverse linear filters to smooth images using OpenCV
functions such as:
-
@ref cv::blur
-
@ref cv::GaussianBlur
-
@ref cv::medianBlur
-
@ref cv::bilateralFilter
-
**blur()**
-
**GaussianBlur()**
-
**medianBlur()**
-
**bilateralFilter()**
Theory
------
...
...
@@ -92,38 +94,65 @@ Code
-
Loads an image
-
Applies 4 different kinds of filters (explained in Theory) and show the filtered images
sequentially
@add_toggle_cpp
-
**Downloadable code**
: Click
[
here
](
https://raw.githubusercontent.com/opencv/opencv/master/samples/cpp/tutorial_code/ImgProc/Smoothing/Smoothing.cpp
)
-
**Code at glance:**
@include samples/cpp/tutorial_code/ImgProc/Smoothing/Smoothing.cpp
@end_toggle
@add_toggle_java
-
**Downloadable code**
: Click
[
here
](
https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/ImgProc/Smoothing.cpp
)
[
here
](
https://raw.githubusercontent.com/opencv/opencv/master/samples/java/tutorial_code/ImgProc/Smoothing/Smoothing.java
)
-
**Code at glance:**
@include samples/java/tutorial_code/ImgProc/Smoothing/Smoothing.java
@end_toggle
@add_toggle_python
-
**Downloadable code**
: Click
[
here
](
https://raw.githubusercontent.com/opencv/opencv/master/samples/python/tutorial_code/imgProc/Smoothing/smoothing.py
)
-
**Code at glance:**
@include samples/cpp/tutorial_code/ImgProc/Smoothing.cpp
@include samples/python/tutorial_code/imgProc/Smoothing/smoothing.py
@end_toggle
Explanation
-----------
-# Let's check the OpenCV functions that involve only the smoothing procedure, since the rest is
already known by now.
-#
**Normalized Block Filter:**
Let's check the OpenCV functions that involve only the smoothing procedure, since the rest is
already known by now.
OpenCV offers the function @ref cv::blur to perform smoothing with this filter.
@snippet cpp/tutorial_code/ImgProc/Smoothing.cpp blur
#### Normalized Block Filter:
-
OpenCV offers the function
**blur()**
to perform smoothing with this filter.
We specify 4 arguments (more details, check the Reference):
-
*src*
: Source image
-
*dst*
: Destination image
- *Size( w,h )*: Defines the size of the kernel to be used ( of width *w* pixels and height
-
*Size( w,
h )*
: Defines the size of the kernel to be used ( of width
*w*
pixels and height
*h*
pixels)
-
*Point(-1, -1)*
: Indicates where the anchor point (the pixel evaluated) is located with
respect to the neighborhood. If there is a negative value, then the center of the kernel is
considered the anchor point.
-#
**Gaussian Filter:**
@add_toggle_cpp
@snippet cpp/tutorial_code/ImgProc/Smoothing/Smoothing.cpp blur
@end_toggle
It is performed by the function @ref cv::GaussianBlur :
@snippet cpp/tutorial_code/ImgProc/Smoothing.cpp gaussianblur
@add_toggle_java
@snippet samples/java/tutorial_code/ImgProc/Smoothing/Smoothing.java blur
@end_toggle
Here we use 4 arguments (more details, check the OpenCV reference):
@add_toggle_python
@snippet samples/python/tutorial_code/imgProc/Smoothing/smoothing.py blur
@end_toggle
#### Gaussian Filter:
-
It is performed by the function
**GaussianBlur()**
:
Here we use 4 arguments (more details, check the OpenCV reference):
-
*src*
: Source image
-
*dst*
: Destination image
-
*Size(w, h)*
: The size of the kernel to be used (the neighbors to be considered).
\f
$w
\f
$ and
...
...
@@ -134,35 +163,65 @@ Explanation
-
\f
$
\s
igma_{y}
\f
$: The standard deviation in y. Writing
\f
$0
\f
$ implies that
\f
$
\s
igma_{y}
\f
$ is
calculated using kernel size.
-#
**Median Filter:**
@add_toggle_cpp
@snippet cpp/tutorial_code/ImgProc/Smoothing/Smoothing.cpp gaussianblur
@end_toggle
This filter is provided by the @ref cv::medianBlur function:
@snippet cpp/tutorial_code/ImgProc/Smoothing.cpp medianblur
@add_toggle_java
@snippet samples/java/tutorial_code/ImgProc/Smoothing/Smoothing.java gaussianblur
@end_toggle
We use three arguments:
@add_toggle_python
@snippet samples/python/tutorial_code/imgProc/Smoothing/smoothing.py gaussianblur
@end_toggle
#### Median Filter:
-
This filter is provided by the
**medianBlur()**
function:
We use three arguments:
-
*src*
: Source image
-
*dst*
: Destination image, must be the same type as
*src*
-
*i*
: Size of the kernel (only one because we use a square window). Must be odd.
-#
**Bilateral Filter**
@add_toggle_cpp
@snippet cpp/tutorial_code/ImgProc/Smoothing/Smoothing.cpp medianblur
@end_toggle
Provided by OpenCV function @ref cv::bilateralFilter
@snippet cpp/tutorial_code/ImgProc/Smoothing.cpp bilateralfilter
@add_toggle_java
@snippet samples/java/tutorial_code/ImgProc/Smoothing/Smoothing.java medianblur
@end_toggle
We use 5 arguments:
@add_toggle_python
@snippet samples/python/tutorial_code/imgProc/Smoothing/smoothing.py medianblur
@end_toggle
#### Bilateral Filter
-
Provided by OpenCV function
**bilateralFilter()**
We use 5 arguments:
-
*src*
: Source image
-
*dst*
: Destination image
-
*d*
: The diameter of each pixel neighborhood.
-
\f
$
\s
igma_{Color}
\f
$: Standard deviation in the color space.
-
\f
$
\s
igma_{Space}
\f
$: Standard deviation in the coordinate space (in pixel terms)
@add_toggle_cpp
@snippet cpp/tutorial_code/ImgProc/Smoothing/Smoothing.cpp bilateralfilter
@end_toggle
@add_toggle_java
@snippet samples/java/tutorial_code/ImgProc/Smoothing/Smoothing.java bilateralfilter
@end_toggle
@add_toggle_python
@snippet samples/python/tutorial_code/imgProc/Smoothing/smoothing.py bilateralfilter
@end_toggle
Results
-------
-
The code opens an image (in this case
*lena.jpg*
) and display it under the effects of the 4
filters explained.
-
The code opens an image (in this case
[
lena.jpg
](
https://raw.githubusercontent.com/opencv/opencv/master/samples/data/lena.jpg
)
)
and display it under the effects of the 4
filters explained.
-
Here is a snapshot of the image smoothed using
*medianBlur*
:
![](images/Smoothing_Tutorial_Result_Median_Filter.jpg)
doc/tutorials/imgproc/table_of_content_imgproc.markdown
View file @
bc18fb48
...
...
@@ -5,6 +5,8 @@ In this section you will learn about the image processing (manipulation) functio
-
@subpage tutorial_gausian_median_blur_bilateral_filter
*Languages:* C++, Java, Python
*Compatibility:* \> OpenCV 2.0
*Author:* Ana Huamán
...
...
samples/cpp/tutorial_code/ImgProc/Smoothing.cpp
→
samples/cpp/tutorial_code/ImgProc/Smoothing
/Smoothing
.cpp
View file @
bc18fb48
...
...
@@ -4,6 +4,7 @@
* author OpenCV team
*/
#include <iostream>
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
...
...
@@ -27,61 +28,66 @@ int display_dst( int delay );
/**
* function main
*/
int
main
(
void
)
int
main
(
int
argc
,
char
**
argv
)
{
namedWindow
(
window_name
,
WINDOW_AUTOSIZE
);
namedWindow
(
window_name
,
WINDOW_AUTOSIZE
);
/// Load the source image
src
=
imread
(
"../data/lena.jpg"
,
IMREAD_COLOR
)
;
/// Load the source image
const
char
*
filename
=
argc
>=
2
?
argv
[
1
]
:
"../data/lena.jpg"
;
if
(
display_caption
(
"Original Image"
)
!=
0
)
{
return
0
;
}
src
=
imread
(
filename
,
IMREAD_COLOR
);
if
(
src
.
empty
()){
printf
(
" Error opening image
\n
"
);
printf
(
" Usage: ./Smoothing [image_name -- default ../data/lena.jpg]
\n
"
);
return
-
1
;
}
dst
=
src
.
clone
();
if
(
display_dst
(
DELAY_CAPTION
)
!=
0
)
{
return
0
;
}
if
(
display_caption
(
"Original Image"
)
!=
0
)
{
return
0
;
}
dst
=
src
.
clone
();
if
(
display_dst
(
DELAY_CAPTION
)
!=
0
)
{
return
0
;
}
/// Applying Homogeneous blur
if
(
display_caption
(
"Homogeneous Blur"
)
!=
0
)
{
return
0
;
}
//![blur]
for
(
int
i
=
1
;
i
<
MAX_KERNEL_LENGTH
;
i
=
i
+
2
)
{
blur
(
src
,
dst
,
Size
(
i
,
i
),
Point
(
-
1
,
-
1
)
);
/// Applying Homogeneous blur
if
(
display_caption
(
"Homogeneous Blur"
)
!=
0
)
{
return
0
;
}
//![blur]
for
(
int
i
=
1
;
i
<
MAX_KERNEL_LENGTH
;
i
=
i
+
2
)
{
blur
(
src
,
dst
,
Size
(
i
,
i
),
Point
(
-
1
,
-
1
)
);
if
(
display_dst
(
DELAY_BLUR
)
!=
0
)
{
return
0
;
}
}
//![blur]
//![blur]
/// Applying Gaussian blur
if
(
display_caption
(
"Gaussian Blur"
)
!=
0
)
{
return
0
;
}
/// Applying Gaussian blur
if
(
display_caption
(
"Gaussian Blur"
)
!=
0
)
{
return
0
;
}
//![gaussianblur]
for
(
int
i
=
1
;
i
<
MAX_KERNEL_LENGTH
;
i
=
i
+
2
)
{
GaussianBlur
(
src
,
dst
,
Size
(
i
,
i
),
0
,
0
);
//![gaussianblur]
for
(
int
i
=
1
;
i
<
MAX_KERNEL_LENGTH
;
i
=
i
+
2
)
{
GaussianBlur
(
src
,
dst
,
Size
(
i
,
i
),
0
,
0
);
if
(
display_dst
(
DELAY_BLUR
)
!=
0
)
{
return
0
;
}
}
//![gaussianblur]
//![gaussianblur]
/// Applying Median blur
if
(
display_caption
(
"Median Blur"
)
!=
0
)
{
return
0
;
}
/// Applying Median blur
if
(
display_caption
(
"Median Blur"
)
!=
0
)
{
return
0
;
}
//![medianblur]
for
(
int
i
=
1
;
i
<
MAX_KERNEL_LENGTH
;
i
=
i
+
2
)
{
medianBlur
(
src
,
dst
,
i
);
//![medianblur]
for
(
int
i
=
1
;
i
<
MAX_KERNEL_LENGTH
;
i
=
i
+
2
)
{
medianBlur
(
src
,
dst
,
i
);
if
(
display_dst
(
DELAY_BLUR
)
!=
0
)
{
return
0
;
}
}
//![medianblur]
//![medianblur]
/// Applying Bilateral Filter
if
(
display_caption
(
"Bilateral Blur"
)
!=
0
)
{
return
0
;
}
/// Applying Bilateral Filter
if
(
display_caption
(
"Bilateral Blur"
)
!=
0
)
{
return
0
;
}
//![bilateralfilter]
for
(
int
i
=
1
;
i
<
MAX_KERNEL_LENGTH
;
i
=
i
+
2
)
{
bilateralFilter
(
src
,
dst
,
i
,
i
*
2
,
i
/
2
);
//![bilateralfilter]
for
(
int
i
=
1
;
i
<
MAX_KERNEL_LENGTH
;
i
=
i
+
2
)
{
bilateralFilter
(
src
,
dst
,
i
,
i
*
2
,
i
/
2
);
if
(
display_dst
(
DELAY_BLUR
)
!=
0
)
{
return
0
;
}
}
//![bilateralfilter]
/// Wait until user press a key
display_caption
(
"End: Press a key!"
);
//![bilateralfilter]
waitKey
(
0
);
/// Done
display_caption
(
"Done!"
);
return
0
;
return
0
;
}
/**
...
...
@@ -89,15 +95,12 @@ int main( void )
*/
int
display_caption
(
const
char
*
caption
)
{
dst
=
Mat
::
zeros
(
src
.
size
(),
src
.
type
()
);
putText
(
dst
,
caption
,
Point
(
src
.
cols
/
4
,
src
.
rows
/
2
),
FONT_HERSHEY_COMPLEX
,
1
,
Scalar
(
255
,
255
,
255
)
);
imshow
(
window_name
,
dst
);
int
c
=
waitKey
(
DELAY_CAPTION
);
if
(
c
>=
0
)
{
return
-
1
;
}
return
0
;
dst
=
Mat
::
zeros
(
src
.
size
(),
src
.
type
()
);
putText
(
dst
,
caption
,
Point
(
src
.
cols
/
4
,
src
.
rows
/
2
),
FONT_HERSHEY_COMPLEX
,
1
,
Scalar
(
255
,
255
,
255
)
);
return
display_dst
(
DELAY_CAPTION
);
}
/**
...
...
@@ -105,8 +108,8 @@ int display_caption( const char* caption )
*/
int
display_dst
(
int
delay
)
{
imshow
(
window_name
,
dst
);
int
c
=
waitKey
(
delay
);
if
(
c
>=
0
)
{
return
-
1
;
}
return
0
;
imshow
(
window_name
,
dst
);
int
c
=
waitKey
(
delay
);
if
(
c
>=
0
)
{
return
-
1
;
}
return
0
;
}
samples/java/tutorial_code/ImgProc/Smoothing/Smoothing.java
0 → 100644
View file @
bc18fb48
import
org.opencv.core.*
;
import
org.opencv.highgui.HighGui
;
import
org.opencv.imgcodecs.Imgcodecs
;
import
org.opencv.imgproc.Imgproc
;
class
SmoothingRun
{
/// Global Variables
int
DELAY_CAPTION
=
1500
;
int
DELAY_BLUR
=
100
;
int
MAX_KERNEL_LENGTH
=
31
;
Mat
src
=
new
Mat
(),
dst
=
new
Mat
();
String
windowName
=
"Filter Demo 1"
;
public
void
run
(
String
[]
args
)
{
String
filename
=
((
args
.
length
>
0
)
?
args
[
0
]
:
"../data/lena.jpg"
);
src
=
Imgcodecs
.
imread
(
filename
,
Imgcodecs
.
IMREAD_COLOR
);
if
(
src
.
empty
()
)
{
System
.
out
.
println
(
"Error opening image"
);
System
.
out
.
println
(
"Usage: ./Smoothing [image_name -- default ../data/lena.jpg] \n"
);
System
.
exit
(-
1
);
}
if
(
displayCaption
(
"Original Image"
)
!=
0
)
{
System
.
exit
(
0
);
}
dst
=
src
.
clone
();
if
(
displayDst
(
DELAY_CAPTION
)
!=
0
)
{
System
.
exit
(
0
);
}
/// Applying Homogeneous blur
if
(
displayCaption
(
"Homogeneous Blur"
)
!=
0
)
{
System
.
exit
(
0
);
}
//! [blur]
for
(
int
i
=
1
;
i
<
MAX_KERNEL_LENGTH
;
i
=
i
+
2
)
{
Imgproc
.
blur
(
src
,
dst
,
new
Size
(
i
,
i
),
new
Point
(-
1
,
-
1
));
displayDst
(
DELAY_BLUR
);
}
//! [blur]
/// Applying Gaussian blur
if
(
displayCaption
(
"Gaussian Blur"
)
!=
0
)
{
System
.
exit
(
0
);
}
//! [gaussianblur]
for
(
int
i
=
1
;
i
<
MAX_KERNEL_LENGTH
;
i
=
i
+
2
)
{
Imgproc
.
GaussianBlur
(
src
,
dst
,
new
Size
(
i
,
i
),
0
,
0
);
displayDst
(
DELAY_BLUR
);
}
//! [gaussianblur]
/// Applying Median blur
if
(
displayCaption
(
"Median Blur"
)
!=
0
)
{
System
.
exit
(
0
);
}
//! [medianblur]
for
(
int
i
=
1
;
i
<
MAX_KERNEL_LENGTH
;
i
=
i
+
2
)
{
Imgproc
.
medianBlur
(
src
,
dst
,
i
);
displayDst
(
DELAY_BLUR
);
}
//! [medianblur]
/// Applying Bilateral Filter
if
(
displayCaption
(
"Bilateral Blur"
)
!=
0
)
{
System
.
exit
(
0
);
}
//![bilateralfilter]
for
(
int
i
=
1
;
i
<
MAX_KERNEL_LENGTH
;
i
=
i
+
2
)
{
Imgproc
.
bilateralFilter
(
src
,
dst
,
i
,
i
*
2
,
i
/
2
);
displayDst
(
DELAY_BLUR
);
}
//![bilateralfilter]
/// Done
displayCaption
(
"Done!"
);
System
.
exit
(
0
);
}
int
displayCaption
(
String
caption
)
{
dst
=
Mat
.
zeros
(
src
.
size
(),
src
.
type
());
Imgproc
.
putText
(
dst
,
caption
,
new
Point
(
src
.
cols
()
/
4
,
src
.
rows
()
/
2
),
Core
.
FONT_HERSHEY_COMPLEX
,
1
,
new
Scalar
(
255
,
255
,
255
));
return
displayDst
(
DELAY_CAPTION
);
}
int
displayDst
(
int
delay
)
{
HighGui
.
imshow
(
windowName
,
dst
);
int
c
=
HighGui
.
waitKey
(
delay
);
if
(
c
>=
0
)
{
return
-
1
;
}
return
0
;
}
}
public
class
Smoothing
{
public
static
void
main
(
String
[]
args
)
{
// Load the native library.
System
.
loadLibrary
(
Core
.
NATIVE_LIBRARY_NAME
);
new
SmoothingRun
().
run
(
args
);
}
}
samples/python/tutorial_code/imgProc/Smoothing/smoothing.py
0 → 100644
View file @
bc18fb48
import
sys
import
cv2
import
numpy
as
np
# Global Variables
DELAY_CAPTION
=
1500
DELAY_BLUR
=
100
MAX_KERNEL_LENGTH
=
31
src
=
None
dst
=
None
window_name
=
'Smoothing Demo'
def
main
(
argv
):
cv2
.
namedWindow
(
window_name
,
cv2
.
WINDOW_AUTOSIZE
)
# Load the source image
imageName
=
argv
[
0
]
if
len
(
argv
)
>
0
else
"../data/lena.jpg"
global
src
src
=
cv2
.
imread
(
imageName
,
1
)
if
src
is
None
:
print
(
'Error opening image'
)
print
(
'Usage: smoothing.py [image_name -- default ../data/lena.jpg]
\n
'
)
return
-
1
if
display_caption
(
'Original Image'
)
!=
0
:
return
0
global
dst
dst
=
np
.
copy
(
src
)
if
display_dst
(
DELAY_CAPTION
)
!=
0
:
return
0
# Applying Homogeneous blur
if
display_caption
(
'Homogeneous Blur'
)
!=
0
:
return
0
## [blur]
for
i
in
range
(
1
,
MAX_KERNEL_LENGTH
,
2
):
dst
=
cv2
.
blur
(
src
,
(
i
,
i
))
if
display_dst
(
DELAY_BLUR
)
!=
0
:
return
0
## [blur]
# Applying Gaussian blur
if
display_caption
(
'Gaussian Blur'
)
!=
0
:
return
0
## [gaussianblur]
for
i
in
range
(
1
,
MAX_KERNEL_LENGTH
,
2
):
dst
=
cv2
.
GaussianBlur
(
src
,
(
i
,
i
),
0
)
if
display_dst
(
DELAY_BLUR
)
!=
0
:
return
0
## [gaussianblur]
# Applying Median blur
if
display_caption
(
'Median Blur'
)
!=
0
:
return
0
## [medianblur]
for
i
in
range
(
1
,
MAX_KERNEL_LENGTH
,
2
):
dst
=
cv2
.
medianBlur
(
src
,
i
)
if
display_dst
(
DELAY_BLUR
)
!=
0
:
return
0
## [medianblur]
# Applying Bilateral Filter
if
display_caption
(
'Bilateral Blur'
)
!=
0
:
return
0
## [bilateralfilter]
# Remember, bilateral is a bit slow, so as value go higher, it takes long time
for
i
in
range
(
1
,
MAX_KERNEL_LENGTH
,
2
):
dst
=
cv2
.
bilateralFilter
(
src
,
i
,
i
*
2
,
i
/
2
)
if
display_dst
(
DELAY_BLUR
)
!=
0
:
return
0
## [bilateralfilter]
# Done
display_caption
(
'Done!'
)
return
0
def
display_caption
(
caption
):
global
dst
dst
=
np
.
zeros
(
src
.
shape
,
src
.
dtype
)
rows
,
cols
,
ch
=
src
.
shape
cv2
.
putText
(
dst
,
caption
,
(
int
(
cols
/
4
),
int
(
rows
/
2
)),
cv2
.
FONT_HERSHEY_COMPLEX
,
1
,
(
255
,
255
,
255
))
return
display_dst
(
DELAY_CAPTION
)
def
display_dst
(
delay
):
cv2
.
imshow
(
window_name
,
dst
)
c
=
cv2
.
waitKey
(
delay
)
if
c
>=
0
:
return
-
1
return
0
if
__name__
==
"__main__"
:
main
(
sys
.
argv
[
1
:])
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment